packages feed

crypto-cipher-benchmarks (empty) → 0.0.1

raw patch · 4 files changed

+255/−0 lines, 4 filesdep +basedep +byteabledep +bytestringsetup-changed

Dependencies added: base, byteable, bytestring, criterion, crypto-cipher-types, mtl, pretty, securemem

Files

+ Crypto/Cipher/Benchmarks.hs view
@@ -0,0 +1,195 @@+-- |+-- Module      : Crypto.Cipher.Benchmarks+-- License     : BSD-style+-- Maintainer  : Vincent Hanquez <vincent@snarc.org>+-- Stability   : Stable+-- Portability : Excellent+--+-- benchmarks for symmetric ciphers+--+{-# LANGUAGE ExistentialQuantification #-}+{-# LANGUAGE Rank2Types #-}+module Crypto.Cipher.Benchmarks+    ( defaultMain+    , GBlockCipher(..)+    ) where++import Control.Applicative+import Criterion+import Criterion.Environment+import Criterion.Config hiding (Help)+import Criterion.Monad+import Criterion.Analysis+import Criterion.Measurement++import Text.Printf+import Text.PrettyPrint hiding (Mode, mode)++import Data.Maybe+import Control.Monad.Trans++import qualified Data.ByteString as B++import Crypto.Cipher.Types++import System.Console.GetOpt+import System.Environment+import System.Exit++import Data.Char (toUpper)++-- | Generic Block cipher that wrap a specific block cipher.+data GBlockCipher = forall a . BlockCipher a => GBlockCipher a++data Mode = ECB+          | CBC+          | CTR+          | XTS+          | OCB+          | CCM+          | EAX+          | CWC+          | GCM+          deriving (Show, Enum, Bounded)++defaultSzs :: [Int]+defaultSzs = [16,32,128,512,1024,4096,16384]++defaultModes :: [Mode]+defaultModes = [minBound..]++doCipher :: Environment -> Int -> [Int] -> (B.ByteString -> B.ByteString) -> Criterion [Double]+doCipher env nbIter szs f = mapM getMeanFromBench szs+  where getMeanFromBench sz =+            runBenchmark env (whnf f $ B.replicate sz 0) >>= \sample ->+            analyseMean sample nbIter >>= return++modeToBench :: BlockCipher cipher => cipher -> Mode -> Maybe (B.ByteString -> B.ByteString)+modeToBench cipher ECB = Just $ ecbEncrypt cipher+modeToBench cipher CBC = Just $ cbcEncrypt cipher nullIV+modeToBench cipher CTR = Just $ ctrCombine cipher nullIV+modeToBench cipher XTS = Just $ xtsEncrypt (cipher, cipher) nullIV 0+modeToBench cipher OCB = benchAEAD cipher AEAD_OCB+modeToBench cipher GCM = benchAEAD cipher AEAD_GCM+modeToBench cipher CCM = benchAEAD cipher AEAD_CCM+modeToBench cipher CWC = benchAEAD cipher AEAD_CWC+modeToBench cipher EAX = benchAEAD cipher AEAD_EAX++benchAEAD :: BlockCipher cipher => cipher -> AEADMode -> Maybe (B.ByteString -> B.ByteString)+benchAEAD cipher mode = (\aead -> (\b -> snd $ aeadSimpleEncrypt aead B.empty b (blockSize cipher))) `fmap` aeadInit mode cipher (B.replicate (blockSize cipher) 0)++modesToBench :: BlockCipher cipher => cipher -> [Mode] -> [(Mode, B.ByteString -> B.ByteString)]+modesToBench cipher = reverse . foldl (\acc mode -> case modeToBench cipher mode of+                                                      Just fb -> (mode, fb) : acc+                                                      Nothing -> acc) []++data Report = Report+    { reportSz     :: Int+    , reportMean   :: Double+    , reportSecs   :: String+    , reportSpeed  :: Double+    , reportSpeedS :: String+    } deriving (Show)++doOne :: Int -> Environment -> [Int] -> String -> (B.ByteString -> B.ByteString) -> Criterion (String, [Report])+doOne iters env szs name f = do+    means <- doCipher env iters szs f+    return (name, map toReport $ zip means szs)+  where toReport (mean, sz) = Report+            { reportSz     = sz+            , reportMean   = mean+            , reportSecs   = secs mean+            , reportSpeed  = norm sz mean+            , reportSpeedS = pn (norm sz mean)+            }++        norm :: Int -> Double -> Double+        norm n meanTime+            | n < 1024  = 1.0 / (meanTime * (1024 / fromIntegral n))+            | n == 1024 = 1.0 / meanTime+            | otherwise = 1.0 / (meanTime / (fromIntegral n / 1024))++        pn :: Double -> String+        pn val+            | val > (10 * 1024) = printf "%.1f M/s" (val / 1024)+            | otherwise         = printf "%.1f K/s" val+++runBench :: Int -> Bool -> [Int] -> [Mode] -> [GBlockCipher] -> Criterion ()+runBench iters showTime szs modes ciphers = do+    env     <- measureEnvironment+    reports <- concat <$> mapM (runBenchCipher env) ciphers+    let docHeader = col1 "cipher name" <+> hsep (map (textOf 12 . show) szs)+    let doc = vcat (docHeader : map toLine reports)+           +    liftIO $ putStrLn $ show doc+    +  where runBenchCipher env (GBlockCipher cipher) = do+            let name   = cipherName cipher+                benchs = modesToBench cipher modes+            mapM (\(benchMode, benchF) -> doOne iters env szs (name ++ "-" ++ show benchMode) benchF) benchs+        toLine (name, szReports) =+            hsep (col1 name : map field szReports)+        field | showTime  = textOf 12 . reportSecs+              | otherwise = textOf 12 . reportSpeedS+        textOf n s | len == n  = text s+                   | len < n   = text (s ++ replicate (n - len) ' ')+                   | otherwise = text (take n s)+          where len = length s+        col1 = textOf 14+        +data OptionArg = SizeArg String+               | CipherArg String+               | ModeArg String+               | Iter String+               | Time+               | Help+               deriving (Show,Eq)++wordsWhen :: (Char -> Bool) -> String -> [String]+wordsWhen p s =+    case dropWhile p s of+        "" -> []+        s' -> w : wordsWhen p s''+              where (w, s'') = break p s'++instanciateCiphers :: [GBlockCipher] -> [GBlockCipher]+instanciateCiphers ciphers = map proxy ciphers+  where proxy :: GBlockCipher -> GBlockCipher+        proxy (GBlockCipher c) = GBlockCipher $ instanciate c+        instanciate :: BlockCipher a => a -> a+        instanciate c =+            let bs = case cipherKeySize c of+                            Nothing -> B.replicate 1 0+                            Just sz -> B.replicate sz 1+             in cipherInit (fromJust $ makeKey bs)++-- | DefaultMain: parse command line arguments, run benchmarks+-- and report+defaultMain :: [GBlockCipher] -> IO ()+defaultMain ciphers = do+    args <- getArgs+    case getOpt Permute opts args of+        (os,_,[]) | Help `elem` os -> do putStrLn (usageInfo "crypto-cipher-benchmark" opts)+                                         exitFailure+                  | otherwise -> do let (ss, ms, iters) = foldl (\(sp, mp, it) o ->+                                            case o of+                                                SizeArg s -> (map read $ wordsWhen (== ',') s, mp, it)+                                                ModeArg s -> let modes = wordsWhen (== ',') $ map toUpper s+                                                                 nm    = filter (\m -> show m `elem` modes) mp+                                                              in (sp, nm, it)+                                                Iter s      -> (sp, mp, read s)+                                                CipherArg _ -> (sp, mp, it)+                                                _           -> (sp, mp, it)+            +                                            ) (defaultSzs, defaultModes, 100) os+                                    withConfig defaultConfig $ runBench iters (Time `elem` os) ss ms (instanciateCiphers ciphers)+        (_,_,err) -> error (show err)+  where opts =+            [ Option ['n'] ["iter"] (ReqArg Iter "iteration") "number of iterations per benchmarks"+            , Option [] ["size"] (ReqArg SizeArg "size") "size to run (csv)"+            , Option [] ["cipher"] (ReqArg CipherArg "cipher") "cipher to run (csv)"+            , Option [] ["mode"] (ReqArg ModeArg "mode") "mode to run (csv)"+            , Option ['t'] ["time"] (NoArg Time) "show average time instead of average speed"+            , Option ['h'] ["help"] (NoArg Help) "get help"+            ]
+ LICENSE view
@@ -0,0 +1,27 @@+Copyright (c) 2013 Vincent Hanquez <vincent@snarc.org>++All rights reserved.++Redistribution and use in source and binary forms, with or without+modification, are permitted provided that the following conditions+are met:+1. Redistributions of source code must retain the above copyright+   notice, this list of conditions and the following disclaimer.+2. Redistributions in binary form must reproduce the above copyright+   notice, this list of conditions and the following disclaimer in the+   documentation and/or other materials provided with the distribution.+3. Neither the name of the author nor the names of his contributors+   may be used to endorse or promote products derived from this software+   without specific prior written permission.++THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS AS IS'' AND+ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE+IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE+ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHORS OR CONTRIBUTORS BE LIABLE+FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL+DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS+OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)+HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT+LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY+OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF+SUCH DAMAGE.
+ Setup.hs view
@@ -0,0 +1,2 @@+import Distribution.Simple+main = defaultMain
+ crypto-cipher-benchmarks.cabal view
@@ -0,0 +1,31 @@+Name:                crypto-cipher-benchmarks+Version:             0.0.1+Synopsis:            Generic cryptography cipher benchmarks+Description:         Generic cryptography cipher benchmarks+License:             BSD3+License-file:        LICENSE+Copyright:           Vincent Hanquez <vincent@snarc.org>+Author:              Vincent Hanquez <vincent@snarc.org>+Maintainer:          vincent@snarc.org+Category:            Cryptography+Stability:           experimental+Build-Type:          Simple+Homepage:            http://github.com/vincenthz/hs-crypto-cipher+Cabal-Version:       >=1.8++Library+  Exposed-modules:   Crypto.Cipher.Benchmarks+  Build-depends:     base >= 4 && < 5+                   , bytestring+                   , byteable >= 0.1.1+                   , securemem >= 0.1.1+                   , criterion+                   , crypto-cipher-types+                   , mtl+                   , pretty+  ghc-options:       -Wall -fwarn-tabs++source-repository head+  type: git+  location: git://github.com/vincenthz/hs-crypto-cipher+  subdir: benchs