1{-# LANGUAGE OverloadedStrings #-} 2{-# LANGUAGE ExistentialQuantification #-} 3{-# LANGUAGE FlexibleContexts #-} 4module Main where 5 6import Gauge.Main 7 8import Crypto.Cipher.AES 9import qualified Crypto.Cipher.AESGCMSIV as AESGCMSIV 10import Crypto.Cipher.Blowfish 11import Crypto.Cipher.CAST5 12import qualified Crypto.Cipher.ChaChaPoly1305 as CP 13import Crypto.Cipher.DES 14import Crypto.Cipher.Twofish 15import Crypto.Cipher.Types 16import Crypto.ECC 17import Crypto.Error 18import Crypto.Hash 19import qualified Crypto.KDF.BCrypt as BCrypt 20import qualified Crypto.KDF.PBKDF2 as PBKDF2 21import Crypto.Number.Basic (numBits) 22import Crypto.Number.Generate 23import qualified Crypto.PubKey.DH as DH 24import qualified Crypto.PubKey.ECC.Types as ECC 25import qualified Crypto.PubKey.ECC.Prim as ECC 26import qualified Crypto.PubKey.ECDSA as ECDSA 27import Crypto.Random 28 29import Control.DeepSeq (NFData) 30import Data.ByteArray (ByteArray, Bytes) 31import qualified Data.ByteString as B 32 33import qualified Crypto.PubKey.ECC.P256 as P256 34 35import Number.F2m 36 37data HashAlg = forall alg . HashAlgorithm alg => HashAlg alg 38 39benchHash = 40 [ env oneKB $ \b -> bgroup "1KB" $ map (doHashBench b) hashAlgs 41 , env oneMB $ \b -> bgroup "1MB" $ map (doHashBench b) hashAlgs 42 ] 43 where 44 doHashBench b (name, HashAlg alg) = bench name $ nf (hashWith alg) b 45 46 oneKB :: IO Bytes 47 oneKB = getRandomBytes 1024 48 49 oneMB :: IO Bytes 50 oneMB = getRandomBytes $ 1024 * 1024 51 52 hashAlgs = 53 [ ("MD2", HashAlg MD2) 54 , ("MD4", HashAlg MD4) 55 , ("MD5", HashAlg MD5) 56 , ("SHA1", HashAlg SHA1) 57 , ("SHA224", HashAlg SHA224) 58 , ("SHA256", HashAlg SHA256) 59 , ("SHA384", HashAlg SHA384) 60 , ("SHA512", HashAlg SHA512) 61 , ("SHA512t_224", HashAlg SHA512t_224) 62 , ("SHA512t_256", HashAlg SHA512t_256) 63 , ("RIPEMD160", HashAlg RIPEMD160) 64 , ("Tiger", HashAlg Tiger) 65 --, ("Skein256-160", HashAlg Skein256_160) 66 , ("Skein256-256", HashAlg Skein256_256) 67 --, ("Skein512-160", HashAlg Skein512_160) 68 , ("Skein512-384", HashAlg Skein512_384) 69 , ("Skein512-512", HashAlg Skein512_512) 70 --, ("Skein512-896", HashAlg Skein512_896) 71 , ("Whirlpool", HashAlg Whirlpool) 72 , ("Keccak-224", HashAlg Keccak_224) 73 , ("Keccak-256", HashAlg Keccak_256) 74 , ("Keccak-384", HashAlg Keccak_384) 75 , ("Keccak-512", HashAlg Keccak_512) 76 , ("SHA3-224", HashAlg SHA3_224) 77 , ("SHA3-256", HashAlg SHA3_256) 78 , ("SHA3-384", HashAlg SHA3_384) 79 , ("SHA3-512", HashAlg SHA3_512) 80 , ("Blake2b-160", HashAlg Blake2b_160) 81 , ("Blake2b-224", HashAlg Blake2b_224) 82 , ("Blake2b-256", HashAlg Blake2b_256) 83 , ("Blake2b-384", HashAlg Blake2b_384) 84 , ("Blake2b-512", HashAlg Blake2b_512) 85 , ("Blake2s-160", HashAlg Blake2s_160) 86 , ("Blake2s-224", HashAlg Blake2s_224) 87 , ("Blake2s-256", HashAlg Blake2s_256) 88 ] 89 90benchPBKDF2 = 91 [ bgroup "64" 92 [ bench "cryptonite-PBKDF2-100-64" $ nf (pbkdf2 64) 100 93 , bench "cryptonite-PBKDF2-1000-64" $ nf (pbkdf2 64) 1000 94 , bench "cryptonite-PBKDF2-10000-64" $ nf (pbkdf2 64) 10000 95 ] 96 , bgroup "128" 97 [ bench "cryptonite-PBKDF2-100-128" $ nf (pbkdf2 128) 100 98 , bench "cryptonite-PBKDF2-1000-128" $ nf (pbkdf2 128) 1000 99 , bench "cryptonite-PBKDF2-10000-128" $ nf (pbkdf2 128) 10000 100 ] 101 ] 102 where 103 pbkdf2 :: Int -> Int -> B.ByteString 104 pbkdf2 n iter = PBKDF2.generate (PBKDF2.prfHMAC SHA512) (params n iter) mypass mysalt 105 106 mypass, mysalt :: B.ByteString 107 mypass = "password" 108 mysalt = "salt" 109 110 params n iter = PBKDF2.Parameters iter n 111 112benchBCrypt = 113 [ bench "cryptonite-BCrypt-4" $ nf bcrypt 4 114 , bench "cryptonite-BCrypt-5" $ nf bcrypt 5 115 , bench "cryptonite-BCrypt-7" $ nf bcrypt 7 116 , bench "cryptonite-BCrypt-11" $ nf bcrypt 11 117 ] 118 where 119 bcrypt :: Int -> B.ByteString 120 bcrypt cost = BCrypt.bcrypt cost mysalt mypass 121 122 mypass, mysalt :: B.ByteString 123 mypass = "password" 124 mysalt = "saltsaltsaltsalt" 125 126benchBlockCipher = 127 [ bgroup "ECB" benchECB 128 , bgroup "CBC" benchCBC 129 ] 130 where 131 benchECB = 132 [ bench "DES-input=1024" $ nf (run (undefined :: DES) cipherInit key8) input1024 133 , bench "Blowfish128-input=1024" $ nf (run (undefined :: Blowfish128) cipherInit key16) input1024 134 , bench "Twofish128-input=1024" $ nf (run (undefined :: Twofish128) cipherInit key16) input1024 135 , bench "CAST5-128-input=1024" $ nf (run (undefined :: CAST5) cipherInit key16) input1024 136 , bench "AES128-input=1024" $ nf (run (undefined :: AES128) cipherInit key16) input1024 137 , bench "AES256-input=1024" $ nf (run (undefined :: AES256) cipherInit key32) input1024 138 ] 139 where run :: (ByteArray ba, ByteArray key, BlockCipher c) 140 => c -> (key -> CryptoFailable c) -> key -> ba -> ba 141 run _witness initF key input = 142 (ecbEncrypt (throwCryptoError (initF key))) input 143 144 benchCBC = 145 [ bench "DES-input=1024" $ nf (run (undefined :: DES) cipherInit key8 iv8) input1024 146 , bench "Blowfish128-input=1024" $ nf (run (undefined :: Blowfish128) cipherInit key16 iv8) input1024 147 , bench "Twofish128-input=1024" $ nf (run (undefined :: Twofish128) cipherInit key16 iv16) input1024 148 , bench "CAST5-128-input=1024" $ nf (run (undefined :: CAST5) cipherInit key16 iv8) input1024 149 , bench "AES128-input=1024" $ nf (run (undefined :: AES128) cipherInit key16 iv16) input1024 150 , bench "AES256-input=1024" $ nf (run (undefined :: AES256) cipherInit key32 iv16) input1024 151 ] 152 where run :: (ByteArray ba, ByteArray key, BlockCipher c) 153 => c -> (key -> CryptoFailable c) -> key -> IV c -> ba -> ba 154 run _witness initF key iv input = 155 (cbcEncrypt (throwCryptoError (initF key))) iv input 156 157 key8 = B.replicate 8 0 158 key16 = B.replicate 16 0 159 key32 = B.replicate 32 0 160 input1024 = B.replicate 1024 0 161 162 iv8 :: BlockCipher c => IV c 163 iv8 = maybe (error "iv size 8") id $ makeIV key8 164 165 iv16 :: BlockCipher c => IV c 166 iv16 = maybe (error "iv size 16") id $ makeIV key16 167 168benchAE = 169 [ bench "ChaChaPoly1305" $ nf (cp key32) (input64, input1024) 170 , bench "AES-GCM" $ nf (gcm key32) (input64, input1024) 171 , bench "AES-CCM" $ nf (ccm key32) (input64, input1024) 172 , bench "AES-GCM-SIV" $ nf (gcmsiv key32) (input64, input1024) 173 ] 174 where cp k (ini, plain) = 175 let iniState = throwCryptoError $ CP.initialize k (throwCryptoError $ CP.nonce12 nonce12) 176 afterAAD = CP.finalizeAAD (CP.appendAAD ini iniState) 177 (out, afterEncrypt) = CP.encrypt plain afterAAD 178 outtag = CP.finalize afterEncrypt 179 in (outtag, out) 180 181 gcm k (ini, plain) = 182 let ctx = throwCryptoError (cipherInit k) :: AES256 183 state = throwCryptoError $ aeadInit AEAD_GCM ctx nonce12 184 in aeadSimpleEncrypt state ini plain 16 185 186 ccm k (ini, plain) = 187 let ctx = throwCryptoError (cipherInit k) :: AES256 188 mode = AEAD_CCM 1024 CCM_M16 CCM_L3 189 state = throwCryptoError $ aeadInit mode ctx nonce12 190 in aeadSimpleEncrypt state ini plain 16 191 192 gcmsiv k (ini, plain) = 193 let ctx = throwCryptoError (cipherInit k) :: AES256 194 iv = throwCryptoError (AESGCMSIV.nonce nonce12) 195 in AESGCMSIV.encrypt ctx iv ini plain 196 197 input64 = B.replicate 64 0 198 input1024 = B.replicate 1024 0 199 200 nonce12 :: B.ByteString 201 nonce12 = B.replicate 12 0 202 203 key32 = B.replicate 32 0 204 205benchECC = 206 [ bench "pointAddTwoMuls-baseline" $ nf run_b (n1, p1, n2, p2) 207 , bench "pointAddTwoMuls-optimized" $ nf run_o (n1, p1, n2, p2) 208 , bench "pointAdd-ECC" $ nf run_c (p1, p2) 209 , bench "pointMul-ECC" $ nf run_d (n1, p2) 210 ] 211 where run_b (n, p, k, q) = ECC.pointAdd c (ECC.pointMul c n p) 212 (ECC.pointMul c k q) 213 214 run_o (n, p, k, q) = ECC.pointAddTwoMuls c n p k q 215 run_c (p, q) = ECC.pointAdd c p q 216 run_d (n, p) = ECC.pointMul c n p 217 218 c = ECC.getCurveByName ECC.SEC_p256r1 219 p1 = ECC.pointBaseMul c n1 220 p2 = ECC.pointBaseMul c n2 221 n1 = 0x2ba9daf2363b2819e69b34a39cf496c2458a9b2a21505ea9e7b7cbca42dc7435 222 n2 = 0xf054a7f60d10b8c2cf847ee90e9e029f8b0e971b09ca5f55c4d49921a11fadc1 223 224benchP256 = 225 [ bench "pointAddTwoMuls-P256" $ nf run_p (n1, p1, n2, p2) 226 , bench "pointAdd-P256" $ nf run_q (p1, p2) 227 , bench "pointMul-P256" $ nf run_t (n1, p1) 228 ] 229 where run_p (n, p, k, q) = P256.pointAdd (P256.pointMul n p) (P256.pointMul k q) 230 run_q (p, q) = P256.pointAdd p q 231 run_t (n, p) = P256.pointMul n p 232 233 xS = 0xde2444bebc8d36e682edd27e0f271508617519b3221a8fa0b77cab3989da97c9 234 yS = 0xc093ae7ff36e5380fc01a5aad1e66659702de80f53cec576b6350b243042a256 235 xT = 0x55a8b00f8da1d44e62f6b3b25316212e39540dc861c89575bb8cf92e35e0986b 236 yT = 0x5421c3209c2d6c704835d82ac4c3dd90f61a8a52598b9e7ab656e9d8c8b24316 237 p1 = P256.pointFromIntegers (xS, yS) 238 p2 = P256.pointFromIntegers (xT, yT) 239 n1 = throwCryptoError $ P256.scalarFromInteger 0x2ba9daf2363b2819e69b34a39cf496c2458a9b2a21505ea9e7b7cbca42dc7435 240 n2 = throwCryptoError $ P256.scalarFromInteger 0xf054a7f60d10b8c2cf847ee90e9e029f8b0e971b09ca5f55c4d49921a11fadc1 241 242 243 244benchFFDH = map doFFDHBench primes 245 where 246 doFFDHBench (e, p) = 247 let bits = numBits p 248 params = DH.Params { DH.params_p = p, DH.params_g = 2, DH.params_bits = bits } 249 in env (generate e params) $ bench (show bits) . nf (run params) 250 251 generate e params = do 252 aPriv <- DH.PrivateNumber `fmap` generatePriv e 253 bPriv <- DH.PrivateNumber `fmap` generatePriv e 254 return (aPriv, DH.calculatePublic params bPriv) 255 256 generatePriv e = generateParams e (Just SetHighest) False 257 258 run params (priv, pub) = DH.getShared params priv pub 259 260 -- RFC 7919: prime p with minimal size of exponent 261 primes = [ (225, 0xFFFFFFFFFFFFFFFFADF85458A2BB4A9AAFDC5620273D3CF1D8B9C583CE2D3695A9E13641146433FBCC939DCE249B3EF97D2FE363630C75D8F681B202AEC4617AD3DF1ED5D5FD65612433F51F5F066ED0856365553DED1AF3B557135E7F57C935984F0C70E0E68B77E2A689DAF3EFE8721DF158A136ADE73530ACCA4F483A797ABC0AB182B324FB61D108A94BB2C8E3FBB96ADAB760D7F4681D4F42A3DE394DF4AE56EDE76372BB190B07A7C8EE0A6D709E02FCE1CDF7E2ECC03404CD28342F619172FE9CE98583FF8E4F1232EEF28183C3FE3B1B4C6FAD733BB5FCBC2EC22005C58EF1837D1683B2C6F34A26C1B2EFFA886B423861285C97FFFFFFFFFFFFFFFF) 262 , (275, 0xFFFFFFFFFFFFFFFFADF85458A2BB4A9AAFDC5620273D3CF1D8B9C583CE2D3695A9E13641146433FBCC939DCE249B3EF97D2FE363630C75D8F681B202AEC4617AD3DF1ED5D5FD65612433F51F5F066ED0856365553DED1AF3B557135E7F57C935984F0C70E0E68B77E2A689DAF3EFE8721DF158A136ADE73530ACCA4F483A797ABC0AB182B324FB61D108A94BB2C8E3FBB96ADAB760D7F4681D4F42A3DE394DF4AE56EDE76372BB190B07A7C8EE0A6D709E02FCE1CDF7E2ECC03404CD28342F619172FE9CE98583FF8E4F1232EEF28183C3FE3B1B4C6FAD733BB5FCBC2EC22005C58EF1837D1683B2C6F34A26C1B2EFFA886B4238611FCFDCDE355B3B6519035BBC34F4DEF99C023861B46FC9D6E6C9077AD91D2691F7F7EE598CB0FAC186D91CAEFE130985139270B4130C93BC437944F4FD4452E2D74DD364F2E21E71F54BFF5CAE82AB9C9DF69EE86D2BC522363A0DABC521979B0DEADA1DBF9A42D5C4484E0ABCD06BFA53DDEF3C1B20EE3FD59D7C25E41D2B66C62E37FFFFFFFFFFFFFFFF) 263 , (325, 0xFFFFFFFFFFFFFFFFADF85458A2BB4A9AAFDC5620273D3CF1D8B9C583CE2D3695A9E13641146433FBCC939DCE249B3EF97D2FE363630C75D8F681B202AEC4617AD3DF1ED5D5FD65612433F51F5F066ED0856365553DED1AF3B557135E7F57C935984F0C70E0E68B77E2A689DAF3EFE8721DF158A136ADE73530ACCA4F483A797ABC0AB182B324FB61D108A94BB2C8E3FBB96ADAB760D7F4681D4F42A3DE394DF4AE56EDE76372BB190B07A7C8EE0A6D709E02FCE1CDF7E2ECC03404CD28342F619172FE9CE98583FF8E4F1232EEF28183C3FE3B1B4C6FAD733BB5FCBC2EC22005C58EF1837D1683B2C6F34A26C1B2EFFA886B4238611FCFDCDE355B3B6519035BBC34F4DEF99C023861B46FC9D6E6C9077AD91D2691F7F7EE598CB0FAC186D91CAEFE130985139270B4130C93BC437944F4FD4452E2D74DD364F2E21E71F54BFF5CAE82AB9C9DF69EE86D2BC522363A0DABC521979B0DEADA1DBF9A42D5C4484E0ABCD06BFA53DDEF3C1B20EE3FD59D7C25E41D2B669E1EF16E6F52C3164DF4FB7930E9E4E58857B6AC7D5F42D69F6D187763CF1D5503400487F55BA57E31CC7A7135C886EFB4318AED6A1E012D9E6832A907600A918130C46DC778F971AD0038092999A333CB8B7A1A1DB93D7140003C2A4ECEA9F98D0ACC0A8291CDCEC97DCF8EC9B55A7F88A46B4DB5A851F44182E1C68A007E5E655F6AFFFFFFFFFFFFFFFF) 264 , (375, 0xFFFFFFFFFFFFFFFFADF85458A2BB4A9AAFDC5620273D3CF1D8B9C583CE2D3695A9E13641146433FBCC939DCE249B3EF97D2FE363630C75D8F681B202AEC4617AD3DF1ED5D5FD65612433F51F5F066ED0856365553DED1AF3B557135E7F57C935984F0C70E0E68B77E2A689DAF3EFE8721DF158A136ADE73530ACCA4F483A797ABC0AB182B324FB61D108A94BB2C8E3FBB96ADAB760D7F4681D4F42A3DE394DF4AE56EDE76372BB190B07A7C8EE0A6D709E02FCE1CDF7E2ECC03404CD28342F619172FE9CE98583FF8E4F1232EEF28183C3FE3B1B4C6FAD733BB5FCBC2EC22005C58EF1837D1683B2C6F34A26C1B2EFFA886B4238611FCFDCDE355B3B6519035BBC34F4DEF99C023861B46FC9D6E6C9077AD91D2691F7F7EE598CB0FAC186D91CAEFE130985139270B4130C93BC437944F4FD4452E2D74DD364F2E21E71F54BFF5CAE82AB9C9DF69EE86D2BC522363A0DABC521979B0DEADA1DBF9A42D5C4484E0ABCD06BFA53DDEF3C1B20EE3FD59D7C25E41D2B669E1EF16E6F52C3164DF4FB7930E9E4E58857B6AC7D5F42D69F6D187763CF1D5503400487F55BA57E31CC7A7135C886EFB4318AED6A1E012D9E6832A907600A918130C46DC778F971AD0038092999A333CB8B7A1A1DB93D7140003C2A4ECEA9F98D0ACC0A8291CDCEC97DCF8EC9B55A7F88A46B4DB5A851F44182E1C68A007E5E0DD9020BFD64B645036C7A4E677D2C38532A3A23BA4442CAF53EA63BB454329B7624C8917BDD64B1C0FD4CB38E8C334C701C3ACDAD0657FCCFEC719B1F5C3E4E46041F388147FB4CFDB477A52471F7A9A96910B855322EDB6340D8A00EF092350511E30ABEC1FFF9E3A26E7FB29F8C183023C3587E38DA0077D9B4763E4E4B94B2BBC194C6651E77CAF992EEAAC0232A281BF6B3A739C1226116820AE8DB5847A67CBEF9C9091B462D538CD72B03746AE77F5E62292C311562A846505DC82DB854338AE49F5235C95B91178CCF2DD5CACEF403EC9D1810C6272B045B3B71F9DC6B80D63FDD4A8E9ADB1E6962A69526D43161C1A41D570D7938DAD4A40E329CD0E40E65FFFFFFFFFFFFFFFF) 265 , (400, 0xFFFFFFFFFFFFFFFFADF85458A2BB4A9AAFDC5620273D3CF1D8B9C583CE2D3695A9E13641146433FBCC939DCE249B3EF97D2FE363630C75D8F681B202AEC4617AD3DF1ED5D5FD65612433F51F5F066ED0856365553DED1AF3B557135E7F57C935984F0C70E0E68B77E2A689DAF3EFE8721DF158A136ADE73530ACCA4F483A797ABC0AB182B324FB61D108A94BB2C8E3FBB96ADAB760D7F4681D4F42A3DE394DF4AE56EDE76372BB190B07A7C8EE0A6D709E02FCE1CDF7E2ECC03404CD28342F619172FE9CE98583FF8E4F1232EEF28183C3FE3B1B4C6FAD733BB5FCBC2EC22005C58EF1837D1683B2C6F34A26C1B2EFFA886B4238611FCFDCDE355B3B6519035BBC34F4DEF99C023861B46FC9D6E6C9077AD91D2691F7F7EE598CB0FAC186D91CAEFE130985139270B4130C93BC437944F4FD4452E2D74DD364F2E21E71F54BFF5CAE82AB9C9DF69EE86D2BC522363A0DABC521979B0DEADA1DBF9A42D5C4484E0ABCD06BFA53DDEF3C1B20EE3FD59D7C25E41D2B669E1EF16E6F52C3164DF4FB7930E9E4E58857B6AC7D5F42D69F6D187763CF1D5503400487F55BA57E31CC7A7135C886EFB4318AED6A1E012D9E6832A907600A918130C46DC778F971AD0038092999A333CB8B7A1A1DB93D7140003C2A4ECEA9F98D0ACC0A8291CDCEC97DCF8EC9B55A7F88A46B4DB5A851F44182E1C68A007E5E0DD9020BFD64B645036C7A4E677D2C38532A3A23BA4442CAF53EA63BB454329B7624C8917BDD64B1C0FD4CB38E8C334C701C3ACDAD0657FCCFEC719B1F5C3E4E46041F388147FB4CFDB477A52471F7A9A96910B855322EDB6340D8A00EF092350511E30ABEC1FFF9E3A26E7FB29F8C183023C3587E38DA0077D9B4763E4E4B94B2BBC194C6651E77CAF992EEAAC0232A281BF6B3A739C1226116820AE8DB5847A67CBEF9C9091B462D538CD72B03746AE77F5E62292C311562A846505DC82DB854338AE49F5235C95B91178CCF2DD5CACEF403EC9D1810C6272B045B3B71F9DC6B80D63FDD4A8E9ADB1E6962A69526D43161C1A41D570D7938DAD4A40E329CCFF46AAA36AD004CF600C8381E425A31D951AE64FDB23FCEC9509D43687FEB69EDD1CC5E0B8CC3BDF64B10EF86B63142A3AB8829555B2F747C932665CB2C0F1CC01BD70229388839D2AF05E454504AC78B7582822846C0BA35C35F5C59160CC046FD8251541FC68C9C86B022BB7099876A460E7451A8A93109703FEE1C217E6C3826E52C51AA691E0E423CFC99E9E31650C1217B624816CDAD9A95F9D5B8019488D9C0A0A1FE3075A577E23183F81D4A3F2FA4571EFC8CE0BA8A4FE8B6855DFE72B0A66EDED2FBABFBE58A30FAFABE1C5D71A87E2F741EF8C1FE86FEA6BBFDE530677F0D97D11D49F7A8443D0822E506A9F4614E011E2A94838FF88CD68C8BB7C5C6424CFFFFFFFFFFFFFFFF) 266 ] 267 268data CurveDH = forall c . (EllipticCurveDH c, NFData (Scalar c), NFData (Point c)) => CurveDH c 269 270benchECDH = map doECDHBench curves 271 where 272 doECDHBench (name, CurveDH c) = 273 let proxy = Just c -- using Maybe as Proxy 274 in env (generate proxy) $ bench name . nf (run proxy) 275 276 generate proxy = do 277 KeyPair _ aScalar <- curveGenerateKeyPair proxy 278 KeyPair bPoint _ <- curveGenerateKeyPair proxy 279 return (aScalar, bPoint) 280 281 run proxy (s, p) = throwCryptoError (ecdh proxy s p) 282 283 curves = [ ("P256R1", CurveDH Curve_P256R1) 284 , ("P384R1", CurveDH Curve_P384R1) 285 , ("P521R1", CurveDH Curve_P521R1) 286 , ("X25519", CurveDH Curve_X25519) 287 , ("X448", CurveDH Curve_X448) 288 ] 289 290data CurveHashECDSA = 291 forall curve hashAlg . (ECDSA.EllipticCurveECDSA curve, 292 NFData (Scalar curve), 293 NFData (Point curve), 294 HashAlgorithm hashAlg) => CurveHashECDSA curve hashAlg 295 296benchECDSA = map doECDSABench curveHashes 297 where 298 doECDSABench (name, CurveHashECDSA c hashAlg) = 299 let proxy = Just c -- using Maybe as Proxy 300 in bgroup name 301 [ env (signGenerate proxy) $ bench "sign" . nfIO . signRun proxy hashAlg 302 , env (verifyGenerate proxy hashAlg) $ bench "verify" . nf (verifyRun proxy hashAlg) 303 ] 304 305 signGenerate proxy = do 306 m <- tenKB 307 s <- curveGenerateScalar proxy 308 return (s, m) 309 310 signRun proxy hashAlg (priv, msg) = ECDSA.sign proxy priv hashAlg msg 311 312 verifyGenerate proxy hashAlg = do 313 m <- tenKB 314 KeyPair p s <- curveGenerateKeyPair proxy 315 sig <- ECDSA.sign proxy s hashAlg m 316 return (p, sig, m) 317 318 verifyRun proxy hashAlg (pub, sig, msg) = ECDSA.verify proxy hashAlg pub sig msg 319 320 tenKB :: IO Bytes 321 tenKB = getRandomBytes 10240 322 323 curveHashes = [ ("secp256r1_sha256", CurveHashECDSA Curve_P256R1 SHA256) 324 , ("secp384r1_sha384", CurveHashECDSA Curve_P384R1 SHA384) 325 , ("secp521r1_sha512", CurveHashECDSA Curve_P521R1 SHA512) 326 ] 327 328main = defaultMain 329 [ bgroup "hash" benchHash 330 , bgroup "block-cipher" benchBlockCipher 331 , bgroup "AE" benchAE 332 , bgroup "pbkdf2" benchPBKDF2 333 , bgroup "bcrypt" benchBCrypt 334 , bgroup "ECC" benchECC 335 , bgroup "P256" benchP256 336 , bgroup "DH" 337 [ bgroup "FFDH" benchFFDH 338 , bgroup "ECDH" benchECDH 339 ] 340 , bgroup "ECDSA" benchECDSA 341 , bgroup "F2m" benchF2m 342 ] 343