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