Browse files

Hid nonessential modules. Changed namespace. Various cleanup. Changed…

… the way benchmarks are run.
  • Loading branch information...
1 parent 14bdb2e commit 3ad20dd729e2f118ce65a683e6a8ac305f652870 @rrnewton committed Aug 25, 2011
View
14 Codec/Crypto/ConvertRNG.hs
@@ -26,7 +26,7 @@
module Codec.Crypto.ConvertRNG
( BCtoCRG(..), convertCRG
, CRGtoRG()
- , CRGtoRG0(..) -- Inefficient version for testing...
+ , CRGtoRG_Unbuffered(..) -- Inefficient version for testing...
)
where
@@ -73,21 +73,21 @@ import Foreign.Storable
-- | Converting CryptoRandomGen to RandomGen.
-- This naive version is probably pretty inefficent:
-data CRGtoRG0 a = CRGtoRG0 a
-instance CryptoRandomGen g => RandomGen (CRGtoRG0 g) where
- next (CRGtoRG0 g) =
+data CRGtoRG_Unbuffered a = CRGtoRG_Unbuffered a
+instance CryptoRandomGen g => RandomGen (CRGtoRG_Unbuffered g) where
+ next (CRGtoRG_Unbuffered g) =
-- case genBytes (max bytes_in_int (keyLength g `quot` 8)) g of
case genBytes bytes_in_int g of
Left err -> error$ "CryptoRandomGen genBytes error: " ++ show err
Right (bytes,g') ->
case decode bytes of
Left err -> error$ "Deserialization error:"++ show err
- Right n -> (n, CRGtoRG0 g')
+ Right n -> (n, CRGtoRG_Unbuffered g')
- split (CRGtoRG0 g) =
+ split (CRGtoRG_Unbuffered g) =
case splitGen g of
Left err -> error$ "CryptoRandomGen splitGen error:"++ show err
- Right (g1,g2) -> (CRGtoRG0 g1, CRGtoRG0 g2)
+ Right (g1,g2) -> (CRGtoRG_Unbuffered g1, CRGtoRG_Unbuffered g2)
-- Another option would be to amortize overhead by generating a large
-- buffer of random bits at once.
View
129 Codec/Crypto/IntelAES.hs
@@ -1,129 +0,0 @@
-{-|
- Module : Codec.Crypto.IntelAES
- Copyright : (c) Ryan Newton 2011
- License : BSD-style (see the file LICENSE)
- Maintainer : rrnewton@gmail.com
- Stability : experimental
- Portability : linux only (NEEDS PORTING)
-
- This module provides an AES implementation that will test the CPU
- ID and use hardware acceleration where available, otherwise it will
- fall back to Dr. Brian Gladman's software implementation.
-
- This module also exports a random number generator based on AES
- both using the System.Random.RandomGen interface and the
- Codec.Crypto.Random.
-
- -}
-{-# OPTIONS_GHC -fwarn-unused-imports #-}
-{-# LANGUAGE ForeignFunctionInterface, CPP, ScopedTypeVariables #-}
-
-module Codec.Crypto.IntelAES
- (
- mkAESGen,
- CompoundAESRNG(),
- supportsAESNI,
- -- Plus, instances exported of course.
- testIntelAES
- )
-where
-
-import qualified Codec.Crypto.IntelAES.AESNI as NI
-import qualified Codec.Crypto.GladmanAES as GA
-import GHC.IO (unsafeDupablePerformIO)
-import Data.Tagged
-import Data.Word
-import Data.Serialize
-import qualified Data.ByteString as B
-import Crypto.Random (CryptoRandomGen(..), GenError(..), splitGen, genBytes)
-import Crypto.Types
-import Codec.Crypto.ConvertRNG
-import Debug.Trace
-
-newtype CompoundCRG =
- CompoundCRG
- (Either (BCtoCRG (NI.IntelAES NI.N128))
- (BCtoCRG (GA.AES GA.N128)))
-
--- | A type representing an AES-based random number generator which
--- will use AESNI instructions when available, and invoke the
--- portable Gladman implementation when not.
-type CompoundAESRNG = CRGtoRG CompoundCRG
-
--- | Simple function to create a random number generator from an Int,
--- analogous to `System.Random.newStdGen`. Only 128-bit encryption
--- is provided for now.
-mkAESGen :: Int -> CompoundAESRNG
-mkAESGen int = convertCRG gen
- where
- Right (gen :: CompoundCRG) = newGen (B.append halfseed halfseed )
- halfseed = encode word64
- word64 = fromIntegral int :: Word64
-
-
-
--- foreign import ccall unsafe "iaesni.h" check_for_aes_instructions :: IO Bool
-foreign import ccall unsafe "iaesni.h" check_for_aes_instructions :: Bool
-
--- | Does the machine support AESNI instructions?
-supportsAESNI :: Bool
-supportsAESNI = check_for_aes_instructions
-
-{-# INLINE mapRight #-}
-mapRight fn x@(Left _) = x
-mapRight fn (Right x) = Right$ fn x
-
-{-# INLINE mapSnd #-}
-mapSnd fn (x,y) = (x,fn y)
-
-
-instance CryptoRandomGen CompoundCRG where
-
--- newGen :: B.ByteString -> Either GenError CompoundCRG
- newGen =
--- if unsafeDupablePerformIO check_for_aes_instructions
--- trace ("Checked for AES instructions: "++ show check_for_aes_instructions)$
- if check_for_aes_instructions
- -- Ick, boilerplate:
- then \bytes -> case newGen bytes of Left err -> Left err
- Right gen -> Right$ CompoundCRG$ Left gen
- else \bytes -> case newGen bytes of Left err -> Left err
- Right gen -> Right$ CompoundCRG$ Right gen
-
- genSeedLength = Tagged 128
-
-
- -- ByteLength -> CompoundCRG -> Either GenError (B.ByteString, CompoundCRG)
- genBytes req (CompoundCRG (Left gen)) =
--- Let's try to reduce that boilerplate if we can...
-#if 0
- mapRight (mapSnd (CompoundCRG . Left) ) $ genBytes req gen
-#else
- case genBytes req gen of
- Left err -> Left err
- Right (bytes,gen') -> Right (bytes, CompoundCRG (Left gen'))
-#endif
-
--- <boilerplate> OUCH
- genBytes req (CompoundCRG (Right gen)) =
- case genBytes req gen of
- Left err -> Left err
- Right (bytes,gen') -> Right (bytes, CompoundCRG (Right gen'))
- reseed bs (CompoundCRG (Left gen)) =
- case reseed bs gen of
- Left err -> Left err
- Right gen' -> Right (CompoundCRG (Left gen'))
- reseed bs (CompoundCRG (Right gen)) =
- case reseed bs gen of
- Left err -> Left err
- Right gen' -> Right (CompoundCRG (Right gen'))
--- </boilerplate>
-
-
-
-testIntelAES = do
- putStrLn$ "Running crude tests."
--- b <- check_for_aes_instructions
- let b = check_for_aes_instructions
- putStrLn$ "Machine supports AESNI: "++ show b
-
View
8 Codec/Crypto/IntelAES/AESNI.hs
@@ -29,7 +29,7 @@ module Codec.Crypto.IntelAES.AESNI
, mkAESGen192, mkAESGen256
-- Inefficient version for testing:
- , mkAESGen0, SimpleAESRNG0
+ , mkAESGen0, SimpleAESRNG_Unbuffered
, IntelAES, N128, N192, N256
-- Plus, instances exported of course.
)
@@ -87,9 +87,9 @@ mkAESGen256 seed = convertCRG gen
-- | TEMP: Inefficient version for testing.
-type SimpleAESRNG0 = CRGtoRG0 (BCtoCRG (IntelAES N128))
-mkAESGen0 :: Int -> SimpleAESRNG0
-mkAESGen0 int = CRGtoRG0 gen
+type SimpleAESRNG_Unbuffered = CRGtoRG_Unbuffered (BCtoCRG (IntelAES N128))
+mkAESGen0 :: Int -> SimpleAESRNG_Unbuffered
+mkAESGen0 int = CRGtoRG_Unbuffered gen
where
Right (gen :: BCtoCRG (IntelAES N128)) = newGen (B.append halfseed halfseed )
halfseed = encode word64
View
3 Setup.hs
@@ -39,6 +39,7 @@ my_clean desc () hooks flags = do
setCurrentDirectory "./cbits/"
system "make clean"
setCurrentDirectory ".."
+ system "rm -f benchmark-intel-aes-rng"
putStrLn$ " [intel-aes] Done. Now running normal cabal clean action.\n"
(cleanHook simpleUserHooks) desc () hooks flags
@@ -88,7 +89,7 @@ patchDesc desc localinfo = do
-- Whew... nested record updates are painful:
desc3 = desc { library = Just (lib { libBuildInfo = newlbi})}
- putStrLn$ " [intel-aes] Modified package info. "
+ putStrLn$ " [intel-aes] Modified package description structure with extra options. "
return desc3
View
128 System/Random/AES.hs
@@ -0,0 +1,128 @@
+{-|
+ Module : System.Random.AES
+ Copyright : (c) Ryan Newton 2011
+ License : BSD-style (see the file LICENSE)
+ Maintainer : rrnewton@gmail.com
+ Stability : experimental
+ Portability : Mac OS, Linux, Untested on Windows
+
+ This module provides a random number generator based on AES both
+ using the System.Random.RandomGen interface and the
+ Codec.Crypto.Random one. The AES implementation that will test
+ the CPU ID and use hardware acceleration where available,
+ otherwise it will fall back to Dr. Brian Gladman's software
+ implementation.
+
+ -}
+{-# OPTIONS_GHC -fwarn-unused-imports #-}
+{-# LANGUAGE ForeignFunctionInterface, CPP, ScopedTypeVariables #-}
+
+module System.Random.AES
+ (
+ mkAESGen, mkAESGenCRG,
+ AesCRG(), AesRG(),
+ supportsAESNI,
+ -- Plus, instances exported of course.
+-- testIntelAES
+ )
+where
+
+import qualified Codec.Crypto.IntelAES.AESNI as NI
+import qualified Codec.Crypto.GladmanAES as GA
+-- import GHC.IO (unsafeDupablePerformIO)
+import Data.Tagged
+import Data.Word
+import Data.Serialize
+import qualified Data.ByteString as B
+-- import Crypto.Random (CryptoRandomGen(..), GenError(..), splitGen, genBytes)
+import Crypto.Random (CryptoRandomGen(..))
+-- import Crypto.Types
+import Codec.Crypto.ConvertRNG
+
+-- This type represents an RNG which may have one of two different
+-- representations, corresponding to the software or the hardware
+-- supported version.
+newtype AesCRG =
+ AesCRG
+ (Either (BCtoCRG (NI.IntelAES NI.N128))
+ (BCtoCRG (GA.AES GA.N128)))
+
+-- | A type representing an AES-based random number generator which
+-- will use AESNI instructions when available, and invoke the
+-- portable Gladman implementation when not.
+type AesRG = CRGtoRG AesCRG
+
+-- | Simple function to create a random number generator from an Int,
+-- exposing the `System.Random.RandomGen` interface, analogous to
+-- `System.Random.newStdGen`. Only 128-bit encryption is currently
+-- provided.
+mkAESGen :: Int -> AesRG
+mkAESGen int = convertCRG (mkAESGenCRG int)
+
+-- | This variant creates an random number generator which exposes the
+-- `Crypto.Random.CryptoRandomGen` interface.
+mkAESGenCRG :: Int -> AesCRG
+mkAESGenCRG int = gen
+ where
+ Right (gen :: AesCRG) = newGen (B.append halfseed halfseed )
+ halfseed = encode word64
+ word64 = fromIntegral int :: Word64
+
+
+
+foreign import ccall unsafe "iaesni.h" check_for_aes_instructions :: Bool
+
+-- | Does the machine support AESNI instructions?
+supportsAESNI :: Bool
+supportsAESNI = check_for_aes_instructions
+
+-- | This instance provides the CryptoRandomGen interface, which
+-- allows bulk generation of random bytes.
+instance CryptoRandomGen AesCRG where
+
+-- newGen :: B.ByteString -> Either GenError AesCRG
+ newGen =
+ if check_for_aes_instructions
+ -- Ick, boilerplate:
+ then \bytes -> case newGen bytes of Left err -> Left err
+ Right gen -> Right$ AesCRG$ Left gen
+ else \bytes -> case newGen bytes of Left err -> Left err
+ Right gen -> Right$ AesCRG$ Right gen
+
+ genSeedLength = Tagged 128
+
+ -- ByteLength -> AesCRG -> Either GenError (B.ByteString, AesCRG)
+ genBytes req (AesCRG (Left gen)) =
+
+#if 0
+ -- UNFINISHED: Let's try to reduce that boilerplate if we can...
+ mapRight (mapSnd (AesCRG . Left) ) $ genBytes req gen
+#else
+ case genBytes req gen of
+ Left err -> Left err
+ Right (bytes,gen') -> Right (bytes, AesCRG (Left gen'))
+#endif
+
+
+-- <boilerplate> OUCH
+ genBytes req (AesCRG (Right gen)) =
+ case genBytes req gen of
+ Left err -> Left err
+ Right (bytes,gen') -> Right (bytes, AesCRG (Right gen'))
+ reseed bs (AesCRG (Left gen)) =
+ case reseed bs gen of
+ Left err -> Left err
+ Right gen' -> Right (AesCRG (Left gen'))
+ reseed bs (AesCRG (Right gen)) =
+ case reseed bs gen of
+ Left err -> Left err
+ Right gen' -> Right (AesCRG (Right gen'))
+-- </boilerplate>
+
+-- UNFINISHED Refactoring:
+{-# INLINE mapRight #-}
+mapRight fn x@(Left _) = x
+mapRight fn (Right x) = Right$ fn x
+{-# INLINE mapSnd #-}
+mapSnd fn (x,y) = (x,fn y)
+
View
37 SimpleRNGBench.hs → System/Random/AES/Tests.hs
@@ -1,28 +1,26 @@
-#!/usr/bin/env runhaskell
{-# LANGUAGE BangPatterns, ScopedTypeVariables, ForeignFunctionInterface #-}
--- | A simple script to do some very basic timing of the RNGs.
--- It is important that we also run established stastical tests on
--- these RNGs a some point...
+{- | A simple script to do some very basic timing of the RNGs. This
+ module is here to be part of the same compilation unit as the
+ library itself (e.g. to access hidden modules).
-module Main where
+ TODO: It is important that we also run established stastical tests on
+ these RNGs a some point...
+ -}
-import qualified Codec.Encryption.BurtonRNGSlow as BS
+module System.Random.AES.Tests (runTests) where
---import qualified Codec.Crypto.IntelAES.GladmanAES as GA
+import qualified System.Random.AES as IA
+import qualified Codec.Encryption.BurtonRNGSlow as BS
import qualified Codec.Crypto.GladmanAES as GA
import qualified Codec.Crypto.IntelAES.AESNI as NI
-import qualified Codec.Crypto.IntelAES as IA
import qualified Codec.Crypto.ConvertRNG as CR
--- import qualified Codec.Crypto.AES.Random as Svein
import System.Exit (exitSuccess, exitFailure)
import System.Environment
import System.Random
--- import System.PosixCompat (sleep)
import System.Posix (sleep)
import System.CPUTime (getCPUTime)
--- import Data.Time.Clock (diffUTCTime)
import System.CPUTime.Rdtsc
import System.Console.GetOpt
@@ -60,8 +58,8 @@ mkAESGen_gladman int = CR.convertCRG gen
word64 = fromIntegral int :: Word64
-mkAESGen_gladman0 :: Int -> CR.CRGtoRG0 (CR.BCtoCRG (GA.AES GA.N128))
-mkAESGen_gladman0 int = CR.CRGtoRG0 gen
+mkAESGen_gladman_unbuffered :: Int -> CR.CRGtoRG_Unbuffered (CR.BCtoCRG (GA.AES GA.N128))
+mkAESGen_gladman_unbuffered int = CR.CRGtoRG_Unbuffered gen
where
Right (gen :: CR.BCtoCRG (GA.AES GA.N128)) = newGen (B.append halfseed halfseed )
halfseed = encode word64
@@ -298,13 +296,12 @@ options =
, Option ['t'] ["test"] (NoArg Test) "run some basic tests"
]
-
-main = do
+runTests = do
argv <- getArgs
let (opts,_,other) = getOpt Permute options argv
+ putStrLn$ "Does machine supports AESNI?: " ++ show IA.supportsAESNI
when (Test `elem` opts)$ do
- IA.testIntelAES
NI.testAESNI
exitSuccess
@@ -334,15 +331,15 @@ main = do
timeit th freq "System.Random stdGen" mkStdGen
timeit th freq "PureHaskell/reference" BS.mkBurtonGen_reference
timeit th freq "PureHaskell" BS.mkBurtonGen
--- timeit th freq "Gladman inefficient" GA.mkAESGen0
+-- timeit th freq "Gladman unbuffered" GA.mkAESGen0
-- timeit th freq "Gladman" GA.mkAESGen
- timeit th freq "Gladman inefficient" mkAESGen_gladman0
- timeit th freq "Gladman" mkAESGen_gladman
+ timeit th freq "Gladman unbuffered" mkAESGen_gladman_unbuffered
+ timeit th freq "Gladman" mkAESGen_gladman
timeit th freq "Compound gladman/intel" IA.mkAESGen
-- timeit th freq "Svein's Gladman package" (const svein)
if IA.supportsAESNI then do
- timeit th freq "IntelAES inefficient" NI.mkAESGen0
+ timeit th freq "IntelAES unbuffered" NI.mkAESGen0
timeit th freq "IntelAES" NI.mkAESGen
else
putStrLn$ " [Skipping AESNI-only tests, current machine does not support these instructions.]"
View
8 benchmark-intel-aes-rng.hs
@@ -0,0 +1,8 @@
+#!/usr/bin/env runhaskell -i
+
+-- Note the -i to prevent GHC from searching ./ as part of the library search path.
+
+module Main where
+import System.Random.AES.Tests (runTests)
+
+main = runTests
View
29 intel-aes.cabal
@@ -89,19 +89,22 @@ source-repository head
library
build-depends: base >= 4 && < 5, random, DRBG, split, process, haskell98, time,
crypto-api >= 0.5,
- bytestring, cereal, tagged, largeword
+ bytestring, cereal, tagged, largeword,
+ -- For AES.Tests only:
+ rdtsc, unix
- exposed-modules: Codec.Encryption.BurtonRNGSlow
- , Codec.Crypto.IntelAES
- , Codec.Crypto.IntelAES.AESNI
+ exposed-modules:
+ System.Random.AES
, Codec.Crypto.ConvertRNG
--- , Codec.Crypto.IntelAES.GladmanAES
- , Codec.Crypto.GladmanAES
+ , System.Random.AES.Tests
other-modules:
Benchmark.BinSearch
, Codec.Encryption.AES
, Codec.Encryption.AESAux
, Codec.Utils
+ , Codec.Encryption.BurtonRNGSlow
+ , Codec.Crypto.IntelAES.AESNI
+ , Codec.Crypto.GladmanAES
GHC-Options: -O2
extra-libraries: intel_aes
@@ -110,20 +113,6 @@ library
cbits/gladman/aes_modes.c, cbits/gladman/ctr_inc.c
Include-Dirs: cbits
-
-- ----------------------------------------------------------------------------------------------------
-Executable benchmark-intel-aes-rng
- Main-is: SimpleRNGBench.hs
- Build-Depends: base >= 4 && < 5, split, rdtsc, random, DRBG
- , crypto-api >= 0.5
--- , unix-compat
- , unix
- , tagged, cereal, bytestring, process, haskell98, time, largeword
- , intel-aes
- GHC-Options: -O2 -threaded -rtsopts
- C-sources: cbits/c_test.c
- Include-dirs: cbits
-
-
-- cabal haddock --hoogle --executables --hyperlink-source --haddock-options="--html"

0 comments on commit 3ad20dd

Please sign in to comment.