sha512

Pure Haskell SHA-512, HMAC-SHA512 (docs.ppad.tech/sha512).
git clone git://git.ppad.tech/sha512.git
Log | Files | Refs | README | LICENSE

Property.hs (2248B)


      1 {-# OPTIONS_GHC -fno-warn-orphans #-}
      2 
      3 module Property (
      4     properties
      5   ) where
      6 
      7 import qualified Data.ByteString as BS
      8 import qualified Data.ByteString.Lazy as BL
      9 import Crypto.Hash.SHA512
     10 import Test.Tasty
     11 import qualified Test.Tasty.QuickCheck as Q
     12 import Test.QuickCheck.Instances.ByteString ()
     13 
     14 -- strict/lazy hash equivalence
     15 hash_equiv :: BS.ByteString -> Bool
     16 hash_equiv bs = hash bs == hash_lazy (BL.fromStrict bs)
     17 
     18 -- strict/lazy hmac equivalence
     19 hmac_equiv :: BS.ByteString -> BS.ByteString -> Bool
     20 hmac_equiv k m = hmac k m == hmac_lazy k (BL.fromStrict m)
     21 
     22 -- hash output is always 64 bytes
     23 hash_length :: BS.ByteString -> Bool
     24 hash_length bs = BS.length (hash bs) == 64
     25 
     26 -- hmac output is always 64 bytes
     27 hmac_length :: BS.ByteString -> BS.ByteString -> Bool
     28 hmac_length k m = let MAC h = hmac k m in BS.length h == 64
     29 
     30 -- hash_lazy produces same result regardless of chunking
     31 hash_chunking :: BS.ByteString -> [Q.Positive Int] -> Bool
     32 hash_chunking bs chunks =
     33   let lazy_single = BL.fromStrict bs
     34       lazy_chunked = BL.fromChunks (chunk_by (map Q.getPositive chunks) bs)
     35   in  hash_lazy lazy_single == hash_lazy lazy_chunked
     36 
     37 -- hmac_lazy produces same result regardless of chunking
     38 hmac_chunking :: BS.ByteString -> BS.ByteString -> [Q.Positive Int] -> Bool
     39 hmac_chunking k m chunks =
     40   let lazy_single = BL.fromStrict m
     41       lazy_chunked = BL.fromChunks (chunk_by (map Q.getPositive chunks) m)
     42   in  hmac_lazy k lazy_single == hmac_lazy k lazy_chunked
     43 
     44 chunk_by :: [Int] -> BS.ByteString -> [BS.ByteString]
     45 chunk_by _ bs | BS.null bs = []
     46 chunk_by [] bs = [bs]
     47 chunk_by (n:ns) bs =
     48   let (h, t) = BS.splitAt n bs
     49   in  h : chunk_by ns t
     50 
     51 properties :: TestTree
     52 properties = testGroup "properties" [
     53     Q.testProperty "hash == hash_lazy" $
     54       Q.withMaxSuccess 1000 hash_equiv
     55   , Q.testProperty "hmac == hmac_lazy" $
     56       Q.withMaxSuccess 1000 hmac_equiv
     57   , Q.testProperty "hash output is 64 bytes" $
     58       Q.withMaxSuccess 1000 hash_length
     59   , Q.testProperty "hmac output is 64 bytes" $
     60       Q.withMaxSuccess 1000 hmac_length
     61   , Q.testProperty "hash_lazy chunking-invariant" $
     62       Q.withMaxSuccess 1000 hash_chunking
     63   , Q.testProperty "hmac_lazy chunking-invariant" $
     64       Q.withMaxSuccess 1000 hmac_chunking
     65   ]