git-annex-10.20260624: Utility/Hash/Crypton.hs
{- Convenience wrapper around crypton's hashing.
-
- Copyright 2013-2026 Joey Hess <id@joeyh.name>
-
- License: BSD-2-clause
-}
{-# LANGUAGE BangPatterns, PackageImports #-}
{-# LANGUAGE RankNTypes #-}
module Utility.Hash.Crypton (
sha1,
sha1_hasher,
sha1s,
sha2_224,
sha2_224_hasher,
sha2_256,
sha2_256_hasher,
sha2_384,
sha2_384_hasher,
sha2_512,
sha2_512_hasher,
sha3_224,
sha3_224_hasher,
sha3_256,
sha3_256_hasher,
sha3_384,
sha3_384_hasher,
sha3_512,
sha3_512_hasher,
skein256,
skein256_hasher,
skein512,
skein512_hasher,
blake2s_160,
blake2s_160_hasher,
blake2s_224,
blake2s_224_hasher,
blake2s_256,
blake2s_256_hasher,
blake2sp_224,
blake2sp_224_hasher,
blake2sp_256,
blake2sp_256_hasher,
blake2b_160,
blake2b_160_hasher,
blake2b_224,
blake2b_224_hasher,
blake2b_256,
blake2b_256_hasher,
blake2b_384,
blake2b_384_hasher,
blake2b_512,
blake2b_512_hasher,
blake2bp_512,
blake2bp_512_hasher,
md5,
md5_hasher,
md5s,
hashUpdate,
hashFinalize,
Digest,
HashAlgorithm,
Context,
mkIncrementalHasher,
mkIncrementalVerifier,
) where
import qualified Data.ByteString as S
import qualified Data.ByteString.Lazy as L
import Data.IORef
import qualified Data.ByteArray as BA
import "crypton" Crypto.Hash
import Utility.Hash.Types
import Utility.Hash.Incremental
sha1 :: L.ByteString -> HashDigest
sha1 = hashDigest . (hashlazy :: HashLazy SHA1)
sha1_hasher :: IO IncrementalHasher
sha1_hasher = mkIncrementalHasher (hashInit :: Context SHA1)
sha1s :: S.ByteString -> HashDigest
sha1s = hashDigest . (hash :: HashStrict SHA1)
sha2_224 :: L.ByteString -> HashDigest
sha2_224 = hashDigest . (hashlazy :: HashLazy SHA224)
sha2_224_hasher :: IO IncrementalHasher
sha2_224_hasher = mkIncrementalHasher (hashInit :: Context SHA224)
sha2_256 :: L.ByteString -> HashDigest
sha2_256 = hashDigest . (hashlazy :: HashLazy SHA256)
sha2_256_hasher :: IO IncrementalHasher
sha2_256_hasher = mkIncrementalHasher (hashInit :: Context SHA256)
sha2_384 :: L.ByteString -> HashDigest
sha2_384 = hashDigest . (hashlazy :: HashLazy SHA384)
sha2_384_hasher :: IO IncrementalHasher
sha2_384_hasher = mkIncrementalHasher (hashInit :: Context SHA384)
sha2_512 :: L.ByteString -> HashDigest
sha2_512 = hashDigest . (hashlazy :: HashLazy SHA512)
sha2_512_hasher :: IO IncrementalHasher
sha2_512_hasher = mkIncrementalHasher (hashInit :: Context SHA512)
sha3_224 :: L.ByteString -> HashDigest
sha3_224 = hashDigest . (hashlazy :: HashLazy SHA3_224)
sha3_224_hasher :: IO IncrementalHasher
sha3_224_hasher = mkIncrementalHasher (hashInit :: Context SHA3_224)
sha3_256 :: L.ByteString -> HashDigest
sha3_256 = hashDigest . (hashlazy :: HashLazy SHA3_256)
sha3_256_hasher :: IO IncrementalHasher
sha3_256_hasher = mkIncrementalHasher (hashInit :: Context SHA3_256)
sha3_384 :: L.ByteString -> HashDigest
sha3_384 = hashDigest . (hashlazy :: HashLazy SHA3_384)
sha3_384_hasher :: IO IncrementalHasher
sha3_384_hasher = mkIncrementalHasher (hashInit :: Context SHA3_384)
sha3_512 :: L.ByteString -> HashDigest
sha3_512 = hashDigest . (hashlazy :: HashLazy SHA3_512)
sha3_512_hasher :: IO IncrementalHasher
sha3_512_hasher = mkIncrementalHasher (hashInit :: Context SHA3_512)
skein256 :: L.ByteString -> HashDigest
skein256 = hashDigest . (hashlazy :: HashLazy Skein256_256)
skein256_hasher :: IO IncrementalHasher
skein256_hasher = mkIncrementalHasher (hashInit :: Context Skein256_256)
skein512 :: L.ByteString -> HashDigest
skein512 = hashDigest . (hashlazy :: HashLazy Skein512_512)
skein512_hasher :: IO IncrementalHasher
skein512_hasher = mkIncrementalHasher (hashInit :: Context Skein512_512)
blake2s_160 :: L.ByteString -> HashDigest
blake2s_160 = hashDigest . (hashlazy :: HashLazy Blake2s_160)
blake2s_160_hasher :: IO IncrementalHasher
blake2s_160_hasher = mkIncrementalHasher (hashInit :: Context Blake2s_160)
blake2s_224 :: L.ByteString -> HashDigest
blake2s_224 = hashDigest . (hashlazy :: HashLazy Blake2s_224)
blake2s_224_hasher :: IO IncrementalHasher
blake2s_224_hasher = mkIncrementalHasher (hashInit :: Context Blake2s_224)
blake2s_256 :: L.ByteString -> HashDigest
blake2s_256 = hashDigest . (hashlazy :: HashLazy Blake2s_256)
blake2s_256_hasher :: IO IncrementalHasher
blake2s_256_hasher = mkIncrementalHasher (hashInit :: Context Blake2s_256)
blake2sp_224 :: L.ByteString -> HashDigest
blake2sp_224 = hashDigest . (hashlazy :: HashLazy Blake2sp_224)
blake2sp_224_hasher :: IO IncrementalHasher
blake2sp_224_hasher = mkIncrementalHasher (hashInit :: Context Blake2sp_224)
blake2sp_256 :: L.ByteString -> HashDigest
blake2sp_256 = hashDigest . (hashlazy :: HashLazy Blake2sp_256)
blake2sp_256_hasher :: IO IncrementalHasher
blake2sp_256_hasher = mkIncrementalHasher (hashInit :: Context Blake2sp_256)
blake2b_160 :: L.ByteString -> HashDigest
blake2b_160 = hashDigest . (hashlazy :: HashLazy Blake2b_160)
blake2b_160_hasher :: IO IncrementalHasher
blake2b_160_hasher = mkIncrementalHasher (hashInit :: Context Blake2b_160)
blake2b_224 :: L.ByteString -> HashDigest
blake2b_224 = hashDigest . (hashlazy :: HashLazy Blake2b_224)
blake2b_224_hasher :: IO IncrementalHasher
blake2b_224_hasher = mkIncrementalHasher (hashInit :: Context Blake2b_224)
blake2b_256 :: L.ByteString -> HashDigest
blake2b_256 = hashDigest . (hashlazy :: HashLazy Blake2b_256)
blake2b_256_hasher :: IO IncrementalHasher
blake2b_256_hasher = mkIncrementalHasher (hashInit :: Context Blake2b_256)
blake2b_384 :: L.ByteString -> HashDigest
blake2b_384 = hashDigest . (hashlazy :: HashLazy Blake2b_384)
blake2b_384_hasher :: IO IncrementalHasher
blake2b_384_hasher = mkIncrementalHasher (hashInit :: Context Blake2b_384)
blake2b_512 :: L.ByteString -> HashDigest
blake2b_512 = hashDigest . (hashlazy :: HashLazy Blake2b_512)
blake2b_512_hasher :: IO IncrementalHasher
blake2b_512_hasher = mkIncrementalHasher (hashInit :: Context Blake2b_512)
blake2bp_512 :: L.ByteString -> HashDigest
blake2bp_512 = hashDigest . (hashlazy :: HashLazy Blake2bp_512)
blake2bp_512_hasher :: IO IncrementalHasher
blake2bp_512_hasher = mkIncrementalHasher (hashInit :: Context Blake2bp_512)
md5 :: L.ByteString -> HashDigest
md5 = hashDigest . (hashlazy :: HashLazy MD5)
md5_hasher :: IO IncrementalHasher
md5_hasher = mkIncrementalHasher (hashInit :: Context MD5)
md5s :: S.ByteString -> HashDigest
md5s = hashDigest . (hash :: HashStrict MD5)
type HashStrict t = S.ByteString -> Digest t
type HashLazy t = L.ByteString -> Digest t
hashDigest :: Digest a -> HashDigest
hashDigest = HashDigest . BA.convert
mkIncrementalHasher :: HashAlgorithm h => Context h -> IO IncrementalHasher
mkIncrementalHasher ctx = do
v <- newIORef (Just (ctx, 0))
return $ IncrementalHasher
{ updateIncrementalHasher = \b ->
modifyIORef' v $ \case
(Just (ctx', n)) ->
let !ctx'' = hashUpdate ctx' b
!n' = n + fromIntegral (S.length b)
in (Just (ctx'', n'))
Nothing -> Nothing
, finalizeIncrementalHasher =
readIORef v >>= \case
(Just (ctx', _)) -> return $ Just $
hashDigest $ hashFinalize ctx'
Nothing -> return Nothing
, unableIncrementalHasher = writeIORef v Nothing
, positionIncrementalHasher = readIORef v >>= \case
Just (_, n) -> return (Just n)
Nothing -> return Nothing
}