{-# LANGUAGE CPP, ForeignFunctionInterface #-} -- | -- Module: Data.Digest.SHA256 -- Copyright: Zooko O'Whielacronx -- License: GPL -- -- Stability: experimental -- ByteString-based, zero-copying binding to Crypto++'s sha interface -- thanks to Don Stewart , Matthew Sackman -- , Brian O'Sullivan, lispy, Adam Langley module Crypt.SHA256 ( sha256sum ) where import Foreign import Foreign.C.Types import Numeric (showHex) import Foreign.C.String ( withCString ) import Data.ByteString.Unsafe (unsafeUseAsCStringLen) import qualified Data.ByteString as B sha256sum :: B.ByteString -> String sha256sum p = unsafePerformIO $ withCString (take 64 $ repeat 'x') $ \digestCString -> unsafeUseAsCStringLen p $ \(ptr,n) -> do let digest = castPtr digestCString :: Ptr Word8 c_sha256 ptr (fromIntegral n) digest go digest 0 [] where -- print it in 0-padded hex format go :: Ptr Word8 -> Int -> [String] -> IO String go q n acc | seq q n >= 32 = return $ concat (reverse acc) | otherwise = do w <- peekElemOff q n go q (n+1) (draw w : acc) draw w = case showHex w [] of [x] -> ['0', x] x -> x -- void sha256sum(const unsigned char *d, size_t n, unsigned char *md); -- foreign import ccall unsafe "sha2.h sha256" c_sha256 :: Ptr CChar -> CSize -> Ptr Word8 -> IO ()