diff --git a/CHANGELOG.md b/CHANGELOG.md
new file mode 100644
--- /dev/null
+++ b/CHANGELOG.md
@@ -0,0 +1,14 @@
+# Changelog
+All notable changes to this project will be documented in this file.
+
+The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/)
+
+## [Unreleased]
+
+## [0.1.1.0] - 2020-02-29
+### Added
+- bindings to generichash (Blake2), thanks [@donatello](https://github.com/donatello)
+
+### Changed
+- Don't use `fail` in tests to fix compilation with GHC 8.8
+- Windows install instructions added, thanks [@tmcl](https://github.com/tmcl)
diff --git a/README.md b/README.md
new file mode 100644
--- /dev/null
+++ b/README.md
@@ -0,0 +1,69 @@
+# Saltine 0.1.1.0 [![Build Status](https://travis-ci.org/tel/saltine.png?branch=master)](https://travis-ci.org/tel/saltine)[![Hackage version](https://img.shields.io/hackage/v/saltine.svg?colorB=4FB900)](https://hackage.haskell.org/package/saltine)
+
+A Haskell binding for @jedisct1's portable binding for djb's
+NaCl. **This is an early release.** Please try it out, but don't just
+yet stake your life or job on it.
+
+It is imperative you call `sodiumInit` before using any other function.
+
+``` haskell
+import           Crypto.Saltine
+import           Crypto.Saltine.Core.SecretBox
+import qualified Data.ByteString.Char8 as BSC8
+
+main = do
+  sodiumInit
+  k <- newKey
+  n <- newNonce
+  let ciphertext = secretbox k n (BSC8.pack "foobar")
+  print $ secretboxOpen k n ciphertext
+
+-- Just "foobar"
+```
+
+In
+[*The Security Impact of a New Cryptographic Library*](http://cryptojedi.org/papers/coolnacl-20111201.pdf)
+Bernstein, Lange, and Schwabe argue that high-level cryptographic
+libraries eliminate whole spaces of cryptographic disasters which are
+nigh inevitable whenever programmers use low-level crypto primitives.
+
+* [Security Stack Exchange: Why Shouldn't We Roll Our Own?](http://security.stackexchange.com/questions/18197/why-shouldnt-we-roll-our-own)
+* [Hacker News on "All the Crypto Code You've Ever Written is Probably Broken"](https://news.ycombinator.com/item?id=4779015)
+* [Stack Overflow: When can you trust yourself to implement cryptography based solutions?](http://stackoverflow.com/questions/1914257/when-can-you-trust-yourself-to-implement-cryptography-based-solutions)
+* [Coding Horror: Why isn't my encryption... encrypting?](http://www.codinghorror.com/blog/2009/05/why-isnt-my-encryption-encrypting.html)
+
+Crypto is complicated, so pre-rolled solutions are important
+prevention mechanisms.
+
+[NaCl](http://nacl.cr.yp.to/) is Bernstein, Lange, and Schwabe's
+solution: a high-level, performant cryptography library with a no-fuss
+interface. [Saltine](http://github.com/tel/saltine) is a Haskell
+binding to NaCl (via
+[`libsodium`](https://github.com/jedisct1/libsodium)) which hopes to
+provide even more simplicity and safety to the usage of cryptography.
+
+Note that it's still possible to shoot yourself in the foot pretty
+easily using Saltine. Nonces must always be unique which must be managed 
+by the library user.
+[`Crypto.Saltine.Core.Stream`](https://github.com/tel/saltine/blob/master/src/Crypto/Saltine/Core/Stream.hs)
+produces messages which can beundetectably tampered with in-flight. 
+Keys are insecurely read from disk—they may be copied and then paged 
+back to disk.
+
+When uncertain, use [`Crypto.Saltine.Core.SecretBox`](https://github.com/tel/saltine/blob/master/src/Crypto/Saltine/Core/SecretBox.hs) 
+and [`Crypto.Saltine.Core.Box`](https://github.com/tel/saltine/blob/master/src/Crypto/Saltine/Core/Box.hs).
+If you can think of ways to use Haskell's type system to enforce 
+security invariants, please suggest them.
+
+To use it on Windows systems, download 
+[a prebuild libsodium-\*-stable-mingw.tar.gz file](https://download.libsodium.org/libsodium/releases/) 
+and copy the files in `libsodium-win64`  into the equivalent places 
+in `C:\Program Files\Haskell Platform\*\mingw`. Then just add saltine 
+to your cabal file and watch it go.
+
+Tested with [`libsodium-1.0.13`](https://download.libsodium.org/libsodium/releases/).
+
+Inspired by @thoughtpolice's
+[`salt`](http://github.com/thoughtpolice/salt) library. `salt` also
+binds to NaCl, but uses a Haskell managed version of djb's code
+instead of `libsodium`.
diff --git a/saltine.cabal b/saltine.cabal
--- a/saltine.cabal
+++ b/saltine.cabal
@@ -1,5 +1,5 @@
 name:                saltine
-version:             0.1.0.2
+version:             0.1.1.0
 synopsis:            Cryptography that's easy to digest (NaCl/libsodium bindings).
 description:
 
@@ -18,6 +18,10 @@
   /Saltine/ is a Haskell binding to the NaCl primitives going through
   Sodium for build convenience and, eventually, portability.
 
+extra-source-files:
+                     README.md
+                     CHANGELOG.md
+
 license:             MIT
 license-file:        LICENSE
 author:              Joseph Abrahamson
@@ -27,7 +31,7 @@
 category:            Cryptography
 build-type:          Simple
 cabal-version:       >=1.10
-tested-with:         GHC==7.8.4, GHC==7.10.3, GHC==8.0.2, GHC==8.2.1
+tested-with:         GHC==7.8.4, GHC==7.10.3, GHC==8.0.2, GHC==8.2.2, GHC==8.4.3, GHC==8.6.5, GHC==8.8.3
 
 source-repository head
   type: git
@@ -62,8 +66,9 @@
   default-language:   Haskell2010
   build-depends:
                 base >= 4.5 && < 5
-              , bytestring
-              , profunctors
+              , bytestring >= 0.10.8 && < 0.11
+              , profunctors >= 5.3 && < 5.6
+              , hashable
 
 test-suite tests
   type:    exitcode-stdio-1.0
@@ -83,7 +88,7 @@
   hs-source-dirs: tests
   default-language: Haskell2010
   build-depends:
-                base >= 4.5 && < 5
+                base >= 4.7 && < 5
               , saltine
               , bytestring
               , QuickCheck
diff --git a/src/Crypto/Saltine/Core/AEAD.hs b/src/Crypto/Saltine/Core/AEAD.hs
--- a/src/Crypto/Saltine/Core/AEAD.hs
+++ b/src/Crypto/Saltine/Core/AEAD.hs
@@ -1,3 +1,5 @@
+{-# LANGUAGE DeriveDataTypeable, GeneralizedNewtypeDeriving, DeriveGeneric #-}
+
 -- |
 -- Module      : Crypto.Saltine.Core.AEAD
 -- Copyright   : (c) Thomas DuBuisson 2017
@@ -47,11 +49,14 @@
 import           Foreign.Ptr
 import qualified Data.ByteString                   as S
 import           Data.ByteString                     (ByteString)
+import           Data.Hashable (Hashable)
+import           Data.Data (Data, Typeable)
+import           GHC.Generics (Generic)
 
 -- $types
 
 -- | An opaque 'secretbox' cryptographic key.
-newtype Key = Key ByteString deriving (Eq, Ord)
+newtype Key = Key ByteString deriving (Eq, Ord, Hashable, Data, Typeable, Generic)
 
 instance IsEncoding Key where
   decode v = if S.length v == Bytes.secretBoxKey
@@ -62,7 +67,7 @@
   {-# INLINE encode #-}
 
 -- | An opaque 'secretbox' nonce.
-newtype Nonce = Nonce ByteString deriving (Eq, Ord)
+newtype Nonce = Nonce ByteString deriving (Eq, Ord, Hashable, Data, Typeable, Generic)
 
 instance IsEncoding Nonce where
   decode v = if S.length v == Bytes.secretBoxNonce
diff --git a/src/Crypto/Saltine/Core/Auth.hs b/src/Crypto/Saltine/Core/Auth.hs
--- a/src/Crypto/Saltine/Core/Auth.hs
+++ b/src/Crypto/Saltine/Core/Auth.hs
@@ -1,3 +1,5 @@
+{-# LANGUAGE DeriveDataTypeable, GeneralizedNewtypeDeriving, DeriveGeneric #-}
+
 -- |
 -- Module      : Crypto.Saltine.Core.Auth
 -- Copyright   : (c) Joseph Abrahamson 2013
@@ -52,14 +54,17 @@
 import           Foreign.Ptr
 import qualified Data.ByteString                   as S
 import           Data.ByteString                     (ByteString)
+import           Data.Hashable (Hashable)
+import           Data.Data (Data, Typeable)
+import           GHC.Generics (Generic)
 
 -- $types
 
 -- | An opaque 'auth' cryptographic key.
-newtype Key           = Key ByteString deriving (Eq, Ord)
+newtype Key           = Key ByteString deriving (Eq, Ord, Hashable, Data, Typeable, Generic)
 
 -- | An opaque 'auth' authenticator.
-newtype Authenticator = Au ByteString  deriving (Eq, Ord)
+newtype Authenticator = Au ByteString  deriving (Eq, Ord, Hashable, Data, Typeable, Generic)
 
 instance IsEncoding Key where
   decode v = if S.length v == Bytes.authKey
diff --git a/src/Crypto/Saltine/Core/Box.hs b/src/Crypto/Saltine/Core/Box.hs
--- a/src/Crypto/Saltine/Core/Box.hs
+++ b/src/Crypto/Saltine/Core/Box.hs
@@ -1,3 +1,5 @@
+{-# LANGUAGE DeriveDataTypeable, GeneralizedNewtypeDeriving, DeriveGeneric #-}
+
 -- |
 -- Module      : Crypto.Saltine.Core.Box
 -- Copyright   : (c) Joseph Abrahamson 2013
@@ -94,12 +96,15 @@
 import           Foreign.Ptr
 import qualified Data.ByteString                   as S
 import           Data.ByteString (ByteString)
+import           Data.Hashable (Hashable)
+import           Data.Data (Data, Typeable)
+import           GHC.Generics (Generic)
 
 
 -- $types
 
 -- | An opaque 'box' cryptographic secret key.
-newtype SecretKey = SK ByteString deriving (Eq, Ord)
+newtype SecretKey = SK ByteString deriving (Eq, Ord, Hashable, Data, Typeable, Generic)
 
 instance IsEncoding SecretKey where
   decode v = if S.length v == Bytes.boxSK
@@ -110,7 +115,7 @@
   {-# INLINE encode #-}
 
 -- | An opaque 'box' cryptographic public key.
-newtype PublicKey = PK ByteString deriving (Eq, Ord)
+newtype PublicKey = PK ByteString deriving (Eq, Ord, Hashable, Data, Typeable, Generic)
 
 instance IsEncoding PublicKey where
   decode v = if S.length v == Bytes.boxPK
@@ -124,7 +129,7 @@
 type Keypair = (SecretKey, PublicKey)
 
 -- | An opaque 'boxAfterNM' cryptographic combined key.
-newtype CombinedKey = CK ByteString deriving (Eq, Ord)
+newtype CombinedKey = CK ByteString deriving (Eq, Ord, Hashable, Data, Typeable, Generic)
 
 instance IsEncoding CombinedKey where
   decode v = if S.length v == Bytes.boxBeforeNM
@@ -135,7 +140,7 @@
   {-# INLINE encode #-}
 
 -- | An opaque 'box' nonce.
-newtype Nonce = Nonce ByteString deriving (Eq, Ord)
+newtype Nonce = Nonce ByteString deriving (Eq, Ord, Hashable, Data, Typeable, Generic)
 
 instance IsEncoding Nonce where
   decode v = if S.length v == Bytes.boxNonce
diff --git a/src/Crypto/Saltine/Core/Hash.hs b/src/Crypto/Saltine/Core/Hash.hs
--- a/src/Crypto/Saltine/Core/Hash.hs
+++ b/src/Crypto/Saltine/Core/Hash.hs
@@ -1,4 +1,6 @@
--- |
+{-# LANGUAGE DeriveDataTypeable, GeneralizedNewtypeDeriving, DeriveGeneric #-}
+
+ -- |
 -- Module      : Crypto.Saltine.Core.Hash
 -- Copyright   : (c) Joseph Abrahamson 2013
 -- License     : MIT
@@ -34,16 +36,20 @@
 -- alternatives that inspire satisfactory levels of confidence. One
 -- can hope that NIST's SHA-3 competition will improve the situation.
 --
--- Sodium includes an implementation of the Blake2 hash
--- (<https://blake2.net/>) but since this is not standard NaCl nor was
--- Blake2 selected to be SHA-3 the library doesn't bind it.
+-- Sodium includes an implementation of the Blake2b hash function
+-- (<https://blake2.net/>) and is bound here as the 'generichash'
+-- function.
 --
 -- This is version 2010.08.30 of the hash.html web page. Information
 -- about SipHash has been added.
 module Crypto.Saltine.Core.Hash (
   ShorthashKey,
   hash,
-  shorthash, newShorthashKey
+  shorthash, newShorthashKey,
+  GenerichashKey,
+  newGenerichashKey,
+  GenerichashOutLen,
+  generichashOutLen, generichash
   ) where
 
 import           Crypto.Saltine.Class
@@ -55,6 +61,9 @@
 import           Foreign.Ptr
 import qualified Data.ByteString as S
 import           Data.ByteString (ByteString)
+import           Data.Hashable (Hashable)
+import           Data.Data (Data, Typeable)
+import           GHC.Generics (Generic)
 
 -- | Computes a cryptographically collision-resistant hash making
 -- @hash m == hash m' ==> m == m'@ highly likely even when under
@@ -67,7 +76,7 @@
   constByteStrings [m] $ \[(pm, _)] -> c_hash ph pm (fromIntegral $ S.length m)
 
 -- | An opaque 'shorthash' cryptographic secret key.
-newtype ShorthashKey = ShK ByteString deriving (Eq, Ord)
+newtype ShorthashKey = ShK ByteString deriving (Eq, Ord, Hashable, Data, Typeable, Generic)
 
 instance IsEncoding ShorthashKey where
   decode v = if S.length v == Bytes.shorthashKey
@@ -91,6 +100,43 @@
   constByteStrings [k, m] $ \[(pk, _), (pm, _)] ->
     c_shorthash ph pm (fromIntegral $ S.length m) pk
 
+-- | An opaque 'generichash' cryptographic secret key.
+newtype GenerichashKey = GhK ByteString deriving (Eq, Ord, Hashable, Data, Typeable, Generic)
+
+instance IsEncoding GenerichashKey where
+  decode v = if S.length v <= Bytes.generichashKeyLenMax
+             then Just (GhK v)
+             else Nothing
+  {-# INLINE decode #-}
+  encode (GhK v) = v
+  {-# INLINE encode #-}
+
+-- | Randomly generates a new key for 'generichash' of the given length.
+newGenerichashKey :: Int -> IO (Maybe GenerichashKey)
+newGenerichashKey n = if n >= 0 && n <= Bytes.generichashKeyLenMax
+                      then Just . GhK <$> randomByteString n
+                      else return Nothing
+
+newtype GenerichashOutLen = GhOL Int deriving (Eq, Ord, Hashable, Data, Typeable, Generic)
+
+-- | Create a validated Generichash output length
+generichashOutLen :: Int -> Maybe GenerichashOutLen
+generichashOutLen n = if n > 0 && n <= Bytes.generichashOutLenMax
+                      then Just $ GhOL $ fromIntegral n
+                      else Nothing
+
+-- | Computes a generic, keyed hash.
+generichash :: GenerichashKey
+            -> ByteString
+            -- ^ Message
+            -> GenerichashOutLen
+            -- ^ Desired output hash length
+            -> ByteString
+            -- ^ Hash
+generichash (GhK k) m (GhOL outLen) = snd . buildUnsafeByteString outLen $ \ph ->
+  constByteStrings [k, m] $ \[(pk, _), (pm, _)] ->
+    c_generichash ph (fromIntegral outLen) pm (fromIntegral $ S.length m) pk (fromIntegral $ S.length k)
+
 foreign import ccall "crypto_hash"
   c_hash :: Ptr CChar
          -- ^ Output hash buffer
@@ -112,3 +158,19 @@
               -- ^ Constant Key buffer
               -> IO CInt
               -- ^ Always 0
+
+foreign import ccall "crypto_generichash"
+  c_generichash :: Ptr CChar
+                -- ^ Output hash buffer
+                -> CULLong
+                -- ^ Output hash length
+                -> Ptr CChar
+                -- ^ Constant message buffer
+                -> CULLong
+                -- ^ Message buffer length
+                -> Ptr CChar
+                -- ^ Constant Key buffer
+                -> CULLong
+                -- ^ Key buffer length
+                -> IO CInt
+                -- ^ Always 0
diff --git a/src/Crypto/Saltine/Core/OneTimeAuth.hs b/src/Crypto/Saltine/Core/OneTimeAuth.hs
--- a/src/Crypto/Saltine/Core/OneTimeAuth.hs
+++ b/src/Crypto/Saltine/Core/OneTimeAuth.hs
@@ -1,3 +1,5 @@
+{-# LANGUAGE DeriveDataTypeable, GeneralizedNewtypeDeriving, DeriveGeneric #-}
+
 -- |
 -- Module      : Crypto.Saltine.Core.OneTimeAuth
 -- Copyright   : (c) Joseph Abrahamson 2013
@@ -48,14 +50,17 @@
 import           Foreign.Ptr
 import qualified Data.ByteString                   as S
 import           Data.ByteString                     (ByteString)
+import           Data.Hashable (Hashable)
+import           Data.Data (Data, Typeable)
+import           GHC.Generics (Generic)
 
 -- $types
 
 -- | An opaque 'auth' cryptographic key.
-newtype Key           = Key ByteString deriving (Eq, Ord)
+newtype Key           = Key ByteString deriving (Eq, Ord, Hashable, Data, Typeable, Generic)
 
 -- | An opaque 'auth' authenticator.
-newtype Authenticator = Au ByteString  deriving (Eq, Ord)
+newtype Authenticator = Au ByteString  deriving (Eq, Ord, Hashable, Data, Typeable, Generic)
 
 instance IsEncoding Key where
   decode v = if S.length v == Bytes.onetimeKey
diff --git a/src/Crypto/Saltine/Core/ScalarMult.hs b/src/Crypto/Saltine/Core/ScalarMult.hs
--- a/src/Crypto/Saltine/Core/ScalarMult.hs
+++ b/src/Crypto/Saltine/Core/ScalarMult.hs
@@ -1,3 +1,5 @@
+{-# LANGUAGE DeriveDataTypeable, GeneralizedNewtypeDeriving, DeriveGeneric #-}
+
 -- |
 -- Module      : Crypto.Saltine.Core.ScalarMult
 -- Copyright   : (c) Joseph Abrahamson 2013
@@ -63,14 +65,17 @@
 import           Foreign.Ptr
 import qualified Data.ByteString                   as S
 import           Data.ByteString                     (ByteString)
+import           Data.Hashable (Hashable)
+import           Data.Data (Data, Typeable)
+import           GHC.Generics (Generic)
 
 -- $types
 
 -- | A group element.
-newtype GroupElement = GE ByteString deriving (Eq)
+newtype GroupElement = GE ByteString deriving (Eq, Ord, Hashable, Data, Typeable, Generic)
 
 -- | A scalar integer.
-newtype Scalar       = Sc ByteString deriving (Eq)
+newtype Scalar       = Sc ByteString deriving (Eq, Ord, Hashable, Data, Typeable, Generic)
 
 instance IsEncoding GroupElement where
   decode v = if S.length v == Bytes.mult
diff --git a/src/Crypto/Saltine/Core/SecretBox.hs b/src/Crypto/Saltine/Core/SecretBox.hs
--- a/src/Crypto/Saltine/Core/SecretBox.hs
+++ b/src/Crypto/Saltine/Core/SecretBox.hs
@@ -1,3 +1,5 @@
+{-# LANGUAGE DeriveDataTypeable, GeneralizedNewtypeDeriving, DeriveGeneric #-}
+
 -- |
 -- Module      : Crypto.Saltine.Core.SecretBox
 -- Copyright   : (c) Joseph Abrahamson 2013
@@ -53,11 +55,14 @@
 import           Foreign.Ptr
 import qualified Data.ByteString                   as S
 import           Data.ByteString                     (ByteString)
+import           Data.Hashable (Hashable)
+import           Data.Data (Data, Typeable)
+import           GHC.Generics (Generic)
 
 -- $types
 
 -- | An opaque 'secretbox' cryptographic key.
-newtype Key = Key ByteString deriving (Eq, Ord)
+newtype Key = Key ByteString deriving (Eq, Ord, Hashable, Data, Typeable, Generic)
 
 instance IsEncoding Key where
   decode v = if S.length v == Bytes.secretBoxKey
@@ -68,7 +73,7 @@
   {-# INLINE encode #-}
 
 -- | An opaque 'secretbox' nonce.
-newtype Nonce = Nonce ByteString deriving (Eq, Ord)
+newtype Nonce = Nonce ByteString deriving (Eq, Ord, Hashable, Data, Typeable, Generic)
 
 instance IsEncoding Nonce where
   decode v = if S.length v == Bytes.secretBoxNonce
diff --git a/src/Crypto/Saltine/Core/Sign.hs b/src/Crypto/Saltine/Core/Sign.hs
--- a/src/Crypto/Saltine/Core/Sign.hs
+++ b/src/Crypto/Saltine/Core/Sign.hs
@@ -1,3 +1,5 @@
+{-# LANGUAGE DeriveDataTypeable, GeneralizedNewtypeDeriving, DeriveGeneric #-}
+
 -- |
 -- Module      : Crypto.Saltine.Core.Sign
 -- Copyright   : (c) Joseph Abrahamson 2013
@@ -43,11 +45,15 @@
 import           System.IO.Unsafe
 import qualified Data.ByteString                   as S
 import           Data.ByteString                     (ByteString)
+import           Data.Data (Data, Typeable)
+import           Data.Hashable (Hashable)
+import           GHC.Generics (Generic)
 
+
 -- $types
 
 -- | An opaque 'box' cryptographic secret key.
-newtype SecretKey = SK ByteString deriving (Eq, Ord)
+newtype SecretKey = SK ByteString deriving (Eq, Ord, Hashable, Data, Typeable, Generic)
 
 instance IsEncoding SecretKey where
   decode v = if S.length v == Bytes.signSK
@@ -58,7 +64,7 @@
   {-# INLINE encode #-}
 
 -- | An opaque 'box' cryptographic public key.
-newtype PublicKey = PK ByteString deriving (Eq, Ord)
+newtype PublicKey = PK ByteString deriving (Eq, Ord, Data, Typeable, Hashable, Generic)
 
 instance IsEncoding PublicKey where
   decode v = if S.length v == Bytes.signPK
diff --git a/src/Crypto/Saltine/Core/Stream.hs b/src/Crypto/Saltine/Core/Stream.hs
--- a/src/Crypto/Saltine/Core/Stream.hs
+++ b/src/Crypto/Saltine/Core/Stream.hs
@@ -1,3 +1,5 @@
+{-# LANGUAGE DeriveDataTypeable, GeneralizedNewtypeDeriving, DeriveGeneric #-}
+
 -- |
 -- Module      : Crypto.Saltine.Core.Stream
 -- Copyright   : (c) Joseph Abrahamson 2013
@@ -62,11 +64,14 @@
 import           Foreign.Ptr
 import qualified Data.ByteString as S
 import           Data.ByteString (ByteString)
+import           Data.Hashable (Hashable)
+import           Data.Data (Data, Typeable)
+import           GHC.Generics (Generic)
 
 -- $types
 
 -- | An opaque 'stream' cryptographic key.
-newtype Key = Key ByteString deriving (Eq, Ord)
+newtype Key = Key ByteString deriving (Eq, Ord, Hashable, Data, Typeable, Generic)
 
 instance IsEncoding Key where
   decode v = if S.length v == Bytes.streamKey
@@ -77,7 +82,7 @@
   {-# INLINE encode #-}
 
 -- | An opaque 'stream' nonce.
-newtype Nonce = Nonce ByteString deriving (Eq, Ord)
+newtype Nonce = Nonce ByteString deriving (Eq, Ord, Hashable, Data, Typeable, Generic)
 
 instance IsNonce Nonce where
   zero = Nonce (S.replicate Bytes.streamNonce 0)
diff --git a/src/Crypto/Saltine/Internal/ByteSizes.hs b/src/Crypto/Saltine/Internal/ByteSizes.hs
--- a/src/Crypto/Saltine/Internal/ByteSizes.hs
+++ b/src/Crypto/Saltine/Internal/ByteSizes.hs
@@ -46,7 +46,9 @@
   streamNonce,
   hash,
   shorthash,
-  shorthashKey
+  shorthashKey,
+  generichashOutLenMax,
+  generichashKeyLenMax
   ) where
 
 import Foreign.C
@@ -62,7 +64,7 @@
 sign, signPK, signSK :: Int
 streamKey, streamNonce :: Int
 hash, shorthash, shorthashKey :: Int
-
+generichashOutLenMax, generichashKeyLenMax :: Int
 
 -- Authentication
 -- | Size of a @crypto_auth@ authenticator.
@@ -148,6 +150,12 @@
 -- | The size of a hashing key for the keyed hash function
 -- 'Crypto.Saltine.Internal.Hash.shorthash'.
 shorthashKey = fromIntegral c_crypto_shorthash_keybytes
+-- | The maximum output size of the generic hash function
+-- 'Crypto.Saltine.Core.Hash.generichash'
+generichashOutLenMax = fromIntegral c_crypto_generichash_bytes_max
+-- | The maximum key size of the generic hash function
+-- 'Crypto.Saltine.Core.Hash.generichash'
+generichashKeyLenMax = fromIntegral c_crypto_generichash_keybytes_max
 
 -- src/libsodium/crypto_auth/crypto_auth.c
 foreign import ccall "crypto_auth_bytes"
@@ -206,6 +214,12 @@
   c_crypto_sign_publickeybytes :: CSize
 foreign import ccall "crypto_sign_secretkeybytes"
   c_crypto_sign_secretkeybytes :: CSize
+
+-- src/libsodium/crypto_generichash/crypto_generichash.c
+foreign import ccall "crypto_generichash_bytes_max"
+  c_crypto_generichash_bytes_max :: CSize
+foreign import ccall "crypto_generichash_keybytes_max"
+  c_crypto_generichash_keybytes_max :: CSize
 
 -- HARDCODED
 -- ---------
diff --git a/tests/AEADProperties.hs b/tests/AEADProperties.hs
--- a/tests/AEADProperties.hs
+++ b/tests/AEADProperties.hs
@@ -12,6 +12,7 @@
 
 import           Control.Applicative
 import qualified Data.ByteString                      as S
+import           Data.Maybe (fromJust)
 import           Test.Framework.Providers.QuickCheck2
 import           Test.Framework
 import           Test.QuickCheck (Property, (==>))
@@ -20,12 +21,12 @@
 instance Arbitrary Nonce where
     arbitrary =
         do bs <- S.pack <$> vector Bytes.secretBoxNonce
-           maybe (fail "impossible arbitrary failure.") pure (decode bs)
+           pure $ fromJust (decode bs)
 
 instance Arbitrary Key where
     arbitrary =
         do bs <- S.pack <$> vector Bytes.secretBoxKey
-           maybe (fail "impossible arbitrary failure.") pure (decode bs)
+           pure $ fromJust (decode bs)
 
 instance Show Key where
     show = show . encode
diff --git a/tests/Main.hs b/tests/Main.hs
--- a/tests/Main.hs
+++ b/tests/Main.hs
@@ -10,6 +10,7 @@
 import AuthProperties        (testAuth)
 import OneTimeAuthProperties (testOneTimeAuth)
 import SignProperties        (testSign)
+import HashProperties        (testHash)
 import ScalarMultProperties  (testScalarMult)
 import Crypto.Saltine
 
@@ -36,5 +37,6 @@
         testAuth,
         testOneTimeAuth,
         testSign,
+        testHash,
         testScalarMult
         ]
diff --git a/tests/SecretBoxProperties.hs b/tests/SecretBoxProperties.hs
--- a/tests/SecretBoxProperties.hs
+++ b/tests/SecretBoxProperties.hs
@@ -12,6 +12,7 @@
 
 import           Control.Applicative
 import qualified Data.ByteString                      as S
+import           Data.Maybe (fromJust)
 import           Test.Framework.Providers.QuickCheck2
 import           Test.Framework
 import           Test.QuickCheck (Property, (==>))
@@ -20,12 +21,12 @@
 instance Arbitrary Nonce where
     arbitrary =
         do bs <- S.pack <$> vector Bytes.secretBoxNonce
-           maybe (fail "impossible arbitrary failure.") pure (decode bs)
+           pure $ fromJust  (decode bs)
 
 instance Arbitrary Key where
     arbitrary =
         do bs <- S.pack <$> vector Bytes.secretBoxKey
-           maybe (fail "impossible arbitrary failure.") pure (decode bs)
+           pure $ fromJust (decode bs)
 instance Show Key where
     show = show . encode
 instance Show Nonce where
