Crypto Multihash
Multihash library implemented on top of cryptonite cryptographic library.
Multihash is a protocol for encoding the hash algorithm and digest length at the start of the digest, see the official multihash github page.
This library is still experimental and the api is not guaranteed stable.
I will increment the version number appropriately in case of breaking changes.
For the moment the library implements all the expected hashing algorithms with the exception of shake-128 and shake-256. A Multihash can be encoded in hex (Base16
), base 32 (Base32
), bitcoin base58 (Base58
) and base64 (Base64
).
Usage
-- in ghci `:set -XOverloadedStrings`
{-# LANGUAGE OverloadedStrings #-}
-- `:m +Crypto.Multihash`
import Crypto.Multihash
import Data.ByteString (ByteString)
main = do
let v = "test"::ByteString
let m = multihash SHA256 v
-- If using the Weak module
-- let m' = weakMultihash "sha256" v
putStrLn $ "Base16: " ++ (encode' Base16 m)
-- You might need to specify the encoded string type
putStrLn $ "Base58: " ++ (encode' Base58 m :: String)
-- `encode` is the safe interface returning an `Either` type
putStrLn $ "Base64: " ++ show (encode Base64 m :: Either String String)
let h = encode' Base58 m :: ByteString
-- You can check that a multihash corresponds to some data `v`
checkMultihash h v
-- Right True
-- Or if you have a Multihash to compare you can use it
check h m
-- Right True
-- There is also an unsafe version, as for encode
-- note that sometimes you will need to specify the string types
checkMultihash' ("whatever"::String) v
-- *** Exception: Unable to infer an encoding
checkMultihash' ("Eiwhatever"::ByteString) v
-- *** Exception: base64: input: invalid length
check' ("EiCfhtCBiEx9ZZov6qDFWtAVo79PGysLgizRXWwVsPA1CA=="::ByteString) m
-- False
checkMultihash' h v
-- True
check' h m
-- True
The of import Crypto.Multihash.Weak
is almost identical, but it additionally introduces the function toWeakMultihash
that tries to import a string as a WeakMultihashDigest
.
Test
Some preliminary tests can be performed with stack test
.
A simple example encoder is in app/Main.hs
.
You can run it on files
echo -n test | stack exec mh -- somefile someotherfile
or read data from the standard input
echo -n test | stack exec mh -- -
Contribution
- Fork repository
- Do some changes
- Create pull request
- Wait for CI build and review
You can use stack to build the project: stack build
To run tests: stack test
TODO
Test the new getBase
implementation using quickcheck
- Accurately test the correct support of truncated multihashes, including the truncation length that triggers easy failures in
getBase
- Implement benchmarks, then start optimising the code where possible
Use the hash length in checkPayload
to treat correctly truncated hashes (see https://github.com/jbenet/multihash/issues/1#issuecomment-91783612)
- Improve documentation
- Implement
shake-128
and shake-256
multihashes
Implement Base32
encoding waiting for https://github.com/jbenet/multihash/issues/31 to be resolved)