pbkdf

Pure Haskell password-based KDF (docs.ppad.tech/pbkdf).
git clone git://git.ppad.tech/pbkdf.git
Log | Files | Refs | README | LICENSE

Main.hs (2126B)


      1 {-# LANGUAGE OverloadedStrings #-}
      2 {-# LANGUAGE RecordWildCards #-}
      3 
      4 module Main where
      5 
      6 import Control.Exception
      7 import qualified Crypto.Hash.SHA256 as SHA256
      8 import qualified Crypto.Hash.SHA512 as SHA512
      9 import qualified Crypto.KDF.PBKDF as KDF
     10 import qualified Data.ByteString as BS
     11 import qualified Data.Aeson as A
     12 import qualified Data.Text.IO as TIO
     13 import Test.Tasty
     14 import Test.Tasty.HUnit
     15 import qualified Wycheproof as W
     16 
     17 main :: IO ()
     18 main = do
     19   wycheproof_hmacsha256 <- TIO.readFile "etc/pbkdf2_hmacsha256_test.json"
     20   wycheproof_hmacsha512 <- TIO.readFile "etc/pbkdf2_hmacsha512_test.json"
     21   let wycheproofs = do
     22         a <- A.decodeStrictText wycheproof_hmacsha256 :: Maybe W.Wycheproof
     23         b <- A.decodeStrictText wycheproof_hmacsha512 :: Maybe W.Wycheproof
     24         pure (a, b)
     25   case wycheproofs of
     26     Nothing -> error "couldn't parse wycheproof vectors"
     27     Just (w256, w512) -> defaultMain $ testGroup "ppad-pbkdf" [
     28         wycheproof_tests SHA256 w256
     29       , wycheproof_tests SHA512 w512
     30       ]
     31 
     32 data Hash = SHA256 | SHA512
     33   deriving Show
     34 
     35 wycheproof_tests :: Hash -> W.Wycheproof -> TestTree
     36 wycheproof_tests h W.Wycheproof {..} =
     37   testGroup ("wycheproof vectors (pbkdf, " <> show h <> ")") $
     38     fmap (execute_group h) wp_testGroups
     39 
     40 execute_group :: Hash -> W.PbkdfTestGroup -> TestTree
     41 execute_group h W.PbkdfTestGroup {..} =
     42   testGroup mempty (fmap (execute h) ptg_tests)
     43 
     44 execute :: Hash -> W.PbkdfTest -> TestTree
     45 execute h W.PbkdfTest {..} = testCase t_msg $ do
     46     let pas = pt_password
     47         sal = pt_salt
     48         cow = pt_iterationCount
     49         siz = pt_dkLen
     50         pec = pt_dk
     51     if   pt_result == "invalid"
     52     then do
     53       out <- try (pure $! KDF.derive hmac pas sal cow siz)
     54                :: IO (Either ErrorCall BS.ByteString)
     55       case out of
     56         Left _  -> assertBool "invalid" True
     57         Right o -> assertBool "invalid" (pec /= o)
     58     else do
     59       let out = KDF.derive hmac pas sal cow siz
     60       assertEqual mempty pec out
     61   where
     62     hmac = case h of
     63       SHA256 -> SHA256.hmac
     64       SHA512 -> SHA512.hmac
     65     t_msg = "test " <> show pt_tcId -- XX embellish
     66