intel-aes 0.1.2.3 → 0.2.0.0
raw patch · 14 files changed
+619/−591 lines, 14 filesdep −intel-aessetup-changed
Dependencies removed: intel-aes
Files
- Codec/Crypto/ConvertRNG.hs +13/−12
- Codec/Crypto/GladmanAES.hsc +2/−1
- Codec/Crypto/IntelAES.hs +0/−129
- Codec/Crypto/IntelAES/AESNI.hs +4/−4
- Setup.hs +14/−10
- SimpleRNGBench.hs +0/−367
- System/Random/AES.hs +134/−0
- System/Random/AES/Tests.hs +365/−0
- benchmark-intel-aes-rng.hs +8/−0
- cbits/Intel_AESNI_Sample_Library_v1.0/intel_aes_lib/Makefile +25/−10
- cbits/Intel_AESNI_Sample_Library_v1.0/intel_aes_lib/where_files_come_from_and_lice +34/−0
- cbits/Intel_AESNI_Sample_Library_v1.0/intel_aes_lib/where_files_come_from_and_license.txt +0/−34
- cbits/Makefile +1/−1
- intel-aes.cabal +19/−23
Codec/Crypto/ConvertRNG.hs view
@@ -15,7 +15,7 @@ @ Specifically, a block cipher can be converted to generate a- @CryptoRandomGen@, which in turn can be converted to provide the+ 'CryptoRandomGen', which in turn can be converted to provide the @RandomGen@ interface. -}@@ -26,7 +26,7 @@ module Codec.Crypto.ConvertRNG ( BCtoCRG(..), convertCRG , CRGtoRG()- , CRGtoRG0(..) -- Inefficient version for testing...+ , CRGtoRG_Unbuffered(..) -- Inefficient version for testing... ) where @@ -72,22 +72,22 @@ -- | 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) = +-- This naive version is inefficent and should not be used in most cases.+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.@@ -98,8 +98,9 @@ -- steps = 128 `quot` bits_in_int --------------------------------------------------------------- | Converting CryptoRandomGen to RandomGen.--- Keep a buffer of random bits and an index into that buffer.+-- | Convert CryptoRandomGen to RandomGen. This version is buffered.+-- That is, it fills a sizable buffer with random bits in bulk and+-- advances an index into that buffer as random bits are requested. data CRGtoRG a = CRGtoRG a {-#UNPACK#-}! (FP.ForeignPtr Int) {-#UNPACK#-}! Int@@ -139,8 +140,8 @@ -- Again there's the tension with UndecidableInstances vs explicit lifting. -- | A BlockCipher can generate random numbers.--- When lifting we include a counter which increments as random numbers are generated: data BCtoCRG a = BCtoCRG a Word64+-- When lifting we include a counter which increments as random numbers are generated. instance BlockCipher x => CryptoRandomGen (BCtoCRG x) where newGen bytes = case buildKey bytes of Nothing -> Left NotEnoughEntropy
Codec/Crypto/GladmanAES.hsc view
@@ -18,7 +18,8 @@ import Crypto.Classes import Crypto.Types import Data.Tagged-import Data.Serialize+-- use import list for Serialize to avoid conflict with `ensure` function+import Data.Serialize(Serialize, Get, get, put, getByteString, putByteString) import Foreign import Control.Applicative
− 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-
Codec/Crypto/IntelAES/AESNI.hs view
@@ -29,7 +29,7 @@ , mkAESGen192, mkAESGen256 -- Inefficient version for testing:- , mkAESGen0, SimpleAESRNG0+ , mkAESGen0, SimpleAESRNG_Unbuffered , IntelAES, N128, N192, N256 -- Plus, instances exported of course. )@@ -87,9 +87,9 @@ -- | 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
Setup.hs view
@@ -39,6 +39,7 @@ 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 @@ -79,8 +80,8 @@ -- I'm not sure what the best policy is. For now I'm adding -- BOTH the build dir and the eventual install dir... -- This will allow the package to function when it is built-but-not-installed.- newO = ("-Wl,-rpath=" ++ libd) : - ("-Wl,-rpath=" ++ cbitsd) : + newO = ("-Wl,-rpath," ++ libd) :+ ("-Wl,-rpath," ++ cbitsd) : oldO cbitsd = root++"/cbits/" newlbi = lbi { ldOptions = newO @@ -88,7 +89,7 @@ -- 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 @@ -109,11 +110,7 @@ my_preBuild args flags = do putStrLn$ "\n================================================================================" let - ext = case Info.os of - "linux" -> ".so"- "mac" -> ".dylib"- "windows" -> ".dll"- _ -> error$ "Unexpected "+ ext = libext cached_so = "./cbits/prebuilt/libintel_aes_"++ Info.os ++"_"++ Info.arch ++ ext dest = "./cbits/libintel_aes"++ext e <- doesFileExist cached_so@@ -147,11 +144,18 @@ putStrLn$ "\n================================================================================" desc2 <- patchDesc desc linfo libd <- readFile tmpfile - let dest = (libd ++ "/libintel_aes.so")+ let dest = (libd ++ "/libintel_aes" ++ libext) putStrLn$ " [intel-aes] Copying shared library to: " ++ show dest system$ "mkdir -p "++ libd -- NONPORTABLE- copyFile "./cbits/libintel_aes.so" dest+ copyFile ("./cbits/libintel_aes"++libext) dest putStrLn$ " [intel-aes] Done copying." -- removeFile tmpfile -- Might install more than once, right? putStrLn$ "================================================================================\n" (instHook simpleUserHooks) desc2 linfo hooks flags++libext :: String+libext = case Info.os of+ "linux" -> ".so"+ "darwin" -> ".dylib"+ "windows" -> ".dll"+ _ -> error$ "Unexpected OS: " ++ (Info.os)
− SimpleRNGBench.hs
@@ -1,367 +0,0 @@-#!/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...--module Main where--import qualified Codec.Encryption.BurtonRNGSlow as BS----import qualified Codec.Crypto.IntelAES.GladmanAES as GA-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--import GHC.Conc-import Control.Concurrent-import Control.Monad -import Control.Concurrent.Chan-import Control.Exception--import Crypto.Random (CryptoRandomGen(..))--import Data.IORef-import Data.List-import Data.Int-import Data.Word-import Data.List.Split-import Data.Serialize-import qualified Data.ByteString as B-import Text.Printf--import Foreign.Ptr-import Foreign.ForeignPtr-import Foreign.Storable (peek,poke)--import Benchmark.BinSearch--------------------------------------------------------------------------------------------------------- TEMP: MOVE ME ELSEWHERE:--mkAESGen_gladman :: Int -> CR.CRGtoRG (CR.BCtoCRG (GA.AES GA.N128))-mkAESGen_gladman int = CR.convertCRG gen- where- Right (gen :: CR.BCtoCRG (GA.AES GA.N128)) = newGen (B.append halfseed halfseed )- halfseed = encode word64- word64 = fromIntegral int :: Word64---mkAESGen_gladman0 :: Int -> CR.CRGtoRG0 (CR.BCtoCRG (GA.AES GA.N128))-mkAESGen_gladman0 int = CR.CRGtoRG0 gen- where- Right (gen :: CR.BCtoCRG (GA.AES GA.N128)) = newGen (B.append halfseed halfseed )- halfseed = encode word64- word64 = fromIntegral int :: Word64---------------------------------------------------------------------------------------------------------- Miscellaneous helpers:---- I cannot *believe* there is not a standard call or an--- easily-findable hackage library supporting locale-based printing of--- numbers. [2011.01.28]-commaint :: Integral a => a -> String-commaint n = - reverse $- concat $- intersperse "," $ - chunk 3 $ - reverse (show n)--padleft n str | length str >= n = str-padleft n str | otherwise = take (n - length str) (repeat ' ') ++ str--padright n str | length str >= n = str-padright n str | otherwise = str ++ take (n - length str) (repeat ' ')--fmt_num n = if n < 100 - then printf "%.2f" n- else commaint (round n)---- WARNING! This is not actually good enough. Even if we use forkOS--- we would have to go further and pin the OS thread (e.g. in linux)--- to keep the OS from waking up the process on a different core.-measure_freq :: IO Int64-measure_freq = do - -- We measure the clock frequency on a bound thread.- -- Otherwise we can get really screwy results from rdtsc if we- -- migrate physical threads when we sleep or threadDelay.- tmpchan <- newChan- forkOS $ do - t1 <- rdtsc- -- sleep 1- threadDelay (1000*1000)- t2 <- rdtsc- -- Just to be careful let's make sure this doesn't happen (this was how I found the problem before forkOS):- when (t2 < t1) $ - putStrLn$ "WARNING: rdtsc not monotonically increasing, first "++show t1++" then "++show t2++" on the same OS thread"- writeChan tmpchan (if t2>t1 then t2-t1 else t1-t2)- freq <- readChan tmpchan- return (fromIntegral freq)---- This version simply busy-waits to stay on the same core:--- WOW! I'm STILL experiencing the non-monotonic rdtsc, even when not compiled with -threaded.--- It can't be overflow can it? The counter should be 64 bit...------ UPDATE: [2011.01.28] This was a bug in the rdtsc package that dropping the precision to 32 bits.-measure_freq2 :: IO Int64-measure_freq2 = do - let second = 1000 * 1000 * 1000 * 1000 -- picoseconds are annoying- t1 <- rdtsc - start <- getCPUTime- let loop !n !last = - do t2 <- rdtsc - when (t2 < last) $- putStrLn$ "COUNTERS WRAPPED "++ show (last,t2) - cput <- getCPUTime - if (cput - start < second) - then loop (n+1) t2- else return (n,t2)- (n,t2) <- loop 0 t1- putStrLn$ " Approx getCPUTime calls per second: "++ commaint n- when (t2 < t1) $ - putStrLn$ "WARNING: rdtsc not monotonically increasing, first "++show t1++" then "++show t2++" on the same OS thread"-- return$ fromIntegral (t2 - t1)--------------------------------------------------------------------------------------------------------- Drivers to get random numbers repeatedly.--incr !counter = - do -- modifyIORef counter (+1)d- -- Incrementing counter strictly (avoiding stack overflow) is annoying:- c <- readIORef counter- let c' = c+1- evaluate c'- writeIORef counter c' --loop :: RandomGen g => IORef Int -> (Int,g) -> IO b-loop !counter !(!n,!g) = - do incr counter--- putStr (show n); putChar ' '- loop counter (next g)--data NoopRNG = NoopRNG-instance RandomGen NoopRNG where - split g = (g,g)- next g = (0,g)----foreign import ccall "cbits/c_test.c" blast_rands :: Ptr Int -> Ptr Int -> IO ()--type Kern = Int -> Ptr Int -> IO ()---- [2011.01.28] Changing this to take "count" and "accumulator ptr" as arguments:-foreign import ccall "cbits/c_test.c" blast_rands :: Kern-foreign import ccall "cbits/c_test.c" store_loop :: Kern-foreign import ccall unsafe "stdlib.hs" rand :: IO Int--loop2 :: IORef Int -> IO ()-loop2 !counter = - do incr counter- n <- rand- loop2 counter ---------------------------------------------------------------------------------------------------------- Timing:--timeit numthreads freq msg mkgen =- do - counters <- forM [1..numthreads] (const$ newIORef 1) - tids <- forM counters $ \counter -> - forkIO $ loop counter (next$ mkgen 23852358661234) - threadDelay (1000*1000) -- One second- mapM_ killThread tids-- finals <- mapM readIORef counters- let mean :: Double = fromIntegral (foldl1 (+) finals) / fromIntegral numthreads- cycles_per :: Double = fromIntegral freq / mean- print_result (round mean) msg cycles_per--print_result total msg cycles_per = - putStrLn$ " "++ padleft 11 (commaint total) ++" random ints generated "++ padright 27 ("["++msg++"]") ++" ~ "- ++ fmt_num cycles_per ++" cycles/int"----- FIXME: This isn't working yet because when the C call goes into a tight infinite loop killThread hangs...--- KEEPING AROUND ONLY FOR FUTURE INVESTIGATION--------------------------------------------------------------time_c :: Int -> Int64 -> (Ptr Int -> Ptr Int -> IO ()) -> IO Int-time_c numthreads freq ffn = do - counter :: ForeignPtr Int <- mallocForeignPtr- sum :: ForeignPtr Int <- mallocForeignPtr- tid <- forkOS $ - withForeignPtr counter $ \ cntr ->- withForeignPtr sum $ \ sm ->- ffn cntr sm- threadDelay (1000*1000) -- One second- stat <- threadStatus tid- putStrLn$ "Thread making foreign call's status: "++ show stat- putStrLn$ "Killing thread running the foreign C call...\n"- killThread tid -- This will hang!!!- putStrLn$ "Killed.\n"- total <- withForeignPtr counter peek - putStrLn$ "Got total: " ++ show total- return total------------------------------------------------------------------ This version flips things around, and assume something about the--- timing so that we can run a fixed number of randoms and time it.--- (We could do binary search here.)-time_c2 :: Int -> Int64 -> String -> (Int -> Ptr Int -> IO ()) -> IO Int-time_c2 numthreads freq msg ffn = do - ptr :: ForeignPtr Int <- mallocForeignPtr-- let kern = if numthreads == 1- then ffn- else replicate_kernel numthreads ffn - wrapped n = withForeignPtr ptr (kern$ fromIntegral n)- (n,t) <- binSearch False 1 (1.0, 1.05) wrapped-- -- ONLY if we're in multi-threaded mode do we then run again with- -- that input size on all threads:-------------------------------------------- NOTE, this approach is TOO SLOW. For workloads that take a massive--- parallel slowdown it doesn't make sense to use the same input size--- in serial and in parallel.--- DISABLING:-{-- (n2,t2) <- - if numthreads > 1 then do- ptrs <- mapM (const mallocForeignPtr) [1..numthreads]- tmpchan <- newChan- putStrLn$ " [forking threads for multithreaded measurement, input size "++ show n++"]"- start <- getCPUTime- tids <- forM ptrs $ \ptr -> forkIO $ - do withForeignPtr ptr (ffn$ fromIntegral n)- writeChan tmpchan () - forM ptrs $ \_ -> readChan tmpchan- end <- getCPUTime- let t2 :: Double = fromIntegral (end-start) / 1000000000000.0- putStrLn$ " [joined threads, time "++ show t2 ++"]"- return (n * fromIntegral numthreads, t2)- else do - return (n,t)--}------------------------------------------- let total_per_second = round $ fromIntegral n * (1 / t)- cycles_per = fromIntegral freq * t / fromIntegral n- print_result total_per_second msg cycles_per- return total_per_second---- This lifts the C kernel to operate -replicate_kernel :: Int -> Kern -> Kern-replicate_kernel numthreads kern n ptr = do- ptrs <- forM [1..numthreads]- (const mallocForeignPtr) - tmpchan <- newChan- -- let childwork = ceiling$ fromIntegral n / fromIntegral numthreads- let childwork = n -- Keep it the same.. interested in per-thread throughput.- -- Fork/join pattern:- tids <- forM ptrs $ \ptr -> forkIO $ - withForeignPtr ptr $ \p -> do- kern (fromIntegral childwork) p- result <- peek p- writeChan tmpchan result-- results <- forM [1..numthreads] $ \_ -> - readChan tmpchan- -- Meaningless semantics here... sum the child ptrs and write to the input one:- poke ptr (foldl1 (+) results)- return ()--------------------------------------------------------------------------------------------------------- Main Script--data Flag = NoC | Help | Test- deriving (Show, Eq)--options = - [ Option ['h'] ["help"] (NoArg Help) "print program help"- , Option [] ["noC"] (NoArg NoC) "omit C benchmarks, haskell only"- , Option ['t'] ["test"] (NoArg Test) "run some basic tests"- ]-- -main = do - argv <- getArgs- let (opts,_,other) = getOpt Permute options argv-- when (Test `elem` opts)$ do- IA.testIntelAES- NI.testAESNI- exitSuccess-- when (not$ null other) $ do- putStrLn$ "ERROR: Unrecognized options: " - mapM_ putStr other- exitFailure-- when (Help `elem` opts) $ do- putStr$ usageInfo "Benchmark random number generation" options- exitSuccess-- putStrLn$ "\nHow many random numbers can we generate in a second on one thread?"-- t1 <- rdtsc- t2 <- rdtsc- putStrLn (" Cost of rdtsc (ffi call): " ++ show (t2 - t1))-- freq <- measure_freq2- putStrLn$ " Approx clock frequency: " ++ commaint freq---- svein <- Svein.newAESGen-- let gamut th = do- putStrLn$ " First, timing with System.Random interface:"- timeit th freq "constant zero gen" (const NoopRNG)- 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" GA.mkAESGen- timeit th freq "Gladman inefficient" mkAESGen_gladman0- 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" NI.mkAESGen- else - putStrLn$ " [Skipping AESNI-only tests, current machine does not support these instructions.]"-- when (not$ NoC `elem` opts) $ do- putStrLn$ " Comparison to C's rand():"- time_c2 th freq "ptr store in C loop" store_loop- time_c2 th freq "rand/store in C loop" blast_rands- time_c2 th freq "rand in Haskell loop" (\n ptr -> forM_ [1..n]$ \_ -> rand )- time_c2 th freq "rand/store in Haskell loop" (\n ptr -> forM_ [1..n]$ \_ -> do n <- rand; poke ptr n )- return ()- -- timeit 1 freq "rand / Haskell loop" mkBurtonGen-- gamut 1-- when (numCapabilities > 1) $ do --- when (False) $ do - putStrLn$ "\nNow "++ show numCapabilities ++" threads, reporting mean randoms-per-second-per-thread:"- gamut numCapabilities- return ()-- putStrLn$ "Finished."
+ System/Random/AES.hs view
@@ -0,0 +1,134 @@+{-|+ 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 cryptographic-strength random number+ generators based on AES.++ The generators are exposed both using the+ 'System.Random.RandomGen' interface and the+ 'Codec.Crypto.CryptoRandomGen' one.++ Internally, this module uses two different AES implementations.+ If the CPU ID indicates that AESNI instructions are available, it+ will use an Intel-provided hardware-accelerated implementation,+ otherwise, it will fall back to Dr. Brian Gladman's well-known+ 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)+
+ System/Random/AES/Tests.hs view
@@ -0,0 +1,365 @@+{-# LANGUAGE BangPatterns, ScopedTypeVariables, ForeignFunctionInterface #-}++{- | A simple script to do some very basic timing of 'System.Random.RandomGen's. ++ This module is located here to be part of the same compilation unit+ as the library itself (e.g. to access hidden modules).++ TODO: It is important that we also run established stastical tests on+ these RNGs a some point...+ -}++module System.Random.AES.Tests (runTests) where++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.ConvertRNG as CR++import System.Exit (exitSuccess, exitFailure)+import System.Environment+import System.Random+import System.Posix (sleep)+import System.CPUTime (getCPUTime)+import System.CPUTime.Rdtsc+import System.Console.GetOpt++import GHC.Conc+import Control.Concurrent+import Control.Monad +import Control.Concurrent.Chan+import Control.Exception++import Crypto.Random (CryptoRandomGen(..))++import Data.IORef+import Data.List+import Data.Int+import Data.Word+import Data.List.Split+import Data.Serialize+import qualified Data.ByteString as B+import Text.Printf++import Foreign.Ptr+import Foreign.ForeignPtr+import Foreign.Storable (peek,poke)++import Benchmark.BinSearch++----------------------------------------------------------------------------------------------------+-- TEMP: MOVE ME ELSEWHERE:++mkAESGen_gladman :: Int -> CR.CRGtoRG (CR.BCtoCRG (GA.AES GA.N128))+mkAESGen_gladman int = CR.convertCRG gen+ where+ Right (gen :: CR.BCtoCRG (GA.AES GA.N128)) = newGen (B.append halfseed halfseed )+ halfseed = encode word64+ word64 = fromIntegral int :: Word64+++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+ word64 = fromIntegral int :: Word64+++----------------------------------------------------------------------------------------------------+-- Miscellaneous helpers:++-- I cannot *believe* there is not a standard call or an+-- easily-findable hackage library supporting locale-based printing of+-- numbers. [2011.01.28]+commaint :: Integral a => a -> String+commaint n = + reverse $+ concat $+ intersperse "," $ + chunk 3 $ + reverse (show n)++padleft n str | length str >= n = str+padleft n str | otherwise = take (n - length str) (repeat ' ') ++ str++padright n str | length str >= n = str+padright n str | otherwise = str ++ take (n - length str) (repeat ' ')++fmt_num n = if n < 100 + then printf "%.2f" n+ else commaint (round n)++-- WARNING! This is not actually good enough. Even if we use forkOS+-- we would have to go further and pin the OS thread (e.g. in linux)+-- to keep the OS from waking up the process on a different core.+measure_freq :: IO Int64+measure_freq = do + -- We measure the clock frequency on a bound thread.+ -- Otherwise we can get really screwy results from rdtsc if we+ -- migrate physical threads when we sleep or threadDelay.+ tmpchan <- newChan+ forkOS $ do + t1 <- rdtsc+ -- sleep 1+ threadDelay (1000*1000)+ t2 <- rdtsc+ -- Just to be careful let's make sure this doesn't happen (this was how I found the problem before forkOS):+ when (t2 < t1) $ + putStrLn$ "WARNING: rdtsc not monotonically increasing, first "++show t1++" then "++show t2++" on the same OS thread"+ writeChan tmpchan (if t2>t1 then t2-t1 else t1-t2)+ freq <- readChan tmpchan+ return (fromIntegral freq)++-- This version simply busy-waits to stay on the same core:+-- WOW! I'm STILL experiencing the non-monotonic rdtsc, even when not compiled with -threaded.+-- It can't be overflow can it? The counter should be 64 bit...+--+-- UPDATE: [2011.01.28] This was a bug in the rdtsc package that dropping the precision to 32 bits.+measure_freq2 :: IO Int64+measure_freq2 = do + let second = 1000 * 1000 * 1000 * 1000 -- picoseconds are annoying+ t1 <- rdtsc + start <- getCPUTime+ let loop !n !last = + do t2 <- rdtsc + when (t2 < last) $+ putStrLn$ "COUNTERS WRAPPED "++ show (last,t2) + cput <- getCPUTime + if (cput - start < second) + then loop (n+1) t2+ else return (n,t2)+ (n,t2) <- loop 0 t1+ putStrLn$ " Approx getCPUTime calls per second: "++ commaint n+ when (t2 < t1) $ + putStrLn$ "WARNING: rdtsc not monotonically increasing, first "++show t1++" then "++show t2++" on the same OS thread"++ return$ fromIntegral (t2 - t1)++----------------------------------------------------------------------------------------------------+-- Drivers to get random numbers repeatedly.++incr !counter = + do -- modifyIORef counter (+1)d+ -- Incrementing counter strictly (avoiding stack overflow) is annoying:+ c <- readIORef counter+ let c' = c+1+ evaluate c'+ writeIORef counter c' ++loop :: RandomGen g => IORef Int -> (Int,g) -> IO b+loop !counter !(!n,!g) = + do incr counter+-- putStr (show n); putChar ' '+ loop counter (next g)++data NoopRNG = NoopRNG+instance RandomGen NoopRNG where + split g = (g,g)+ next g = (0,g)++--foreign import ccall "cbits/c_test.c" blast_rands :: Ptr Int -> Ptr Int -> IO ()++type Kern = Int -> Ptr Int -> IO ()++-- [2011.01.28] Changing this to take "count" and "accumulator ptr" as arguments:+foreign import ccall "cbits/c_test.c" blast_rands :: Kern+foreign import ccall "cbits/c_test.c" store_loop :: Kern+foreign import ccall unsafe "stdlib.hs" rand :: IO Int++loop2 :: IORef Int -> IO ()+loop2 !counter = + do incr counter+ n <- rand+ loop2 counter +++----------------------------------------------------------------------------------------------------+-- Timing:++timeit numthreads freq msg mkgen =+ do + counters <- forM [1..numthreads] (const$ newIORef 1) + tids <- forM counters $ \counter -> + forkIO $ loop counter (next$ mkgen 23852358661234) + threadDelay (1000*1000) -- One second+ mapM_ killThread tids++ finals <- mapM readIORef counters+ let mean :: Double = fromIntegral (foldl1 (+) finals) / fromIntegral numthreads+ cycles_per :: Double = fromIntegral freq / mean+ print_result (round mean) msg cycles_per++print_result total msg cycles_per = + putStrLn$ " "++ padleft 11 (commaint total) ++" random ints generated "++ padright 27 ("["++msg++"]") ++" ~ "+ ++ fmt_num cycles_per ++" cycles/int"+++-- FIXME: This isn't working yet because when the C call goes into a tight infinite loop killThread hangs...+-- KEEPING AROUND ONLY FOR FUTURE INVESTIGATION+------------------------------------------------------------+time_c :: Int -> Int64 -> (Ptr Int -> Ptr Int -> IO ()) -> IO Int+time_c numthreads freq ffn = do + counter :: ForeignPtr Int <- mallocForeignPtr+ sum :: ForeignPtr Int <- mallocForeignPtr+ tid <- forkOS $ + withForeignPtr counter $ \ cntr ->+ withForeignPtr sum $ \ sm ->+ ffn cntr sm+ threadDelay (1000*1000) -- One second+ stat <- threadStatus tid+ putStrLn$ "Thread making foreign call's status: "++ show stat+ putStrLn$ "Killing thread running the foreign C call...\n"+ killThread tid -- This will hang!!!+ putStrLn$ "Killed.\n"+ total <- withForeignPtr counter peek + putStrLn$ "Got total: " ++ show total+ return total+------------------------------------------------------------+++-- This version flips things around, and assume something about the+-- timing so that we can run a fixed number of randoms and time it.+-- (We could do binary search here.)+time_c2 :: Int -> Int64 -> String -> (Int -> Ptr Int -> IO ()) -> IO Int+time_c2 numthreads freq msg ffn = do + ptr :: ForeignPtr Int <- mallocForeignPtr++ let kern = if numthreads == 1+ then ffn+ else replicate_kernel numthreads ffn + wrapped n = withForeignPtr ptr (kern$ fromIntegral n)+ (n,t) <- binSearch False 1 (1.0, 1.05) wrapped++ -- ONLY if we're in multi-threaded mode do we then run again with+ -- that input size on all threads:+----------------------------------------+-- NOTE, this approach is TOO SLOW. For workloads that take a massive+-- parallel slowdown it doesn't make sense to use the same input size+-- in serial and in parallel.+-- DISABLING:+{-+ (n2,t2) <- + if numthreads > 1 then do+ ptrs <- mapM (const mallocForeignPtr) [1..numthreads]+ tmpchan <- newChan+ putStrLn$ " [forking threads for multithreaded measurement, input size "++ show n++"]"+ start <- getCPUTime+ tids <- forM ptrs $ \ptr -> forkIO $ + do withForeignPtr ptr (ffn$ fromIntegral n)+ writeChan tmpchan () + forM ptrs $ \_ -> readChan tmpchan+ end <- getCPUTime+ let t2 :: Double = fromIntegral (end-start) / 1000000000000.0+ putStrLn$ " [joined threads, time "++ show t2 ++"]"+ return (n * fromIntegral numthreads, t2)+ else do + return (n,t)+-}+----------------------------------------++ let total_per_second = round $ fromIntegral n * (1 / t)+ cycles_per = fromIntegral freq * t / fromIntegral n+ print_result total_per_second msg cycles_per+ return total_per_second++-- This lifts the C kernel to operate +replicate_kernel :: Int -> Kern -> Kern+replicate_kernel numthreads kern n ptr = do+ ptrs <- forM [1..numthreads]+ (const mallocForeignPtr) + tmpchan <- newChan+ -- let childwork = ceiling$ fromIntegral n / fromIntegral numthreads+ let childwork = n -- Keep it the same.. interested in per-thread throughput.+ -- Fork/join pattern:+ tids <- forM ptrs $ \ptr -> forkIO $ + withForeignPtr ptr $ \p -> do+ kern (fromIntegral childwork) p+ result <- peek p+ writeChan tmpchan result++ results <- forM [1..numthreads] $ \_ -> + readChan tmpchan+ -- Meaningless semantics here... sum the child ptrs and write to the input one:+ poke ptr (foldl1 (+) results)+ return ()++----------------------------------------------------------------------------------------------------+-- Main Script++data Flag = NoC | Help | Test+ deriving (Show, Eq)++options = + [ Option ['h'] ["help"] (NoArg Help) "print program help"+ , Option [] ["noC"] (NoArg NoC) "omit C benchmarks, haskell only"+ , Option ['t'] ["test"] (NoArg Test) "run some basic tests"+ ]++runTests = do + argv <- getArgs+ let (opts,_,other) = getOpt Permute options argv++ putStrLn$ "Does machine supports AESNI?: " ++ show IA.supportsAESNI+ when (Test `elem` opts)$ do+ NI.testAESNI+ exitSuccess++ when (not$ null other) $ do+ putStrLn$ "ERROR: Unrecognized options: " + mapM_ putStr other+ exitFailure++ when (Help `elem` opts) $ do+ putStr$ usageInfo "Benchmark random number generation" options+ exitSuccess++ putStrLn$ "\nHow many random numbers can we generate in a second on one thread?"++ t1 <- rdtsc+ t2 <- rdtsc+ putStrLn (" Cost of rdtsc (ffi call): " ++ show (t2 - t1))++ freq <- measure_freq2+ putStrLn$ " Approx clock frequency: " ++ commaint freq++-- svein <- Svein.newAESGen++ let gamut th = do+ putStrLn$ " First, timing with System.Random interface:"+ timeit th freq "constant zero gen" (const NoopRNG)+ 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 unbuffered" GA.mkAESGen0+-- timeit th freq "Gladman" GA.mkAESGen+ 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 unbuffered" NI.mkAESGen0+ timeit th freq "IntelAES" NI.mkAESGen+ else + putStrLn$ " [Skipping AESNI-only tests, current machine does not support these instructions.]"++ when (not$ NoC `elem` opts) $ do+ putStrLn$ " Comparison to C's rand():"+ time_c2 th freq "ptr store in C loop" store_loop+ time_c2 th freq "rand/store in C loop" blast_rands+ time_c2 th freq "rand in Haskell loop" (\n ptr -> forM_ [1..n]$ \_ -> rand )+ time_c2 th freq "rand/store in Haskell loop" (\n ptr -> forM_ [1..n]$ \_ -> do n <- rand; poke ptr n )+ return ()+ -- timeit 1 freq "rand / Haskell loop" mkBurtonGen++ gamut 1++ when (numCapabilities > 1) $ do +-- when (False) $ do + putStrLn$ "\nNow "++ show numCapabilities ++" threads, reporting mean randoms-per-second-per-thread:"+ gamut numCapabilities+ return ()++ putStrLn$ "Finished."
+ benchmark-intel-aes-rng.hs view
@@ -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
cbits/Intel_AESNI_Sample_Library_v1.0/intel_aes_lib/Makefile view
@@ -1,5 +1,6 @@ UNAME=$(shell uname -m)+OS:=$(shell uname -s) # Must be 86 (for 32bit compiler) or 64 (for 64bit compiler) ARCH=64@@ -7,9 +8,14 @@ # Must be 32 or 64: SZ=64 #SZ=32+LIBDIR=lib/x$(ARCH) -STATIC=lib/x$(ARCH)/libintel_aes.a-DYNAMIC=lib/x$(ARCH)/libintel_aes.so+STATIC=libintel_aes.a+ifeq (Darwin,$(OS))+DYNAMIC=libintel_aes.dylib+else+DYNAMIC=libintel_aes.so+endif SRC= src/intel_aes.c \ asm/x$(ARCH)/iaesx$(ARCH).s \@@ -22,18 +28,27 @@ # GCC=gcc -m32 GCC=gcc YASM=yasm+ifeq (Darwin,$(OS))+YASMFLAGS= -D__linux__ -g null -f macho$(SZ) --prefix=_+L=libtool+LFLAGS=-dynamic -install_name @rpath/$(DYNAMIC) -macosx_version_min 10.5 -lSystem+else YASMFLAGS= -D__linux__ -g dwarf2 -f elf$(SZ) +L=gcc+LFLAGS=-shared -dynamic+endif -all: $(STATIC) $(DYNAMIC)- cp lib/x$(ARCH)/* ../../+all: $(LIBDIR)/$(STATIC) $(LIBDIR)/$(DYNAMIC)+ cp $(LIBDIR)/* ../../ -$(STATIC): $(OBJ)- @mkdir -p lib/x$(ARCH)+$(LIBDIR)/$(STATIC): $(OBJ)+ @mkdir -p $(LIBDIR) ar -r $@ $(OBJ) -$(DYNAMIC): $(OBJ)- @mkdir -p lib/x$(ARCH)- $(GCC) -shared -dynamic -o $(DYNAMIC) $(OBJ)+$(LIBDIR)/$(DYNAMIC): $(OBJ)+ @mkdir -p $(LIBDIR)+ $(L) $(LFLAGS) -o $(DYNAMIC) $(OBJ)+ mv $(DYNAMIC) $(LIBDIR) obj/x$(ARCH)/do_rdtsc.o: asm/x$(ARCH)/do_rdtsc.s @mkdir -p obj/x$(ARCH)@@ -48,4 +63,4 @@ $(GCC) -fPIC -O3 -g -Iinclude/ -c $< -o $@ clean:- rm -f $(STATIC) $(DYNAMIC) $(OBJ)+ rm -f $(STATIC) $(DYNAMIC) $(LIBDIR)/$(STATIC) $(LIBDIR)/$(DYNAMIC) $(OBJ)
+ cbits/Intel_AESNI_Sample_Library_v1.0/intel_aes_lib/where_files_come_from_and_lice view
@@ -0,0 +1,34 @@+/* intel_aes_lib source files come from Intel. + * Modified by Patrick Fay + * +Copyright (c) 2010, Intel Corporation +All rights reserved. + +Redistribution and use in source and binary forms, with or without +modification, are permitted provided that the following conditions are met: + + * Redistributions of source code must retain the above copyright notice, + this list of conditions and the following disclaimer. + * 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. + * Neither the name of Intel Corporation nor the names of its contributors + may be used to endorse or promote products derived from this software + without specific prior written permission. + +THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS 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 COPYRIGHT OWNER 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. + + --------------------------------------------------------------------------- + Issue Date: Aug 6, 2010 + */ + +Other source code files use the license shown in the source code file.
− cbits/Intel_AESNI_Sample_Library_v1.0/intel_aes_lib/where_files_come_from_and_license.txt
@@ -1,34 +0,0 @@-/* intel_aes_lib source files come from Intel. - * Modified by Patrick Fay - * -Copyright (c) 2010, Intel Corporation -All rights reserved. - -Redistribution and use in source and binary forms, with or without -modification, are permitted provided that the following conditions are met: - - * Redistributions of source code must retain the above copyright notice, - this list of conditions and the following disclaimer. - * 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. - * Neither the name of Intel Corporation nor the names of its contributors - may be used to endorse or promote products derived from this software - without specific prior written permission. - -THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS 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 COPYRIGHT OWNER 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. - - --------------------------------------------------------------------------- - Issue Date: Aug 6, 2010 - */ - -Other source code files use the license shown in the source code file.
cbits/Makefile view
@@ -6,4 +6,4 @@ clean: cd Intel_AESNI_Sample_Library_v1.0/intel_aes_lib; $(MAKE) clean- rm -f libintel_aes.a libintel_aes.so+ rm -f libintel_aes.a libintel_aes.so libintel_aes.dylib
intel-aes.cabal view
@@ -1,6 +1,9 @@ Name: intel-aes-Version: 0.1.2.3+Version: 0.2.0.0 +-- 0.1.2.4 -- minor bump for David (dmpots) Mac OS support+-- 0.2.0.0 -- major bump for API reorg+ License: BSD3 License-file: LICENSE Stability: Beta@@ -50,7 +53,7 @@ Category: Cryptography Cabal-Version: >=1.8 Tested-With: GHC == 7.0.1--- Portability: Untested on Windows.+-- Portability: Works on Linux, Mac OS. Untested on Windows. build-type: Custom @@ -86,41 +89,34 @@ 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 -- The gladman sources are straightforward and can be built by Cabal (unlike the intel C/asm) C-sources: cbits/gladman/aescrypt.c, cbits/gladman/aeskey.c, cbits/gladman/aestab.c, cbits/gladman/aes_modes.c, cbits/gladman/ctr_inc.c- Include-Dirs: cbits + -- Include this script as well:+ -- data-files: benchmark-intel-aes-rng.hs+ 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"+-- Example documentation generation command:+-- cabal haddock --hoogle --executables --hyperlink-source --haddock-options="--html"