packages feed

crypto-api 0.1.2.4 → 0.2

raw patch · 5 files changed

+82/−84 lines, 5 filesdep +deepseqdep ~directorydep ~filepathPVP ok

version bump matches the API change (PVP)

Dependencies added: deepseq

Dependency ranges changed: directory, filepath

API changes (from Hackage documentation)

- Crypto.Modes: instance (BlockCipher k) => Serialize (IV k)
- Crypto.Random: genInteger :: (CryptoRandomGen g) => g -> (Integer, Integer) -> Either GenError (Integer, g)
- Crypto.Random: instance Monad (Either GenError)
+ Crypto.Modes: instance BlockCipher k => Serialize (IV k)
- Crypto.Classes: asymKeyLength :: (AsymCipher p) => p -> BitLength
+ Crypto.Classes: asymKeyLength :: AsymCipher p => p -> BitLength
- Crypto.Classes: blockLength :: (Hash ctx d) => Tagged d BitLength
+ Crypto.Classes: blockLength :: Hash ctx d => Tagged d BitLength
- Crypto.Classes: blockSize :: (BlockCipher k) => Tagged k BitLength
+ Crypto.Classes: blockSize :: BlockCipher k => Tagged k BitLength
- Crypto.Classes: blockSizeBytes :: (BlockCipher k) => Tagged k ByteLength
+ Crypto.Classes: blockSizeBytes :: BlockCipher k => Tagged k ByteLength
- Crypto.Classes: buildKey :: (BlockCipher k) => ByteString -> Maybe k
+ Crypto.Classes: buildKey :: BlockCipher k => ByteString -> Maybe k
- Crypto.Classes: buildStreamKey :: (StreamCipher k iv) => ByteString -> Maybe k
+ Crypto.Classes: buildStreamKey :: StreamCipher k iv => ByteString -> Maybe k
- Crypto.Classes: class (Serialize p) => AsymCipher p
+ Crypto.Classes: class Serialize p => AsymCipher p
- Crypto.Classes: class (Serialize k) => BlockCipher k
+ Crypto.Classes: class Serialize k => BlockCipher k
- Crypto.Classes: class (Serialize k) => StreamCipher k iv | k -> iv
+ Crypto.Classes: class Serialize k => StreamCipher k iv | k -> iv
- Crypto.Classes: decryptAsym :: (AsymCipher p) => p -> ByteString -> ByteString
+ Crypto.Classes: decryptAsym :: AsymCipher p => p -> ByteString -> ByteString
- Crypto.Classes: decryptBlock :: (BlockCipher k) => k -> ByteString -> ByteString
+ Crypto.Classes: decryptBlock :: BlockCipher k => k -> ByteString -> ByteString
- Crypto.Classes: decryptStream :: (StreamCipher k iv) => k -> iv -> ByteString -> (ByteString, iv)
+ Crypto.Classes: decryptStream :: StreamCipher k iv => k -> iv -> ByteString -> (ByteString, iv)
- Crypto.Classes: encryptAsym :: (AsymCipher p) => p -> ByteString -> ByteString
+ Crypto.Classes: encryptAsym :: AsymCipher p => p -> ByteString -> ByteString
- Crypto.Classes: encryptBlock :: (BlockCipher k) => k -> ByteString -> ByteString
+ Crypto.Classes: encryptBlock :: BlockCipher k => k -> ByteString -> ByteString
- Crypto.Classes: encryptStream :: (StreamCipher k iv) => k -> iv -> ByteString -> (ByteString, iv)
+ Crypto.Classes: encryptStream :: StreamCipher k iv => k -> iv -> ByteString -> (ByteString, iv)
- Crypto.Classes: finalize :: (Hash ctx d) => ctx -> ByteString -> d
+ Crypto.Classes: finalize :: Hash ctx d => ctx -> ByteString -> d
- Crypto.Classes: hash :: (Hash ctx d) => ByteString -> d
+ Crypto.Classes: hash :: Hash ctx d => ByteString -> d
- Crypto.Classes: hash' :: (Hash ctx d) => ByteString -> d
+ Crypto.Classes: hash' :: Hash ctx d => ByteString -> d
- Crypto.Classes: hashFunc :: (Hash c d) => d -> (ByteString -> d)
+ Crypto.Classes: hashFunc :: Hash c d => d -> (ByteString -> d)
- Crypto.Classes: hashFunc' :: (Hash c d) => d -> (ByteString -> d)
+ Crypto.Classes: hashFunc' :: Hash c d => d -> (ByteString -> d)
- Crypto.Classes: initialCtx :: (Hash ctx d) => ctx
+ Crypto.Classes: initialCtx :: Hash ctx d => ctx
- Crypto.Classes: keyLength :: (BlockCipher k) => k -> BitLength
+ Crypto.Classes: keyLength :: BlockCipher k => k -> BitLength
- Crypto.Classes: outputLength :: (Hash ctx d) => Tagged d BitLength
+ Crypto.Classes: outputLength :: Hash ctx d => Tagged d BitLength
- Crypto.Classes: sign :: (Signing p v) => v -> ByteString -> ByteString
+ Crypto.Classes: sign :: Signing p v => v -> ByteString -> ByteString
- Crypto.Classes: signingKeyLength :: (Signing p v) => v -> BitLength
+ Crypto.Classes: signingKeyLength :: Signing p v => v -> BitLength
- Crypto.Classes: streamKeyLength :: (StreamCipher k iv) => k -> BitLength
+ Crypto.Classes: streamKeyLength :: StreamCipher k iv => k -> BitLength
- Crypto.Classes: updateCtx :: (Hash ctx d) => ctx -> ByteString -> ctx
+ Crypto.Classes: updateCtx :: Hash ctx d => ctx -> ByteString -> ctx
- Crypto.Classes: verify :: (Signing p v) => p -> ByteString -> ByteString -> Bool
+ Crypto.Classes: verify :: Signing p v => p -> ByteString -> ByteString -> Bool
- Crypto.Classes: verifyingKeyLength :: (Signing p v) => p -> BitLength
+ Crypto.Classes: verifyingKeyLength :: Signing p v => p -> BitLength
- Crypto.HMAC: hmac :: (Hash c d) => MacKey -> ByteString -> d
+ Crypto.HMAC: hmac :: Hash c d => MacKey -> ByteString -> d
- Crypto.HMAC: hmac' :: (Hash c d) => MacKey -> ByteString -> d
+ Crypto.HMAC: hmac' :: Hash c d => MacKey -> ByteString -> d
- Crypto.Modes: cbc :: (BlockCipher k) => k -> IV k -> ByteString -> (ByteString, IV k)
+ Crypto.Modes: cbc :: BlockCipher k => k -> IV k -> ByteString -> (ByteString, IV k)
- Crypto.Modes: cbc' :: (BlockCipher k) => k -> IV k -> ByteString -> (ByteString, IV k)
+ Crypto.Modes: cbc' :: BlockCipher k => k -> IV k -> ByteString -> (ByteString, IV k)
- Crypto.Modes: cfb :: (BlockCipher k) => k -> IV k -> ByteString -> (ByteString, IV k)
+ Crypto.Modes: cfb :: BlockCipher k => k -> IV k -> ByteString -> (ByteString, IV k)
- Crypto.Modes: cfb' :: (BlockCipher k) => k -> IV k -> ByteString -> (ByteString, IV k)
+ Crypto.Modes: cfb' :: BlockCipher k => k -> IV k -> ByteString -> (ByteString, IV k)
- Crypto.Modes: ecb :: (BlockCipher k) => k -> ByteString -> ByteString
+ Crypto.Modes: ecb :: BlockCipher k => k -> ByteString -> ByteString
- Crypto.Modes: ecb' :: (BlockCipher k) => k -> ByteString -> ByteString
+ Crypto.Modes: ecb' :: BlockCipher k => k -> ByteString -> ByteString
- Crypto.Modes: getIVIO :: (BlockCipher k) => IO (IV k)
+ Crypto.Modes: getIVIO :: BlockCipher k => IO (IV k)
- Crypto.Modes: ofb :: (BlockCipher k) => k -> IV k -> ByteString -> (ByteString, IV k)
+ Crypto.Modes: ofb :: BlockCipher k => k -> IV k -> ByteString -> (ByteString, IV k)
- Crypto.Modes: ofb' :: (BlockCipher k) => k -> IV k -> ByteString -> (ByteString, IV k)
+ Crypto.Modes: ofb' :: BlockCipher k => k -> IV k -> ByteString -> (ByteString, IV k)
- Crypto.Modes: unCbc :: (BlockCipher k) => k -> IV k -> ByteString -> (ByteString, IV k)
+ Crypto.Modes: unCbc :: BlockCipher k => k -> IV k -> ByteString -> (ByteString, IV k)
- Crypto.Modes: unCbc' :: (BlockCipher k) => k -> IV k -> ByteString -> (ByteString, IV k)
+ Crypto.Modes: unCbc' :: BlockCipher k => k -> IV k -> ByteString -> (ByteString, IV k)
- Crypto.Modes: unCfb :: (BlockCipher k) => k -> IV k -> ByteString -> (ByteString, IV k)
+ Crypto.Modes: unCfb :: BlockCipher k => k -> IV k -> ByteString -> (ByteString, IV k)
- Crypto.Modes: unCfb' :: (BlockCipher k) => k -> IV k -> ByteString -> (ByteString, IV k)
+ Crypto.Modes: unCfb' :: BlockCipher k => k -> IV k -> ByteString -> (ByteString, IV k)
- Crypto.Modes: unEcb :: (BlockCipher k) => k -> ByteString -> ByteString
+ Crypto.Modes: unEcb :: BlockCipher k => k -> ByteString -> ByteString
- Crypto.Modes: unEcb' :: (BlockCipher k) => k -> ByteString -> ByteString
+ Crypto.Modes: unEcb' :: BlockCipher k => k -> ByteString -> ByteString
- Crypto.Modes: unOfb :: (BlockCipher k) => k -> IV k -> ByteString -> (ByteString, IV k)
+ Crypto.Modes: unOfb :: BlockCipher k => k -> IV k -> ByteString -> (ByteString, IV k)
- Crypto.Modes: unOfb' :: (BlockCipher k) => k -> IV k -> ByteString -> (ByteString, IV k)
+ Crypto.Modes: unOfb' :: BlockCipher k => k -> IV k -> ByteString -> (ByteString, IV k)
- Crypto.Padding: padBlockSize :: (BlockCipher k) => k -> ByteString -> ByteString
+ Crypto.Padding: padBlockSize :: BlockCipher k => k -> ByteString -> ByteString
- Crypto.Padding: padESPBlockSize :: (BlockCipher k) => k -> ByteString -> ByteString
+ Crypto.Padding: padESPBlockSize :: BlockCipher k => k -> ByteString -> ByteString
- Crypto.Padding: putPadESPBlockSize :: (BlockCipher k) => k -> ByteString -> Put
+ Crypto.Padding: putPadESPBlockSize :: BlockCipher k => k -> ByteString -> Put
- Crypto.Random: genBytes :: (CryptoRandomGen g) => g -> ByteLength -> Either GenError (ByteString, g)
+ Crypto.Random: genBytes :: CryptoRandomGen g => ByteLength -> g -> Either GenError (ByteString, g)
- Crypto.Random: genBytesWithEntropy :: (CryptoRandomGen g) => g -> ByteLength -> ByteString -> Either GenError (ByteString, g)
+ Crypto.Random: genBytesWithEntropy :: CryptoRandomGen g => ByteLength -> ByteString -> g -> Either GenError (ByteString, g)
- Crypto.Random: genSeedLength :: (CryptoRandomGen g) => Tagged g ByteLength
+ Crypto.Random: genSeedLength :: CryptoRandomGen g => Tagged g ByteLength
- Crypto.Random: newGen :: (CryptoRandomGen g) => ByteString -> Either GenError g
+ Crypto.Random: newGen :: CryptoRandomGen g => ByteString -> Either GenError g
- Crypto.Random: newGenIO :: (CryptoRandomGen g) => IO g
+ Crypto.Random: newGenIO :: CryptoRandomGen g => IO g
- Crypto.Random: reseed :: (CryptoRandomGen g) => g -> ByteString -> Either GenError g
+ Crypto.Random: reseed :: CryptoRandomGen g => ByteString -> g -> Either GenError g
- Data.LargeWord: integerToLargeWord :: (LargeWord a) => Integer -> a
+ Data.LargeWord: integerToLargeWord :: LargeWord a => Integer -> a
- Data.LargeWord: largeBitSize :: (LargeWord a) => a -> Int
+ Data.LargeWord: largeBitSize :: LargeWord a => a -> Int
- Data.LargeWord: largeWordAnd :: (LargeWord a) => a -> a -> a
+ Data.LargeWord: largeWordAnd :: LargeWord a => a -> a -> a
- Data.LargeWord: largeWordOr :: (LargeWord a) => a -> a -> a
+ Data.LargeWord: largeWordOr :: LargeWord a => a -> a -> a
- Data.LargeWord: largeWordPlus :: (LargeWord a) => a -> a -> a
+ Data.LargeWord: largeWordPlus :: LargeWord a => a -> a -> a
- Data.LargeWord: largeWordShift :: (LargeWord a) => a -> Int -> a
+ Data.LargeWord: largeWordShift :: LargeWord a => a -> Int -> a
- Data.LargeWord: largeWordToInteger :: (LargeWord a) => a -> Integer
+ Data.LargeWord: largeWordToInteger :: LargeWord a => a -> Integer
- Data.LargeWord: largeWordXor :: (LargeWord a) => a -> a -> a
+ Data.LargeWord: largeWordXor :: LargeWord a => a -> a -> a

