packages feed

ppad-sha512 0.2.0 → 0.2.1

raw patch · 4 files changed

+75/−1 lines, 4 filesdep +quickcheck-instancesdep +tasty-quickcheckPVP ok

version bump matches the API change (PVP)

Dependencies added: quickcheck-instances, tasty-quickcheck

API changes (from Hackage documentation)

Files

CHANGELOG view
@@ -1,5 +1,9 @@ # Changelog +- 0.2.1 (2026-01-11)+  * Adds a basic quickcheck test suite for asserting memory safety of+    library functions on random inputs.+ - 0.2.0 (2026-01-10)   * The HMAC functions now produce a value of type MAC, which is a     newtype over a ByteString. The 'Eq' instance for MAC compares values
ppad-sha512.cabal view
@@ -1,6 +1,6 @@ cabal-version:      3.0 name:               ppad-sha512-version:            0.2.0+version:            0.2.1 synopsis:           The SHA-512 and HMAC-SHA512 algorithms license:            MIT license-file:       LICENSE@@ -49,6 +49,7 @@   hs-source-dirs:      test   main-is:             Main.hs   other-modules:+    Property     Wycheproof    ghc-options:@@ -60,8 +61,10 @@     , bytestring     , ppad-base16     , ppad-sha512+    , quickcheck-instances     , tasty     , tasty-hunit+    , tasty-quickcheck     , text  benchmark sha512-bench
test/Main.hs view
@@ -14,6 +14,7 @@ import qualified Data.Text.IO as TIO import Test.Tasty import Test.Tasty.HUnit+import qualified Property import qualified Wycheproof as W  main :: IO ()@@ -24,6 +25,7 @@     Just w  -> defaultMain $ testGroup "ppad-sha512" [         unit_tests       , wycheproof_tests w+      , Property.properties       ]  wycheproof_tests :: W.Wycheproof -> TestTree
+ test/Property.hs view
@@ -0,0 +1,65 @@+{-# OPTIONS_GHC -fno-warn-orphans #-}++module Property (+    properties+  ) where++import qualified Data.ByteString as BS+import qualified Data.ByteString.Lazy as BL+import Crypto.Hash.SHA512+import Test.Tasty+import qualified Test.Tasty.QuickCheck as Q+import Test.QuickCheck.Instances.ByteString ()++-- strict/lazy hash equivalence+hash_equiv :: BS.ByteString -> Bool+hash_equiv bs = hash bs == hash_lazy (BL.fromStrict bs)++-- strict/lazy hmac equivalence+hmac_equiv :: BS.ByteString -> BS.ByteString -> Bool+hmac_equiv k m = hmac k m == hmac_lazy k (BL.fromStrict m)++-- hash output is always 64 bytes+hash_length :: BS.ByteString -> Bool+hash_length bs = BS.length (hash bs) == 64++-- hmac output is always 64 bytes+hmac_length :: BS.ByteString -> BS.ByteString -> Bool+hmac_length k m = let MAC h = hmac k m in BS.length h == 64++-- hash_lazy produces same result regardless of chunking+hash_chunking :: BS.ByteString -> [Q.Positive Int] -> Bool+hash_chunking bs chunks =+  let lazy_single = BL.fromStrict bs+      lazy_chunked = BL.fromChunks (chunk_by (map Q.getPositive chunks) bs)+  in  hash_lazy lazy_single == hash_lazy lazy_chunked++-- hmac_lazy produces same result regardless of chunking+hmac_chunking :: BS.ByteString -> BS.ByteString -> [Q.Positive Int] -> Bool+hmac_chunking k m chunks =+  let lazy_single = BL.fromStrict m+      lazy_chunked = BL.fromChunks (chunk_by (map Q.getPositive chunks) m)+  in  hmac_lazy k lazy_single == hmac_lazy k lazy_chunked++chunk_by :: [Int] -> BS.ByteString -> [BS.ByteString]+chunk_by _ bs | BS.null bs = []+chunk_by [] bs = [bs]+chunk_by (n:ns) bs =+  let (h, t) = BS.splitAt n bs+  in  h : chunk_by ns t++properties :: TestTree+properties = testGroup "properties" [+    Q.testProperty "hash == hash_lazy" $+      Q.withMaxSuccess 1000 hash_equiv+  , Q.testProperty "hmac == hmac_lazy" $+      Q.withMaxSuccess 1000 hmac_equiv+  , Q.testProperty "hash output is 64 bytes" $+      Q.withMaxSuccess 1000 hash_length+  , Q.testProperty "hmac output is 64 bytes" $+      Q.withMaxSuccess 1000 hmac_length+  , Q.testProperty "hash_lazy chunking-invariant" $+      Q.withMaxSuccess 1000 hash_chunking+  , Q.testProperty "hmac_lazy chunking-invariant" $+      Q.withMaxSuccess 1000 hmac_chunking+  ]