DRBG 0.5 → 0.5.1
raw patch · 3 files changed
+25/−37 lines, 3 filesPVP ok
version bump matches the API change (PVP)
API changes (from Hackage documentation)
+ Crypto.Random.DRBG.CTR: instance Serialize a => Serialize (State a)
Files
- Crypto/Random/DRBG.hs +11/−29
- Crypto/Random/DRBG/CTR.hs +13/−7
- DRBG.cabal +1/−1
Crypto/Random/DRBG.hs view
@@ -1,4 +1,4 @@-{-# LANGUAGE EmptyDataDecls, FlexibleInstances, TypeSynonymInstances, BangPatterns, ScopedTypeVariables #-}+{-# LANGUAGE FlexibleInstances, TypeSynonymInstances, BangPatterns, ScopedTypeVariables #-} {-| Maintainer: Thomas.DuBuisson@gmail.com Stability: beta@@ -6,9 +6,9 @@ This module is the convenience interface for the DRBG (NIST standardized number-theoretically secure random number generator). Everything is setup-for using the "crypto-api" 'CryptoRandomGen' type class. +for using the "crypto-api" 'CryptoRandomGen' type class. -To instantiate the base types of 'HmacDRBG', 'HashDRBG', or 'GenAES' just use+To instantiate the base types of 'HmacDRBG', 'HashDRBG', or 'CtrDRBG' just use the 'CryptoRandomGen' primitives of 'newGen' or 'newGenIO'. For example, to seed a new generator with the system secure random@@ -77,20 +77,14 @@ import Crypto.Util import Crypto.Classes import Crypto.Random-import Crypto.Modes (zeroIV) import Crypto.Hash.CryptoAPI import Crypto.Cipher.AES128 (AESKey) import Crypto.Types import System.Entropy import qualified Data.ByteString as B-import qualified Data.ByteString.Internal as BI import Data.Tagged-import Data.Proxy-import Data.Bits (xor) import Control.Parallel-import Control.Monad (liftM) import Control.Monad.Error () -- Either instance-import Data.Serialize (encode) import Data.Word instance H.SeedLength SHA512 where@@ -271,7 +265,7 @@ return (GenAutoReseed rs 0 a' b') else return $ GenAutoReseed rs (cnt + fromIntegral req) aNew b return (res, gNew)- genBytesWithEntropy req entropy (GenAutoReseed rs cnt a b) = do+ genBytesWithEntropy req entropy (GenAutoReseed rs cnt a b) = case genBytesWithEntropy req entropy a of Left NeedReseed -> do (ent,b') <- genBytes (genSeedLength `for` a) b@@ -308,7 +302,7 @@ else InXBytes (rs * b) (_, InXBytes b) -> let s = genSeedLength `for` ag- nr = if s <= 0 then 1 else ((b `div` fromIntegral s) - 1)+ nr = if s <= 0 then 1 else (b `div` fromIntegral s) - 1 in InXBytes $ rs * nr reseedInfo (GenAutoReseed rs x ag bg) = -- Attempt to provide a lower bound on the next reseed@@ -377,6 +371,7 @@ -- maintain a buffer of random values size >= 1MB and <= 5MB at any time. data GenBuffered g = GenBuffered Int Int (Either (GenError, g) (B.ByteString, g)) {-# UNPACK #-} !B.ByteString +bufferMinDef, bufferMaxDef :: Int bufferMinDef = 2^20 bufferMaxDef = 2^22 @@ -390,7 +385,7 @@ newGenBufferedIO :: CryptoRandomGen g => Int -> Int -> IO (GenBuffered g) newGenBufferedIO min max = do g <- newGenIO- let !(Right !gBuf) = do+ let (Right !gBuf) = do (rs,g') <- genBytes min g let new = wrapErr (genBytes min g') g' rs `par` return (GenBuffered min max new rs)@@ -409,7 +404,7 @@ where help :: Tagged (GenBuffered g) c -> g help = const undefined- genBytes req gb@(GenBuffered min max g bs)+ genBytes req (GenBuffered min max g bs) | remSize >= min = Right (B.take req bs, GenBuffered min max g (B.drop req bs)) | B.length bs < min = case g of@@ -430,7 +425,7 @@ let new | B.length rnd > 0 = wrapErr (genBytes (max - (remSize + B.length rnd)) gen) gen | otherwise = Right (B.empty,gen) (rs,rem) = B.splitAt req bs- in (eval new) `par` Right (rs, GenBuffered min max new (B.append rem rnd))+ in eval new `par` Right (rs, GenBuffered min max new (B.append rem rnd)) | otherwise = Left $ GenErrorOther "Buffering generator hit an impossible case. Please inform the Haskell crypto-api maintainer" where remSize = B.length bs - req@@ -441,7 +436,7 @@ Left (_,g') -> (B.empty, g') Right (rs, g') -> (rs, g') g'' <- reseed ent g'- let new = wrapErr (genBytes (min-B.length bs') g'') g''+ let new = wrapErr (genBytes (min - B.length bs') g'') g'' bs' = B.take max (B.append bs rs) return (GenBuffered min max new bs') reseedPeriod ~(GenBuffered _ _ g _) = reseedPeriod . either snd snd $ g@@ -454,7 +449,7 @@ -- |Force evaluation for use by GenBuffered. eval :: Either x (B.ByteString, g) -> Either x (B.ByteString, g) eval (Left x) = Left x-eval (Right (g,bs)) = bs `seq` (g `seq` (Right (g, bs)))+eval (Right (g,bs)) = bs `seq` (g `seq` Right (g, bs)) instance BlockCipher x => CryptoRandomGen (CtrDRBGWith x) where newGen bytes =@@ -494,16 +489,3 @@ reseedPeriod _ = InXCalls CTR.reseedInterval reseedInfo st = InXCalls (CTR.reseedInterval - CTR.getCounter st)--asProxyStateTypeOf :: CTR.State a -> Proxy a -> CTR.State a-asProxyStateTypeOf = const--xorExtendBS a b = res- where- x = B.pack $ B.zipWith Data.Bits.xor a b- res | al /= bl = x- | otherwise = B.append x rem- al = B.length a- bl = B.length b- rem | bl > al = B.drop al b- | otherwise = B.drop bl a
Crypto/Random/DRBG/CTR.hs view
@@ -1,4 +1,4 @@-{-# LANGUAGE TupleSections, BangPatterns #-}+{-# LANGUAGE TupleSections #-} module Crypto.Random.DRBG.CTR ( State , getCounter@@ -12,21 +12,27 @@ import Data.ByteString (ByteString) import qualified Data.ByteString as B import Crypto.Classes+import Data.Serialize import Crypto.Types import Crypto.Random.DRBG.Types-import Control.Monad (join) import Data.Word (Word64)-import Data.Proxy data State a = St { counter :: {-# UNPACK #-} !Word64 , value :: !(IV a) , key :: a } +instance Serialize a => Serialize (State a) where+ get = do c <- getWord64be+ v <- get+ k <- get+ return $ St c (IV v) k+ put (St c (IV v) k) = putWord64be c >> put v >> put k+ -- |Get a count of how many times this generator has been used since -- instantiation or reseed. getCounter :: State a -> Word64-getCounter st = counter st+getCounter = counter -- |Update the RNG update :: BlockCipher a => ByteString -> State a -> Maybe (State a)@@ -83,13 +89,13 @@ generate st0 len ai0 | counter st0 > reseedInterval = Nothing | not (B.null ai0) =- let aiNew = (B.take seedLen (B.append ai0 (B.replicate seedLen 0)))+ let aiNew = B.take seedLen (B.append ai0 (B.replicate seedLen 0)) in do st' <- update aiNew st0 go st' aiNew | otherwise = go st0 (B.replicate seedLen 0) where- outLen = (blockSizeBytes `for` key st0)- keyLen = (keyLengthBytes `for` key st0)+ outLen = blockSizeBytes `for` key st0+ keyLen = keyLengthBytes `for` key st0 seedLen = outLen + keyLen -- go :: BlockCipher a => State a -- -> AdditionalInput
DRBG.cabal view
@@ -1,5 +1,5 @@ name: DRBG-version: 0.5+version: 0.5.1 license: BSD3 license-file: LICENSE author: Thomas DuBuisson <thomas.dubuisson@gmail.com>