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.SHA256 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 32 bytes 23 hash_length :: BS.ByteString -> Bool 24 hash_length bs = BS.length (hash bs) == 32 25 26 -- hmac output is always 32 bytes 27 hmac_length :: BS.ByteString -> BS.ByteString -> Bool 28 hmac_length k m = let MAC h = hmac k m in BS.length h == 32 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 32 bytes" $ 58 Q.withMaxSuccess 1000 hash_length 59 , Q.testProperty "hmac output is 32 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 ]