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 newtype SharedSecret = SharedSecret ScrubbedBytes
deriving (Eq, ByteArrayAccess) deriving (Eq, ByteArrayAccess, NFData)
class EllipticCurve curve where class EllipticCurve curve where
-- | Point on an Elliptic Curve -- | Point on an Elliptic Curve

View File

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

View File

@ -35,17 +35,20 @@ data Params = Params
, params_bits :: Int , params_bits :: Int
} deriving (Show,Read,Eq,Data,Typeable) } 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. -- | Represent Diffie Hellman public number Y.
newtype PublicNumber = PublicNumber Integer 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. -- | Represent Diffie Hellman private number X.
newtype PrivateNumber = PrivateNumber Integer 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. -- | Represent Diffie Hellman shared secret.
newtype SharedKey = SharedKey ScrubbedBytes 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) -- | 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) -- 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 -- | A P256 scalar
newtype Scalar = Scalar ScrubbedBytes newtype Scalar = Scalar ScrubbedBytes
deriving (Show,Eq,ByteArrayAccess) deriving (Show,Eq,ByteArrayAccess,NFData)
-- | A P256 point -- | A P256 point
newtype Point = Point Bytes newtype Point = Point Bytes
deriving (Show,Eq) deriving (Show,Eq,NFData)
scalarSize :: Int scalarSize :: Int
scalarSize = 32 scalarSize = 32

View File

@ -1,6 +1,6 @@
{-# LANGUAGE PackageImports #-}
{-# LANGUAGE OverloadedStrings #-} {-# LANGUAGE OverloadedStrings #-}
{-# LANGUAGE ExistentialQuantification #-} {-# LANGUAGE ExistentialQuantification #-}
{-# LANGUAGE FlexibleContexts #-}
module Main where module Main where
import Criterion.Main import Criterion.Main
@ -12,36 +12,37 @@ import qualified Crypto.Cipher.ChaChaPoly1305 as CP
import Crypto.Cipher.DES import Crypto.Cipher.DES
import Crypto.Cipher.Twofish import Crypto.Cipher.Twofish
import Crypto.Cipher.Types import Crypto.Cipher.Types
import Crypto.ECC
import Crypto.Error import Crypto.Error
import Crypto.Hash import Crypto.Hash
import qualified Crypto.KDF.PBKDF2 as PBKDF2 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.Types as ECC
import qualified Crypto.PubKey.ECC.Prim as ECC import qualified Crypto.PubKey.ECC.Prim as ECC
import Crypto.Random import Crypto.Random
import Control.DeepSeq (NFData)
import Data.ByteArray (ByteArray, Bytes) import Data.ByteArray (ByteArray, Bytes)
import qualified Data.ByteString as B import qualified Data.ByteString as B
import System.IO.Unsafe (unsafePerformIO)
import Number.F2m import Number.F2m
data HashAlg = forall alg . HashAlgorithm alg => HashAlg alg data HashAlg = forall alg . HashAlgorithm alg => HashAlg alg
benchHash = benchHash =
[ bgroup "1KB" $ map (doHashBench oneKB) hashAlgs [ env oneKB $ \b -> bgroup "1KB" $ map (doHashBench b) hashAlgs
, bgroup "1MB" $ map (doHashBench oneMB) hashAlgs , env oneMB $ \b -> bgroup "1MB" $ map (doHashBench b) hashAlgs
] ]
where where
doHashBench b (name, HashAlg alg) = bench name $ nf (hashWith alg) b doHashBench b (name, HashAlg alg) = bench name $ nf (hashWith alg) b
oneKB :: Bytes oneKB :: IO Bytes
oneKB = unsafePerformIO (getRandomBytes 1024) oneKB = getRandomBytes 1024
{-# NOINLINE oneKB #-}
oneMB :: Bytes oneMB :: IO Bytes
oneMB = unsafePerformIO (getRandomBytes $ 1024 * 1024) oneMB = getRandomBytes $ 1024 * 1024
{-# NOINLINE oneMB #-}
hashAlgs = hashAlgs =
[ ("MD2", HashAlg MD2) [ ("MD2", HashAlg MD2)
@ -181,11 +182,61 @@ benchECC =
n1 = 0x2ba9daf2363b2819e69b34a39cf496c2458a9b2a21505ea9e7b7cbca42dc7435 n1 = 0x2ba9daf2363b2819e69b34a39cf496c2458a9b2a21505ea9e7b7cbca42dc7435
n2 = 0xf054a7f60d10b8c2cf847ee90e9e029f8b0e971b09ca5f55c4d49921a11fadc1 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 main = defaultMain
[ bgroup "hash" benchHash [ bgroup "hash" benchHash
, bgroup "block-cipher" benchBlockCipher , bgroup "block-cipher" benchBlockCipher
, bgroup "AE" benchAE , bgroup "AE" benchAE
, bgroup "pbkdf2" benchPBKDF2 , bgroup "pbkdf2" benchPBKDF2
, bgroup "ECC" benchECC , bgroup "ECC" benchECC
, bgroup "DH"
[ bgroup "FFDH" benchFFDH
, bgroup "ECDH" benchECDH
]
, bgroup "F2m" benchF2m , bgroup "F2m" benchF2m
] ]

View File

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