Files

Benchmark/Crypto.hs view
@@ -26,16 +26,19 @@ 	( benchmarkHash 	, benchmarkBlockCipher 	, benchmarkRNG+	, benchmarkCryptoRandomGen 	) where  import Crypto.Classes import Crypto.Modes (ecb', unEcb')+import Crypto.Random import qualified Data.Serialize as Ser import qualified Data.ByteString as B import qualified Data.ByteString.Lazy as L import Data.Serialize as Ser import Criterion import Control.Monad (liftM)+import Data.IORef  -- 128KB strings ps = B.replicate (2^17) 0@@ -64,5 +67,25 @@ 	in benchs  -- |Benchmark an RNG by requesting 256K of random data-benchmarkRNG :: (Int -> IO L.ByteString) -> String -> Benchmark-benchmarkRNG rng name = bench name (nfIO $ liftM (map B.head . L.toChunks ) (rng (2^18)))+benchmarkRNG :: (Int -> IO B.ByteString) -> String -> Benchmark+benchmarkRNG rng name = bench name (nfIO $ liftM B.head (rng (2^18)))++-- | Benchmark a CryptoRandomGen by storing it in a IORef, and generating+-- 256k per call.+benchmarkCryptoRandomGen :: CryptoRandomGen g => g -> String -> IO Benchmark+benchmarkCryptoRandomGen g name = do+	g' <- useGenIO g+	return $ bench name (nfIO $ liftM B.head (g' (2^18)))++useGenIO :: CryptoRandomGen g => g -> IO (Int -> IO B.ByteString)+useGenIO g = do+        gRef <- newIORef g+        return $ \i -> do+        gen <- readIORef gRef+        let v = genBytes i gen+        case v of+                Left _ -> error "blah"+                Right (b,gen') -> do+                        writeIORef gRef gen'+                        return b+
Crypto/Modes.hs view
@@ -1,4 +1,3 @@-{-# LANGUAGE ScopedTypeVariables, MonoLocalBinds #-} {-|  Maintainer: Thomas.DuBuisson@gmail.com  Stability: beta@@ -31,9 +30,11 @@ import qualified Data.Serialize.Put as SP import qualified Data.Serialize.Get as SG import Data.Bits (xor)+import Data.Tagged import Crypto.Classes import Crypto.Random import System.Crypto.Random (getEntropy)+import Control.Monad (liftM)  -- |Initilization Vectors for BlockCipher implementations (IV k) are used -- for various modes and guarrenteed to be blockSize bits long.@@ -253,7 +254,7 @@ getIV :: (BlockCipher k, CryptoRandomGen g) => g -> Either GenError (IV k, g) getIV g = 	let bytes = ivBlockSizeBytes iv-	    gen = genBytes g bytes+	    gen = genBytes bytes g 	    fromRight (Right x) = x 	    iv  = IV (fst  . fromRight $ gen) 	in case gen of@@ -262,25 +263,36 @@ 			| B.length bs == bytes	-> Right (iv, g') 			| otherwise		-> Left (GenErrorOther "Generator failed to provide requested number of bytes") --- |Obtain an `IV` using the system entropy (see "System.Crypto.Random")+-- | Obtain an `IV` using the system entropy (see "System.Crypto.Random") getIVIO :: (BlockCipher k) => IO (IV k) getIVIO = do-	let bytes = ivBlockSizeBytes p-	    p = undefined-	bs <- getEntropy bytes-	return (IV bs `asTypeOf` p)+	let p = Proxy+	    getTypedIV :: BlockCipher k => Proxy k -> IO (IV k)+	    getTypedIV pr = liftM IV (getEntropy (proxy blockSize pr `div` 8))+	iv <- getTypedIV p+	return (iv `asProxyTypeOf` ivProxy p) +ivProxy :: Proxy k -> Proxy (IV k)+ivProxy = reproxy++deIVProxy :: Proxy (IV k) -> Proxy k+deIVProxy = reproxy++proxyOf :: a -> Proxy a+proxyOf = const Proxy+ ivBlockSizeBytes :: BlockCipher k => IV k -> Int-ivBlockSizeBytes iv = (blockSize `for` (keyForIV iv)) `div` 8-  where-  keyForIV :: IV k -> k-  keyForIV _ = undefined+ivBlockSizeBytes iv =+	let p = deIVProxy (proxyOf iv)+	in proxy blockSize p `div` 8  instance (BlockCipher k) => Serialize (IV k) where 	get = do-	  	let bytes = blockSize .::. (undefined :: k) `div` 8-		iv <- SG.getByteString bytes-		return (IV iv)+		let p = Proxy+		    doGet :: BlockCipher k => Proxy k -> Get (IV k)+	            doGet pr = liftM IV (SG.getByteString (proxy blockSize pr `div` 8))+		iv <- doGet p+		return (iv `asProxyTypeOf` ivProxy p) 	put (IV iv) = SP.putByteString iv  -- TODO: GCM, GMAC
Crypto/Random.hs view
@@ -1,4 +1,4 @@-{-# LANGUAGE ScopedTypeVariables, MonoLocalBinds, FlexibleInstances,CPP #-}+{-# LANGUAGE FlexibleInstances, TypeSynonymInstances #-} {-|  Maintainer: Thomas.DuBuisson@gmail.com  Stability: beta@@ -21,7 +21,6 @@  module Crypto.Random 	( CryptoRandomGen(..)-	, genInteger 	, GenError (..) 	, newGenIO 	) where@@ -43,13 +42,6 @@ 	| NotEnoughEntropy	-- ^ For instantiating new generators (or reseeding)   deriving (Eq, Ord, Show) -#if !MIN_VERSION_base(4,3,0)-instance Monad (Either GenError) where-        return = Right-        (Left x) >>= _  = Left x-        (Right x) >>= f = f x-#endif- -- |A class of random bit generators that allows for the possibility of failure, -- reseeding, providing entropy at the same time as requesting bytes --@@ -62,7 +54,7 @@ 	genSeedLength :: Tagged g ByteLength  	-- |Obtain random data using a generator-	genBytes	:: g -> ByteLength -> Either GenError (B.ByteString, g)+	genBytes	:: ByteLength -> g -> Either GenError (B.ByteString, g)  	-- |@genBytesWithEntropy g i entropy@ generates @i@ random bytes and use the 	-- additional input @entropy@ in the generation of the requested data to@@ -73,9 +65,9 @@ 	-- @ 	--     genBytesWithEntropy g bytes entropy = xor entropy (genBytes g bytes) 	-- @-	genBytesWithEntropy	:: g -> ByteLength -> B.ByteString -> Either GenError (B.ByteString, g)-	genBytesWithEntropy g len entropy =-		let res = genBytes g len+	genBytesWithEntropy	:: ByteLength -> B.ByteString -> g -> Either GenError (B.ByteString, g)+	genBytesWithEntropy len entropy g =+		let res = genBytes len g 		in case res of 			Left err -> Left err 			Right (bs,g') ->@@ -83,54 +75,25 @@ 				in Right (zwp' entropy' bs, g')  	-- |reseed the generator-	reseed		:: g -> B.ByteString -> Either GenError g+	reseed		:: B.ByteString -> g -> Either GenError g  -- |Use "System.Crypto.Random" to obtain entropy for `newGen`. newGenIO :: CryptoRandomGen g => IO g-newGenIO = do-	let r = undefined-	    l = genSeedLength `for` r-	res <- liftM newGen (getEntropy l)+newGenIO = go 0+  where+  go 1000 = error "The generator instance requested by newGenIO never instantiates (1000 tries).  It must be broken."+  go i = do+	let p = Proxy+	    getTypedGen :: (CryptoRandomGen g) => Proxy g -> IO (Either GenError g)+	    getTypedGen pr = liftM newGen (getEntropy $ proxy genSeedLength pr)+	res <- getTypedGen p 	case res of-		Left _ -> newGenIO-		Right g -> return (g `asTypeOf` r)+		Left _ -> go (i+1)+		Right g -> return (g `asProxyTypeOf` p)  -- |Obtain a tagged value for a particular instantiated type. for :: Tagged a b -> a -> b for t _ = unTagged t---- |@genInteger g (low,high)@ will generate an integer between [low, high] inclusively, swapping the pair if high < low.------ This function has degraded (theoretically unbounded, probabilitically decent) performance--- the closer your range size (high - low) is to 2^n (from the top).-genInteger :: CryptoRandomGen g => g -> (Integer, Integer) -> Either GenError (Integer, g)-genInteger g (low,high)-	| high < low = genInteger  g (high,low)-	| high == low = Right (high, g)-	| otherwise = go g-  where-  mask   = foldl' setBit 0 [0 .. fromIntegral nrBits - 1]-  nrBits = base2Log range-  range  = high - low-  nrBytes = (nrBits + 7) `div` 8-  go gen =-	let offset = genBytes gen (fromIntegral nrBytes)-	in case offset of-        Left err -> Left err-        Right (bs,g') -> -	    if nrBytes > fromIntegral (maxBound :: Int)-		then Left RangeInvalid-		else let res = low + (bs2i bs .&. mask)-		     in if res > high then go g' else Right (res, g')--base2Log :: Integer -> Integer-base2Log i-	| i >= setBit 0 64 = 64 + base2Log (i `shiftR` 64)-	| i >= setBit 0 32 = 32 + base2Log (i `shiftR` 32)-	| i >= setBit 0 16 = 16 + base2Log (i `shiftR` 16)-	| i >= setBit 0 8  = 8  + base2Log (i `shiftR` 8)-	| i >= setBit 0 0  = 1  + base2Log (i `shiftR` 1)-	| otherwise        = 0  bs2i :: B.ByteString -> Integer bs2i bs = B.foldl' (\i b -> (i `shiftL` 8) + fromIntegral b) 0 bs
Test/ParseNistKATs.hs view
@@ -35,7 +35,6 @@ module Test.ParseNistKATs 	( parseCategories --, parseCategory, parseProperty 	, Properties, Record, NistTest, TypedTest, TestCategory-	, -- module Text.Parsec 	) where  import Data.Char (isSpace)
crypto-api.cabal view
@@ -1,5 +1,5 @@ name:           crypto-api-version:        0.1.2.4+version:        0.2 license:        BSD3 license-file:   LICENSE copyright:      Thomas DuBuisson <thomas.dubuisson@gmail.com>, Dominic Steinitz (see Data.LargeWord module)@@ -27,17 +27,18 @@ build-type:     Simple cabal-version:  >= 1.6 tested-with:    GHC == 6.12.1-Data-Files:-          Test/KAT_AES/*.txt-	, Test/KAT_SHA/*.txt-	, Test/KAT_HMAC/*.txt-	, Test/KAT_TWOFISH/*.TXT+data-files:+         Test/KAT_AES/*.txt+       , Test/KAT_SHA/*.txt+       , Test/KAT_HMAC/*.txt+       , Test/KAT_TWOFISH/*.TXT extra-source-files:-          Test/KAT_AES/*.txt-        , Test/KAT_SHA/*.txt-        , Test/KAT_HMAC/*.txt-	, Test/KAT_TWOFISH/*.TXT+         Test/KAT_AES/*.txt+       , Test/KAT_SHA/*.txt+       , Test/KAT_HMAC/*.txt+       , Test/KAT_TWOFISH/*.TXT + flag tests   description: Include Test.Crypto module for testing hash and cipher instances   default: False@@ -46,12 +47,13 @@   description: Include benchmarking tools for cryptographic operations   default: False + Library   Build-Depends: base == 4.*,                  bytestring >= 0.9 && < 0.10,                  cereal >= 0.2 && < 0.4,                  tagged == 0.1.*,-                 filepath >= 1.1 && < 1.2+                 filepath >= 1.1 && < 1.3   ghc-options:   -O2   hs-source-dirs:   exposed-modules: Crypto.Classes, Crypto.Types, Crypto.HMAC, Data.LargeWord, Crypto.Modes, System.Crypto.Random, Crypto.Random, Crypto.Padding@@ -60,12 +62,11 @@     extra-libraries: advapi32   if flag(tests)     exposed-modules: Test.Crypto, Test.AES, Test.SHA, Test.HMAC, Test.ParseNistKATs, Test.TwoFish-    build-depends: QuickCheck >= 2.3 && < 2.4, directory >= 1.0.1.0 && < 1.1+    build-depends: QuickCheck >= 2.3 && < 2.4, directory >= 1.0.1.0 && < 1.2     other-modules: Paths_crypto_api   if flag(benchmarks)     exposed-modules: Benchmark.Crypto-    build-depends: criterion >= 0.5-+    build-depends: criterion >= 0.5, deepseq source-repository head     type:     darcs     location: http://code.haskell.org/crypto-api