packages feed

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 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"