/Benchmarks/Benchmarks.hs

http://github.com/vincenthz/hs-cryptocipher · Haskell · 113 lines · 92 code · 19 blank · 2 comment · 1 complexity · 60a3ca266b976f62d9d0c4b57b8cfe8a MD5 · raw file

  1. {-# LANGUAGE CPP #-}
  2. import Criterion
  3. import Criterion.Environment
  4. import Criterion.Config
  5. import Criterion.Monad
  6. import Criterion.Analysis
  7. import Criterion.Measurement
  8. import Text.Printf
  9. import Control.Monad.Trans
  10. import qualified Data.ByteString as B
  11. import qualified Data.ByteString.Lazy as L
  12. import qualified Crypto.Cipher.AES.Haskell as AES
  13. #ifdef HAVE_AESNI
  14. import qualified Crypto.Cipher.AES.X86NI as AESNI
  15. #endif
  16. import qualified Crypto.Cipher.RC4 as RC4
  17. import qualified Crypto.Cipher.Blowfish as Blowfish
  18. import qualified Crypto.Cipher.Camellia as Camellia
  19. import Crypto.Classes
  20. import qualified Crypto.Modes as CAPI
  21. (Right key128) = AES.initKey128 $ B.replicate 16 0
  22. aesEncrypt128 = AES.encrypt key128
  23. aesEncrypt128CBC = AES.encryptCBC key128 (B.replicate 16 0)
  24. (Right key192) = AES.initKey192 $ B.replicate 24 0
  25. aesEncrypt192 = AES.encrypt key192
  26. aesEncrypt192CBC = AES.encryptCBC key192 (B.replicate 16 0)
  27. (Right key256) = AES.initKey256 $ B.replicate 32 0
  28. aesEncrypt256 = AES.encrypt key256
  29. aesEncrypt256CBC = AES.encryptCBC key256 (B.replicate 16 0)
  30. (Just capi_key128) = buildKey (B.replicate 16 0) :: Maybe AES.AES128
  31. aesEncrypt128CBC_capi = fst . CAPI.cbc' capi_key128 CAPI.zeroIV
  32. #ifdef HAVE_AESNI
  33. key128_ni = AESNI.initKey128 $ B.replicate 16 0
  34. aesniEncrypt128 = AESNI.encrypt key128_ni
  35. aesniEncrypt128CBC = AESNI.encryptCBC key128_ni (B.replicate 16 0)
  36. #endif
  37. (Right blowfishKey) = Blowfish.initKey $ B.empty
  38. blowfishEncrypt = Blowfish.encrypt blowfishKey
  39. (Right camelliaKey128) = Camellia.initKey128 $ B.replicate 16 0
  40. camelliaEncrypt128 = Camellia.encrypt camelliaKey128
  41. rc4Key = RC4.initCtx $ replicate 16 0
  42. rc4Encrypt = snd . RC4.encrypt rc4Key
  43. b16 f = whnf f $ B.replicate 16 0
  44. b32 f = whnf f $ B.replicate 32 0
  45. b128 f = whnf f $ B.replicate 128 0
  46. b512 f = whnf f $ B.replicate 512 0
  47. b1024 f = whnf f $ B.replicate 1024 0
  48. b4096 f = whnf f $ B.replicate 4096 0
  49. doCipher env f = do
  50. mean16 <- runBenchmark env (b16 f) >>= \sample -> analyseMean sample 100
  51. mean32 <- runBenchmark env (b32 f) >>= \sample -> analyseMean sample 100
  52. mean128 <- runBenchmark env (b128 f) >>= \sample -> analyseMean sample 100
  53. mean512 <- runBenchmark env (b512 f) >>= \sample -> analyseMean sample 100
  54. mean1024 <- runBenchmark env (b1024 f) >>= \sample -> analyseMean sample 100
  55. mean4096 <- runBenchmark env (b4096 f) >>= \sample -> analyseMean sample 100
  56. return (mean16, mean32, mean128, mean512, mean1024, mean4096)
  57. norm :: Int -> Double -> Double
  58. norm n time
  59. | n < 1024 = 1.0 / (time * (1024 / fromIntegral n))
  60. | n == 1024 = 1.0 / time
  61. | n > 1024 = 1.0 / (time / (fromIntegral n / 1024))
  62. pn :: Int -> Double -> String
  63. pn n time = printf "%.1f K/s" (norm n time)
  64. doOne env (cipherName, f) = do
  65. (mean16, mean32, mean128, mean512, mean1024, mean4096) <- doCipher env f
  66. let s = printf "%12s: %12s %12s %12s %12s %12s %12s\n %12s %12s %12s %12s %12s %12s"
  67. cipherName
  68. (secs mean16) (secs mean32) (secs mean128)
  69. (secs mean512) (secs mean1024) (secs mean4096)
  70. (pn 16 mean16) (pn 32 mean32) (pn 128 mean128)
  71. (pn 512 mean512) (pn 1024 mean1024) (pn 4096 mean4096)
  72. return s
  73. main = withConfig defaultConfig $ do
  74. env <- measureEnvironment
  75. l <- mapM (doOne env)
  76. [ ("RC4" , rc4Encrypt)
  77. , ("Blowfish" , blowfishEncrypt)
  78. , ("Camellia128", camelliaEncrypt128)
  79. , ("AES128" , aesEncrypt128)
  80. , ("AES128-CBC" , aesEncrypt128CBC)
  81. #ifdef HAVE_AESNI
  82. , ("AES128-ni" , aesniEncrypt128)
  83. , ("AES128ni-CBC" , aesniEncrypt128CBC)
  84. #endif
  85. -- , ("AES128-CBC-capi", aesEncrypt128CBC_capi)
  86. , ("AES192" , aesEncrypt192)
  87. , ("AES192-CBC" , aesEncrypt192CBC)
  88. , ("AES256" , aesEncrypt256)
  89. , ("AES256-CBC" , aesEncrypt256CBC)
  90. ]
  91. liftIO $ printf "%12s| %12s %12s %12s %12s %12s %12s\n"
  92. "cipher" "16 bytes" "32 bytes" "64 bytes" "512 bytes" "1024 bytes" "4096 bytes"
  93. liftIO $ printf "=============================================================================================\n"
  94. mapM_ (liftIO . putStrLn) l