crypto-random-api-0.2.0/0000755000000000000000000000000012071231571013243 5ustar0000000000000000crypto-random-api-0.2.0/LICENSE0000644000000000000000000000273112071231571014253 0ustar0000000000000000Copyright (c) 2010-2012 Vincent Hanquez All rights reserved. Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met: 1. Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer. 2. 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. 3. Neither the name of the author nor the names of his contributors may be used to endorse or promote products derived from this software without specific prior written permission. THIS SOFTWARE IS PROVIDED BY THE REGENTS 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 AUTHORS 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. crypto-random-api-0.2.0/Setup.hs0000644000000000000000000000005612071231571014700 0ustar0000000000000000import Distribution.Simple main = defaultMain crypto-random-api-0.2.0/crypto-random-api.cabal0000644000000000000000000000153212071231571017575 0ustar0000000000000000Name: crypto-random-api Version: 0.2.0 Description: Simple random generators API for cryptography related code License: BSD3 License-file: LICENSE Copyright: Vincent Hanquez Author: Vincent Hanquez Maintainer: Vincent Hanquez Synopsis: Simple random generators API for cryptography related code Category: Cryptography Build-Type: Simple Homepage: http://github.com/vincenthz/hs-crypto-random-api Cabal-Version: >=1.6 Library Exposed-modules: Crypto.Random.API Build-depends: base >= 4 && < 5 , bytestring , entropy source-repository head type: git location: git://github.com/vincenthz/hs-crypto-random-api crypto-random-api-0.2.0/Crypto/0000755000000000000000000000000012071231571014523 5ustar0000000000000000crypto-random-api-0.2.0/Crypto/Random/0000755000000000000000000000000012071231571015743 5ustar0000000000000000crypto-random-api-0.2.0/Crypto/Random/API.hs0000644000000000000000000001255012071231571016713 0ustar0000000000000000-- | -- Module : Crypto.Random.API -- License : BSD-style -- Maintainer : Vincent Hanquez -- Stability : experimental -- Portability : Good module Crypto.Random.API ( CPRG(..) , ReseedPolicy(..) , genRandomBytes , genRandomBytes' , withRandomBytes , getSystemEntropy -- * System Random generator , SystemRandom , getSystemRandomGen ) where import Control.Applicative import qualified Data.ByteString as B import Data.ByteString (ByteString) import qualified System.Entropy as SE import System.IO.Unsafe (unsafeInterleaveIO) import Data.Word -- | This is the reseed policy requested by the CPRG data ReseedPolicy = NeverReseed -- ^ there is no need to reseed as either -- the RG doesn't supports it, it's done automatically -- or pratically the reseeding period exceed a Word64 type. | ReseedInBytes Word64 -- ^ the RG need to be reseed in the number -- of bytes joined to the type. it should be done before -- the number reached 0, otherwise an user of the RG -- might request too many bytes and get repeated random bytes. deriving (Show,Eq) -- | A class of Cryptographic Secure Random generator. -- -- The main difference with the generic haskell RNG is that -- it return bytes instead of integer. -- -- It is quite similar to the CryptoRandomGen class in crypto-api -- except that error are not returned to the user. Instead -- the user is suppose to handle reseeding by using the NeedReseed -- and SupplyEntropy methods. For other type of errors, the user -- is expected to generate bytes with the parameters bounds explicity -- defined here. -- -- The CPRG need to be able to generate up to 2^20 bytes in one call, -- class CPRG g where -- | Provide a way to query the CPRG to calculate when new entropy -- is required to be supplied so the CPRG doesn't repeat output, and -- break assumptions. This returns the number of bytes before -- which supply entropy should have been called. cprgNeedReseed :: g -> ReseedPolicy -- | Supply entropy to the CPRG, that can be used now or later -- to reseed the CPRG. This should be used in conjunction to -- NeedReseed to know when to supply entropy. cprgSupplyEntropy :: ByteString -> g -> g -- | Generate bytes using the CPRG and the number specified. -- -- For user of the API, it's recommended to use genRandomBytes -- instead of this method directly. the CPRG need to be able -- to supply at minimum 2^20 bytes at a time. cprgGenBytes :: Int -> g -> (ByteString, g) -- | Generate bytes using the cprg in parameter. -- -- If the number of bytes requested is really high, -- it's preferable to use 'genRandomBytes' for better memory efficiency. genRandomBytes :: CPRG g => Int -- ^ number of bytes to return -> g -- ^ CPRG to use -> (ByteString, g) genRandomBytes len rng = (\(lbs,g) -> (B.concat lbs, g)) $ genRandomBytes' len rng -- | Generate bytes using the cprg in parameter. -- -- This is not tail recursive and an excessive len (>= 2^29) parameter would -- result in stack overflow. genRandomBytes' :: CPRG g => Int -- ^ number of bytes to return -> g -- ^ CPRG to use -> ([ByteString], g) genRandomBytes' len rng | len < 0 = error "genBytes: cannot request negative amount of bytes." | otherwise = loop rng len where loop g len | len == 0 = ([], g) | otherwise = let itBytes = min (2^20) len (bs, g') = cprgGenBytes itBytes g (l, g'') = genRandomBytes' (len-itBytes) g' in (bs:l, g'') -- | this is equivalent to using Control.Arrow 'first' with 'genRandomBytes'. -- -- namely it generate @len bytes and map the bytes to the function @f withRandomBytes :: CPRG g => g -> Int -> (ByteString -> a) -> (a, g) withRandomBytes rng len f = (f bs, rng') where (bs, rng') = genRandomBytes len rng -- | Return system entropy using the entropy package 'getEntropy' getSystemEntropy :: Int -> IO ByteString getSystemEntropy = SE.getEntropy -- | This is a simple generator that pull bytes from the system entropy -- directly. Its randomness and security properties are absolutely -- depends on the underlaying system implementation. data SystemRandom = SystemRandom [B.ByteString] -- | Get a random number generator based on the standard system entropy source getSystemRandomGen :: IO SystemRandom getSystemRandomGen = do ch <- SE.openHandle let getBS = unsafeInterleaveIO $ do bs <- SE.hGetEntropy ch 8192 more <- getBS return (bs:more) SystemRandom <$> getBS instance CPRG SystemRandom where cprgNeedReseed _ = NeverReseed cprgSupplyEntropy _ g = g cprgGenBytes n (SystemRandom l) = (B.concat l1, SystemRandom l2) where (l1, l2) = lbsSplitAt n l lbsSplitAt rBytes (x:xs) | xLen >= rBytes = let (b1,b2) = B.splitAt rBytes x in ([b1], b2:xs) | otherwise = let (l1,l2) = lbsSplitAt (rBytes-xLen) xs in (x:l1,l2) where xLen = B.length x