Merge pull request #204 from ocheron/ecdh-bench

FFDH and ECDH benchmarks
This commit is contained in:
Vincent Hanquez 2017-12-10 15:54:16 +00:00 committed by GitHub
commit 85575fae41
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
6 changed files with 74 additions and 18 deletions

View File

@ -49,7 +49,7 @@ data KeyPair curve = KeyPair
}
newtype SharedSecret = SharedSecret ScrubbedBytes
deriving (Eq, ByteArrayAccess)
deriving (Eq, ByteArrayAccess, NFData)
class EllipticCurve curve where
-- | Point on an Elliptic Curve

View File

@ -1,4 +1,5 @@
{-# LANGUAGE DeriveDataTypeable #-}
{-# LANGUAGE GeneralizedNewtypeDeriving #-}
-- |
-- Module : Crypto.ECC.Simple.Types
-- License : BSD-style
@ -98,7 +99,7 @@ data CurveType =
-- | ECC Private Number
newtype Scalar curve = Scalar Integer
deriving (Show,Read,Eq,Data,Typeable)
deriving (Show,Read,Eq,Data,Typeable,NFData)
-- | Define a point on a curve.
data Point curve =

View File

@ -35,17 +35,20 @@ data Params = Params
, params_bits :: Int
} deriving (Show,Read,Eq,Data,Typeable)
instance NFData Params where
rnf (Params p g bits) = rnf p `seq` rnf g `seq` bits `seq` ()
-- | Represent Diffie Hellman public number Y.
newtype PublicNumber = PublicNumber Integer
deriving (Show,Read,Eq,Enum,Real,Num,Ord)
deriving (Show,Read,Eq,Enum,Real,Num,Ord,NFData)
-- | Represent Diffie Hellman private number X.
newtype PrivateNumber = PrivateNumber Integer
deriving (Show,Read,Eq,Enum,Real,Num,Ord)
deriving (Show,Read,Eq,Enum,Real,Num,Ord,NFData)
-- | Represent Diffie Hellman shared secret.
newtype SharedKey = SharedKey ScrubbedBytes
deriving (Show,Eq,ByteArrayAccess)
deriving (Show,Eq,ByteArrayAccess,NFData)
-- | generate params from a specific generator (2 or 5 are common values)
-- we generate a safe prime (a prime number of the form 2p+1 where p is also prime)

View File

@ -58,11 +58,11 @@ import qualified Crypto.Number.Serialize as S (os2ip, i2ospOf)
-- | A P256 scalar
newtype Scalar = Scalar ScrubbedBytes
deriving (Show,Eq,ByteArrayAccess)
deriving (Show,Eq,ByteArrayAccess,NFData)
-- | A P256 point
newtype Point = Point Bytes
deriving (Show,Eq)
deriving (Show,Eq,NFData)
scalarSize :: Int
scalarSize = 32

View File

@ -1,6 +1,6 @@
{-# LANGUAGE PackageImports #-}
{-# LANGUAGE OverloadedStrings #-}
{-# LANGUAGE ExistentialQuantification #-}
{-# LANGUAGE FlexibleContexts #-}
module Main where
import Criterion.Main
@ -12,36 +12,37 @@ import qualified Crypto.Cipher.ChaChaPoly1305 as CP
import Crypto.Cipher.DES
import Crypto.Cipher.Twofish
import Crypto.Cipher.Types
import Crypto.ECC
import Crypto.Error
import Crypto.Hash
import qualified Crypto.KDF.PBKDF2 as PBKDF2
import Crypto.Number.Basic (numBits)
import Crypto.Number.Generate
import qualified Crypto.PubKey.DH as DH
import qualified Crypto.PubKey.ECC.Types as ECC
import qualified Crypto.PubKey.ECC.Prim as ECC
import Crypto.Random
import Control.DeepSeq (NFData)
import Data.ByteArray (ByteArray, Bytes)
import qualified Data.ByteString as B
import System.IO.Unsafe (unsafePerformIO)
import Number.F2m
data HashAlg = forall alg . HashAlgorithm alg => HashAlg alg
benchHash =
[ bgroup "1KB" $ map (doHashBench oneKB) hashAlgs
, bgroup "1MB" $ map (doHashBench oneMB) hashAlgs
[ env oneKB $ \b -> bgroup "1KB" $ map (doHashBench b) hashAlgs
, env oneMB $ \b -> bgroup "1MB" $ map (doHashBench b) hashAlgs
]
where
doHashBench b (name, HashAlg alg) = bench name $ nf (hashWith alg) b
oneKB :: Bytes
oneKB = unsafePerformIO (getRandomBytes 1024)
{-# NOINLINE oneKB #-}
oneKB :: IO Bytes
oneKB = getRandomBytes 1024
oneMB :: Bytes
oneMB = unsafePerformIO (getRandomBytes $ 1024 * 1024)
{-# NOINLINE oneMB #-}
oneMB :: IO Bytes
oneMB = getRandomBytes $ 1024 * 1024
hashAlgs =
[ ("MD2", HashAlg MD2)
@ -181,11 +182,61 @@ benchECC =
n1 = 0x2ba9daf2363b2819e69b34a39cf496c2458a9b2a21505ea9e7b7cbca42dc7435
n2 = 0xf054a7f60d10b8c2cf847ee90e9e029f8b0e971b09ca5f55c4d49921a11fadc1
benchFFDH = map doFFDHBench primes
where
doFFDHBench (e, p) =
let bits = numBits p
params = DH.Params { DH.params_p = p, DH.params_g = 2, DH.params_bits = bits }
in env (generate e params) $ bench (show bits) . nf (run params)
generate e params = do
aPriv <- DH.PrivateNumber `fmap` generatePriv e
bPriv <- DH.PrivateNumber `fmap` generatePriv e
return (aPriv, DH.calculatePublic params bPriv)
generatePriv e = generateParams e (Just SetHighest) False
run params (priv, pub) = DH.getShared params priv pub
-- RFC 7919: prime p with minimal size of exponent
primes = [ (225, 0xFFFFFFFFFFFFFFFFADF85458A2BB4A9AAFDC5620273D3CF1D8B9C583CE2D3695A9E13641146433FBCC939DCE249B3EF97D2FE363630C75D8F681B202AEC4617AD3DF1ED5D5FD65612433F51F5F066ED0856365553DED1AF3B557135E7F57C935984F0C70E0E68B77E2A689DAF3EFE8721DF158A136ADE73530ACCA4F483A797ABC0AB182B324FB61D108A94BB2C8E3FBB96ADAB760D7F4681D4F42A3DE394DF4AE56EDE76372BB190B07A7C8EE0A6D709E02FCE1CDF7E2ECC03404CD28342F619172FE9CE98583FF8E4F1232EEF28183C3FE3B1B4C6FAD733BB5FCBC2EC22005C58EF1837D1683B2C6F34A26C1B2EFFA886B423861285C97FFFFFFFFFFFFFFFF)
, (275, 0xFFFFFFFFFFFFFFFFADF85458A2BB4A9AAFDC5620273D3CF1D8B9C583CE2D3695A9E13641146433FBCC939DCE249B3EF97D2FE363630C75D8F681B202AEC4617AD3DF1ED5D5FD65612433F51F5F066ED0856365553DED1AF3B557135E7F57C935984F0C70E0E68B77E2A689DAF3EFE8721DF158A136ADE73530ACCA4F483A797ABC0AB182B324FB61D108A94BB2C8E3FBB96ADAB760D7F4681D4F42A3DE394DF4AE56EDE76372BB190B07A7C8EE0A6D709E02FCE1CDF7E2ECC03404CD28342F619172FE9CE98583FF8E4F1232EEF28183C3FE3B1B4C6FAD733BB5FCBC2EC22005C58EF1837D1683B2C6F34A26C1B2EFFA886B4238611FCFDCDE355B3B6519035BBC34F4DEF99C023861B46FC9D6E6C9077AD91D2691F7F7EE598CB0FAC186D91CAEFE130985139270B4130C93BC437944F4FD4452E2D74DD364F2E21E71F54BFF5CAE82AB9C9DF69EE86D2BC522363A0DABC521979B0DEADA1DBF9A42D5C4484E0ABCD06BFA53DDEF3C1B20EE3FD59D7C25E41D2B66C62E37FFFFFFFFFFFFFFFF)
, (325, 0xFFFFFFFFFFFFFFFFADF85458A2BB4A9AAFDC5620273D3CF1D8B9C583CE2D3695A9E13641146433FBCC939DCE249B3EF97D2FE363630C75D8F681B202AEC4617AD3DF1ED5D5FD65612433F51F5F066ED0856365553DED1AF3B557135E7F57C935984F0C70E0E68B77E2A689DAF3EFE8721DF158A136ADE73530ACCA4F483A797ABC0AB182B324FB61D108A94BB2C8E3FBB96ADAB760D7F4681D4F42A3DE394DF4AE56EDE76372BB190B07A7C8EE0A6D709E02FCE1CDF7E2ECC03404CD28342F619172FE9CE98583FF8E4F1232EEF28183C3FE3B1B4C6FAD733BB5FCBC2EC22005C58EF1837D1683B2C6F34A26C1B2EFFA886B4238611FCFDCDE355B3B6519035BBC34F4DEF99C023861B46FC9D6E6C9077AD91D2691F7F7EE598CB0FAC186D91CAEFE130985139270B4130C93BC437944F4FD4452E2D74DD364F2E21E71F54BFF5CAE82AB9C9DF69EE86D2BC522363A0DABC521979B0DEADA1DBF9A42D5C4484E0ABCD06BFA53DDEF3C1B20EE3FD59D7C25E41D2B669E1EF16E6F52C3164DF4FB7930E9E4E58857B6AC7D5F42D69F6D187763CF1D5503400487F55BA57E31CC7A7135C886EFB4318AED6A1E012D9E6832A907600A918130C46DC778F971AD0038092999A333CB8B7A1A1DB93D7140003C2A4ECEA9F98D0ACC0A8291CDCEC97DCF8EC9B55A7F88A46B4DB5A851F44182E1C68A007E5E655F6AFFFFFFFFFFFFFFFF)
, (375, 0xFFFFFFFFFFFFFFFFADF85458A2BB4A9AAFDC5620273D3CF1D8B9C583CE2D3695A9E13641146433FBCC939DCE249B3EF97D2FE363630C75D8F681B202AEC4617AD3DF1ED5D5FD65612433F51F5F066ED0856365553DED1AF3B557135E7F57C935984F0C70E0E68B77E2A689DAF3EFE8721DF158A136ADE73530ACCA4F483A797ABC0AB182B324FB61D108A94BB2C8E3FBB96ADAB760D7F4681D4F42A3DE394DF4AE56EDE76372BB190B07A7C8EE0A6D709E02FCE1CDF7E2ECC03404CD28342F619172FE9CE98583FF8E4F1232EEF28183C3FE3B1B4C6FAD733BB5FCBC2EC22005C58EF1837D1683B2C6F34A26C1B2EFFA886B4238611FCFDCDE355B3B6519035BBC34F4DEF99C023861B46FC9D6E6C9077AD91D2691F7F7EE598CB0FAC186D91CAEFE130985139270B4130C93BC437944F4FD4452E2D74DD364F2E21E71F54BFF5CAE82AB9C9DF69EE86D2BC522363A0DABC521979B0DEADA1DBF9A42D5C4484E0ABCD06BFA53DDEF3C1B20EE3FD59D7C25E41D2B669E1EF16E6F52C3164DF4FB7930E9E4E58857B6AC7D5F42D69F6D187763CF1D5503400487F55BA57E31CC7A7135C886EFB4318AED6A1E012D9E6832A907600A918130C46DC778F971AD0038092999A333CB8B7A1A1DB93D7140003C2A4ECEA9F98D0ACC0A8291CDCEC97DCF8EC9B55A7F88A46B4DB5A851F44182E1C68A007E5E0DD9020BFD64B645036C7A4E677D2C38532A3A23BA4442CAF53EA63BB454329B7624C8917BDD64B1C0FD4CB38E8C334C701C3ACDAD0657FCCFEC719B1F5C3E4E46041F388147FB4CFDB477A52471F7A9A96910B855322EDB6340D8A00EF092350511E30ABEC1FFF9E3A26E7FB29F8C183023C3587E38DA0077D9B4763E4E4B94B2BBC194C6651E77CAF992EEAAC0232A281BF6B3A739C1226116820AE8DB5847A67CBEF9C9091B462D538CD72B03746AE77F5E62292C311562A846505DC82DB854338AE49F5235C95B91178CCF2DD5CACEF403EC9D1810C6272B045B3B71F9DC6B80D63FDD4A8E9ADB1E6962A69526D43161C1A41D570D7938DAD4A40E329CD0E40E65FFFFFFFFFFFFFFFF)
, (400, 0xFFFFFFFFFFFFFFFFADF85458A2BB4A9AAFDC5620273D3CF1D8B9C583CE2D3695A9E13641146433FBCC939DCE249B3EF97D2FE363630C75D8F681B202AEC4617AD3DF1ED5D5FD65612433F51F5F066ED0856365553DED1AF3B557135E7F57C935984F0C70E0E68B77E2A689DAF3EFE8721DF158A136ADE73530ACCA4F483A797ABC0AB182B324FB61D108A94BB2C8E3FBB96ADAB760D7F4681D4F42A3DE394DF4AE56EDE76372BB190B07A7C8EE0A6D709E02FCE1CDF7E2ECC03404CD28342F619172FE9CE98583FF8E4F1232EEF28183C3FE3B1B4C6FAD733BB5FCBC2EC22005C58EF1837D1683B2C6F34A26C1B2EFFA886B4238611FCFDCDE355B3B6519035BBC34F4DEF99C023861B46FC9D6E6C9077AD91D2691F7F7EE598CB0FAC186D91CAEFE130985139270B4130C93BC437944F4FD4452E2D74DD364F2E21E71F54BFF5CAE82AB9C9DF69EE86D2BC522363A0DABC521979B0DEADA1DBF9A42D5C4484E0ABCD06BFA53DDEF3C1B20EE3FD59D7C25E41D2B669E1EF16E6F52C3164DF4FB7930E9E4E58857B6AC7D5F42D69F6D187763CF1D5503400487F55BA57E31CC7A7135C886EFB4318AED6A1E012D9E6832A907600A918130C46DC778F971AD0038092999A333CB8B7A1A1DB93D7140003C2A4ECEA9F98D0ACC0A8291CDCEC97DCF8EC9B55A7F88A46B4DB5A851F44182E1C68A007E5E0DD9020BFD64B645036C7A4E677D2C38532A3A23BA4442CAF53EA63BB454329B7624C8917BDD64B1C0FD4CB38E8C334C701C3ACDAD0657FCCFEC719B1F5C3E4E46041F388147FB4CFDB477A52471F7A9A96910B855322EDB6340D8A00EF092350511E30ABEC1FFF9E3A26E7FB29F8C183023C3587E38DA0077D9B4763E4E4B94B2BBC194C6651E77CAF992EEAAC0232A281BF6B3A739C1226116820AE8DB5847A67CBEF9C9091B462D538CD72B03746AE77F5E62292C311562A846505DC82DB854338AE49F5235C95B91178CCF2DD5CACEF403EC9D1810C6272B045B3B71F9DC6B80D63FDD4A8E9ADB1E6962A69526D43161C1A41D570D7938DAD4A40E329CCFF46AAA36AD004CF600C8381E425A31D951AE64FDB23FCEC9509D43687FEB69EDD1CC5E0B8CC3BDF64B10EF86B63142A3AB8829555B2F747C932665CB2C0F1CC01BD70229388839D2AF05E454504AC78B7582822846C0BA35C35F5C59160CC046FD8251541FC68C9C86B022BB7099876A460E7451A8A93109703FEE1C217E6C3826E52C51AA691E0E423CFC99E9E31650C1217B624816CDAD9A95F9D5B8019488D9C0A0A1FE3075A577E23183F81D4A3F2FA4571EFC8CE0BA8A4FE8B6855DFE72B0A66EDED2FBABFBE58A30FAFABE1C5D71A87E2F741EF8C1FE86FEA6BBFDE530677F0D97D11D49F7A8443D0822E506A9F4614E011E2A94838FF88CD68C8BB7C5C6424CFFFFFFFFFFFFFFFF)
]
data CurveDH = forall c . (EllipticCurveDH c, NFData (Scalar c), NFData (Point c)) => CurveDH c
benchECDH = map doECDHBench curves
where
doECDHBench (name, CurveDH c) =
let proxy = Just c -- using Maybe as Proxy
in env (generate proxy) $ bench name . nf (run proxy)
generate proxy = do
KeyPair _ aScalar <- curveGenerateKeyPair proxy
KeyPair bPoint _ <- curveGenerateKeyPair proxy
return (aScalar, bPoint)
run proxy (s, p) = throwCryptoError (ecdh proxy s p)
curves = [ ("P256R1", CurveDH Curve_P256R1)
, ("P384R1", CurveDH Curve_P384R1)
, ("P521R1", CurveDH Curve_P521R1)
, ("X25519", CurveDH Curve_X25519)
, ("X448", CurveDH Curve_X448)
]
main = defaultMain
[ bgroup "hash" benchHash
, bgroup "block-cipher" benchBlockCipher
, bgroup "AE" benchAE
, bgroup "pbkdf2" benchPBKDF2
, bgroup "ECC" benchECC
, bgroup "DH"
[ bgroup "FFDH" benchFFDH
, bgroup "ECDH" benchECDH
]
, bgroup "F2m" benchF2m
]

View File

@ -431,6 +431,7 @@ Benchmark bench-cryptonite
Other-modules: Number.F2m
Build-Depends: base >= 3 && < 5
, bytestring
, deepseq
, memory
, criterion
, random