cryptonite: Why is `digestFromByteString` Nothing?

I'm trying to verify a signature on a web request. I need to compute an HMAC with the SHA256 hash function using my secret as the key and a signed payload as the message, then compare that with the signature.

The signature looks like this: 0d586561d8f896e52d5c4a2147609fdf74eb72e7bcb3a3756b89fcbef88a94b3

It seems like cryptonite is the right library for this, so I'm using hmac from Crypto.MAC.HMAC. Here's what I have so far:

case digestFromByteString signature of
  Nothing -> return False
  Just signatureDigest ->
    return $ signatureDigest `constEq` hmacGetDigest (hmac secret signedPayload :: HMAC SHA256)

Visually the digest and the signature look the same. If I convert both sides to strings, the strings are equal.

show hmacHash == T.unpack (T.decodeUtf8 signature) -- This is True!

But I can't even get so far as constEq because when I use digestFromByteString to convert the signature string into a digest, it fails. Why?

(Also if I'm barking up the wrong tree on anything else, please let me know.)


I finally found out the answer from a Google search that lead to an old Gitter discussion.

Even though digestFromByteString will take a hex-encoded ByteString, it doesn't know what to do with it. I had to use memory's convertFromBase to convert from base16.

I added this before my conversion to the digest, and now everything works!

case convertFromBase Base16 hexSignature of
  Left err -> return False
  Right signature -> ...

(Leaving this unanswered in case anyone who actually knows about cryptonite can explain the "why" better...)