darcs-2.1.2.1: src/Crypt/SHA256.hs
{-# OPTIONS_GHC -fffi -cpp #-}
{-# 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 <dons@galois.com>, Matthew Sackman
-- <matthew@wellquite.org>, 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 )
#if __GLASGOW_HASKELL__ > 606
import Data.ByteString.Unsafe (unsafeUseAsCStringLen)
#else
import Data.ByteString.Base (unsafeUseAsCStringLen)
#endif
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 ()