1 {-# LANGUAGE CPP, ForeignFunctionInterface #-} 2 3 -- | 4 -- Module: Data.Digest.SHA256 5 -- Copyright: Zooko O'Whielacronx 6 -- License: GPL 7 -- 8 -- Stability: experimental 9 10 -- ByteString-based, zero-copying binding to Crypto++'s sha interface 11 12 -- thanks to Don Stewart <dons@galois.com>, Matthew Sackman 13 -- <matthew@wellquite.org>, Brian O'Sullivan, lispy, Adam Langley 14 15 module Crypt.SHA256 ( sha256sum ) where 16 17 import Foreign 18 import Foreign.C.Types 19 import Numeric (showHex) 20 import Foreign.C.String ( withCString ) 21 import Data.ByteString.Unsafe (unsafeUseAsCStringLen) 22 import qualified Data.ByteString as B 23 24 sha256sum :: B.ByteString -> String 25 sha256sum p = unsafePerformIO $ 26 withCString (take 64 $ repeat 'x') $ \digestCString -> 27 unsafeUseAsCStringLen p $ \(ptr,n) -> 28 do let digest = castPtr digestCString :: Ptr Word8 29 c_sha256 ptr (fromIntegral n) digest 30 go digest 0 [] 31 where -- print it in 0-padded hex format 32 go :: Ptr Word8 -> Int -> [String] -> IO String 33 go q n acc | seq q n >= 32 = return $ concat (reverse acc) 34 | otherwise = do w <- peekElemOff q n 35 go q (n+1) (draw w : acc) 36 draw w = case showHex w [] of 37 [x] -> ['0', x] 38 x -> x 39 40 -- void sha256sum(const unsigned char *d, size_t n, unsigned char *md); 41 -- 42 foreign import ccall unsafe "sha2.h sha256" c_sha256 43 :: Ptr CChar -> CSize -> Ptr Word8 -> IO () 44