I am trying to use the Crypto.Hash module (cryptonite package) and produce "hash of hash" results.
The issue is that the signature of the module's hash function is hashlazy :: HashAlgorithm a => ByteString -> Digest a
, so before I can produce a hashlazy (hashlazy x)
, I'll need to translate a Digest into a ByteString.
Although there is a digestFromByteString function provided, there is no such function for the reverse (maybe it doesn't make sense for all Digests?).
So the only way I found is to do this :
-- produce a hexadecimal string representation of the digest
myHash :: ByteString -> String
myHash b = show (hashlazy bs :: Digest SHA256)
-- convert a hexadecimal string into a ByteString
fromHexString :: String -> ByteString
fromHexString = undefined
and then I can now do hashhash x = myHash $ fromHexString $ myHash x
...
But that looks very cumbersome.
My question: Am I using the library functions properly? Did I miss a conversion function somewhere? Or should I do things differently?
=== EDIT 1 ===
I wanted to keep my question simple and avoided other details which I thought weren't important, but I do need to convert the hash result back into a ByteString, as I need to do manipulate it before hashing again. Eg,
-- myByteString is a constant
-- firstByteString is original input
finalResult = hash $ append myByteString (hash firstByteString)
=== EDIT 2 ===
I accepted ben's answer, and learned from it, but for future reference, one way to convert Crypto.Hash's Digest a
into a ByteString
is via the memory package's Data.ByteArray module and the pack function :
module Main where
import Data.ByteString
import Data.ByteString as BS (pack)
import Data.ByteArray (ByteArrayAccess)
import qualified Data.ByteArray as BA (unpack)
import Crypto.Hash (Digest, hash)
import Crypto.Hash.Algorithms (SHA256(..))
somehash = hash ("foo" :: ByteString) :: Digest SHA256
toByteString :: ByteArrayAccess a => a -> ByteString
toByteString = BS.pack . BA.unpack
somebytestring = toByteString somehash