packages feed

scrypt 0.3.6 → 0.4.0

raw patch · 3 files changed

+45/−36 lines, 3 files

Files

scrypt.cabal view
@@ -1,5 +1,5 @@ name:           scrypt-version:        0.3.6+version:        0.4.0 license:        BSD3 license-file:   LICENSE category:       Cryptography
src/Crypto/Scrypt.hs view
@@ -10,7 +10,7 @@ module Crypto.Scrypt (     -- * Parameters to the @scrypt@ function     -- $params-     ScryptParams, scryptParams, defaultParams+     ScryptParams, scryptParams, scryptParamsLen, defaultParams     -- * Password Storage     -- $password-storage     , EncryptedPass(..), encryptPass, encryptPass', verifyPass, verifyPass'@@ -21,7 +21,7 @@  import Control.Applicative import qualified Data.ByteString.Base64 as Base64-import Data.ByteString.Char8 hiding (map, concat)+import qualified Data.ByteString.Char8 as B import Data.Maybe import Foreign (Ptr, Word8, Word32, Word64, allocaBytes, castPtr) import Foreign.C@@ -29,11 +29,11 @@ import System.IO.Unsafe (unsafePerformIO)  -newtype Pass          = Pass     { unPass :: ByteString } deriving (Show, Eq)-newtype Salt          = Salt     { unSalt :: ByteString } deriving (Show, Eq)-newtype PassHash      = PassHash { unHash :: ByteString } deriving (Show, Eq)+newtype Pass          = Pass     { getPass :: B.ByteString } deriving (Show, Eq)+newtype Salt          = Salt     { getSalt :: B.ByteString } deriving (Show, Eq)+newtype PassHash      = PassHash { getHash :: B.ByteString } deriving (Show, Eq) newtype EncryptedPass =-    EncryptedPass { unEncryptedPass  :: ByteString } deriving (Show, Eq)+    EncryptedPass { getEncryptedPass  :: B.ByteString } deriving (Show, Eq)  ------------------------------------------------------------------------------ -- $params@@ -52,44 +52,50 @@ -- /Running time/ is proportional to all of @N@, @r@ and @p@. Since it's -- influence on memory usage is small, @p@ can be used to independently tune -- the running time.---  -- |Encapsulates the three tuning parameters to the 'scrypt' function: @N@,--- @r@ and @p@ (see above).+-- @r@ and @p@ (see above) as well es the length of the derived key. ---data ScryptParams = Params { logN, r, p, bufLen :: Integer} deriving (Eq)--instance Show ScryptParams where-    show Params{..} = concat [ "ScryptParams "-        , "{ logN=", show logN-        , ", r="   , show r-        , ", p="   , show p-        , " }"-        ]+data ScryptParams = Params { logN, r, p, bufLen :: Integer} deriving (Eq, Show) --- |Constructor function for the 'ScryptParams' data type---+-- |Constructor function for 'ScryptParams' with default derived-key-length of+--  64 bytes. scryptParams     :: Integer     -- ^ @log_2(N)@. Scrypt's @N@ parameter must be a power of two greater     --   than one, thus it's logarithm to base two must be greater than zero.     --   @128*r*N@ must be smaller than the available memory address space.     -> Integer-    -- ^ The parameter @r@, must be greater than zero.+    -- ^ @r@, must be greater than zero.     -> Integer-    -- ^ The parameter @p@, must be greater than zero. @r@ and @p@+    -- ^ @p@, must be greater than zero. @r@ and @p@     --   must satisfy @r*p < 2^30@.     -> Maybe ScryptParams     -- ^ Returns 'Just' the parameter object for valid arguments,     --   otherwise 'Nothing'.     ---scryptParams logN r p | valid     = Just ps-                      | otherwise = Nothing+scryptParams logN r p = scryptParamsLen logN r p 64++-- |Constructor function for 'ScryptParams' with an additional parameter to+--  control the length of the derived key. Only use this function if you are+--  sure you need control over the length of the derived key. Use 'scryptParams'+--  instead.+--+scryptParamsLen+    :: Integer -- ^ @log_2(N)@,+    -> Integer -- ^ @r@,+    -> Integer -- ^ @p@,+    -> Integer+    -- ^ Length of the derived key (the output of 'scrypt') in bytes.+    --   Must be greater than zero and less than or equal to @(2^32-1)*32@.+    -> Maybe ScryptParams+scryptParamsLen logN r p bufLen+    | valid     = Just Params { logN, r, p, bufLen }+    | otherwise = Nothing   where-    ps    = Params { logN, r, p, bufLen = 64 }     valid = and [ logN > 0, r > 0, p > 0                 , r*p < 2^(30 :: Int)-                , bufLen ps <= 2^(32 :: Int)-1 * 32+                , bufLen > 0, bufLen <= 2^(32 :: Int)-1 * 32                 -- allocation fits into (virtual) memory                 , 128*r*2^logN <= fromIntegral (maxBound :: CSize)                 ]@@ -131,19 +137,20 @@  combine :: ScryptParams -> Salt -> PassHash -> EncryptedPass combine Params{..} (Salt salt) (PassHash passHash) =-    EncryptedPass $ intercalate "|"+    EncryptedPass $ B.intercalate "|"         [ showBS logN, showBS r, showBS p         , Base64.encode salt, Base64.encode passHash]   where-    showBS = pack . show+    showBS = B.pack . show  separate :: EncryptedPass -> Maybe (ScryptParams, Salt, PassHash)-separate = go . split '|' . unEncryptedPass+separate = go . B.split '|' . getEncryptedPass   where     go [logN', r', p', salt', hash'] = do         [salt, hash] <- mapM decodeBase64 [salt', hash']-        [logN, r, p] <- mapM (fmap fst . readInteger) [logN', r', p']-        params       <- scryptParams logN r p+        [logN, r, p] <- mapM (fmap fst . B.readInteger) [logN', r', p']+        let bufLen = fromIntegral (B.length hash)+        params       <- scryptParamsLen logN r p bufLen         return (params, Salt salt, PassHash hash)     go _         = Nothing     decodeBase64 = either (const Nothing) Just . Base64.decode@@ -210,20 +217,20 @@ -- consider using the more convenient higher-level API above. -- --- |Calculates a 64-byte hash from the given password, salt and parameters.+-- |Calculates a hash from the given password, salt and parameters. -- scrypt :: ScryptParams -> Salt -> Pass -> PassHash scrypt Params{..} (Salt salt) (Pass pass) =     PassHash <$> unsafePerformIO $-        useAsCStringLen salt $ \(saltPtr, saltLen) ->-        useAsCStringLen pass $ \(passPtr, passLen) ->+        B.useAsCStringLen salt $ \(saltPtr, saltLen) ->+        B.useAsCStringLen pass $ \(passPtr, passLen) ->         allocaBytes (fromIntegral bufLen) $ \bufPtr -> do             throwErrnoIfMinus1_ "crypto_scrypt" $ crypto_scrypt                 (castPtr passPtr) (fromIntegral passLen)                 (castPtr saltPtr) (fromIntegral saltLen)                 (2^logN) (fromIntegral r) (fromIntegral p)                 bufPtr (fromIntegral bufLen)-            packCStringLen (castPtr bufPtr, fromIntegral bufLen)+            B.packCStringLen (castPtr bufPtr, fromIntegral bufLen)  foreign import ccall unsafe crypto_scrypt     :: Ptr Word8 -> CSize         -- password
test/Test.hs view
@@ -14,14 +14,16 @@ import Test.QuickCheck import Test.QuickCheck.Property (morallyDubiousIOProperty) + instance Arbitrary ScryptParams where     arbitrary = do         logN <- elements [1..14]         r    <- elements [1..8]         p    <- elements [1..2]+        bufLen <- elements [1..128]         frequency             [(  1, return defaultParams)-            ,(100, return . fromJust $ scryptParams logN r p)+            ,(100, return . fromJust $ scryptParamsLen logN r p bufLen)             ]  instance Arbitrary Pass where