-- Hoogle documentation, generated by Haddock -- See Hoogle, http://www.haskell.org/hoogle/ -- | Hashing and checking of passwords -- -- A library providing functionality for working with plain-text and -- hashed passwords with different types of algorithms. @package password @version 2.0.0.1 -- | This library provides an easy way for interacting with passwords from -- Haskell. It provides the types Password and -- PasswordHash, which correspond to plain-text and hashed -- passwords. -- --

API

-- -- Every supported hashing algorithm has its own module (e.g. -- Data.Password.Bcrypt) which exports its own -- hashPassword and checkPassword functions, as well as -- all the types and functions in this module. If you are not sure about -- the specifics of an algorithm you want to use, you can rest assured -- that by using the hashPassword function of the respective -- algorithm you are not making any big mistakes, security-wise. -- -- Of course, if you know what you're doing and you want more -- fine-grained control over the hashing function, you can adjust it -- using the hashPasswordWithParams function of the respective -- algorithm. -- --

Algorithms

-- -- Generally, the most "secure" algorithm is believed to be -- Argon2, then Scrypt, then -- Bcrypt, and lastly PBKDF2. -- Bcrypt and PBKDF2 are the most -- established algorithms, so they have been tried and tested, though -- they both lack a memory cost, and therefore have a greater -- vulnerability to specialized hardware attacks. -- -- When choosing an algorithm, and you have no idea which to pick, just -- go for Bcrypt if your password does not need the -- highest security possible. It's still a fine way for hashing -- passwords, and the cost is easily adjustable if needed. If your needs -- do require stronger protection, you should find someone who can advise -- you on this topic. (And if you're already knowledgeable enough, you -- know what to do) -- --

Special instances

-- -- The real benefit of this module is that there is an accompanying -- password-instances package that provides canonical typeclass -- instances for Password and PasswordHash for many common -- typeclasses, like FromJSON from aeson, -- PersistField from persistent, etc. -- -- See the password-instances package for more information. module Data.Password -- | A plain-text password. -- -- This represents a plain-text password that has NOT been hashed. -- -- You should be careful with Password. Make sure not to write it -- to logs or store it in a database. -- -- You can construct a Password by using the mkPassword -- function or as literal strings together with the OverloadedStrings -- pragma (or manually, by using fromString on a String). -- Alternatively, you could also use some of the instances in the -- password-instances library. data Password -- | Construct a Password mkPassword :: Text -> Password -- | A hashed password. -- -- This represents a password that has been put through a hashing -- function. The hashed password can be stored in a database. newtype PasswordHash a PasswordHash :: Text -> PasswordHash a [unPasswordHash] :: PasswordHash a -> Text -- | The result of checking a password against a hashed version. This is -- returned by the checkPassword functions. data PasswordCheck -- | The password check was successful. The plain-text password matches the -- hashed password. PasswordCheckSuccess :: PasswordCheck -- | The password check failed. The plain-text password does not match the -- hashed password. PasswordCheckFail :: PasswordCheck -- | A salt used by a hashing algorithm. newtype Salt a Salt :: ByteString -> Salt a -- | Generate a random x-byte-long salt. newSalt :: MonadIO m => Int -> m (Salt a) -- | This is an unsafe function that shows a password in plain-text. -- --
--   >>> unsafeShowPassword ("foobar" :: Password)
--   "foobar"
--   
-- -- You should generally not use this function. unsafeShowPassword :: Password -> Text -- |

bcrypt

-- -- The bcrypt algorithm is a popular way of hashing passwords. -- It is based on the Blowfish cipher and fairly straightfoward in its -- usage. It has a cost parameter that, when increased, slows down the -- hashing speed. -- -- It is a straightforward and easy way to get decent protection on -- passwords, it is also been around long enough to be battle-tested and -- generally considered to provide a good amount of security. -- --

Other algorithms

-- -- bcrypt, together with PBKDF2, are only -- computationally intensive. And to protect from specialized hardware, -- new algorithms have been developed that are also resource intensive, -- like Scrypt and Argon2. Not having -- high resource demands, means an attacker with specialized software -- could take less time to brute-force a password, though with the -- default cost (10) and a decently long password, the amount of time to -- brute-force would still be significant. -- -- This the algorithm to use if you're not sure about your needs, but -- just want a decent, proven way to encrypt your passwords. module Data.Password.Bcrypt -- | Phantom type for bcrypt data Bcrypt -- | A plain-text password. -- -- This represents a plain-text password that has NOT been hashed. -- -- You should be careful with Password. Make sure not to write it -- to logs or store it in a database. -- -- You can construct a Password by using the mkPassword -- function or as literal strings together with the OverloadedStrings -- pragma (or manually, by using fromString on a String). -- Alternatively, you could also use some of the instances in the -- password-instances library. data Password -- | Construct a Password mkPassword :: Text -> Password -- | Hash the Password using the bcrypt hash algorithm. -- -- N.B.: bcrypt has a limit of 72 bytes as input, so -- anything longer than that will be cut off at the 72 byte point and -- thus any password that is 72 bytes or longer will match as long as the -- first 72 bytes are the same. -- --
--   >>> hashPassword $ mkPassword "foobar"
--   PasswordHash {unPasswordHash = "$2b$10$..."}
--   
hashPassword :: MonadIO m => Password -> m (PasswordHash Bcrypt) -- | A hashed password. -- -- This represents a password that has been put through a hashing -- function. The hashed password can be stored in a database. newtype PasswordHash a PasswordHash :: Text -> PasswordHash a [unPasswordHash] :: PasswordHash a -> Text -- | Check a Password against a PasswordHash Bcrypt. -- -- Returns PasswordCheckSuccess on success. -- --
--   >>> let pass = mkPassword "foobar"
--   
--   >>> passHash <- hashPassword pass
--   
--   >>> checkPassword pass passHash
--   PasswordCheckSuccess
--   
-- -- Returns PasswordCheckFail if an incorrect Password or -- PasswordHash Bcrypt is used. -- --
--   >>> let badpass = mkPassword "incorrect-password"
--   
--   >>> checkPassword badpass passHash
--   PasswordCheckFail
--   
-- -- This should always fail if an incorrect password is given. -- --
--   \(Blind badpass) -> let correctPasswordHash = hashPasswordWithSalt 8 salt "foobar" in checkPassword badpass correctPasswordHash == PasswordCheckFail
--   
checkPassword :: Password -> PasswordHash Bcrypt -> PasswordCheck -- | The result of checking a password against a hashed version. This is -- returned by the checkPassword functions. data PasswordCheck -- | The password check was successful. The plain-text password matches the -- hashed password. PasswordCheckSuccess :: PasswordCheck -- | The password check failed. The plain-text password does not match the -- hashed password. PasswordCheckFail :: PasswordCheck -- | Hash a password using the bcrypt algorithm with the given cost. -- -- The higher the cost, the longer hashPassword and -- checkPassword will take to run, thus increasing the security, -- but taking longer and taking up more resources. The optimal cost for -- generic user logins would be one that would take between 0.05 - 0.5 -- seconds to check on the machine that will run it. -- -- N.B.: It is advised to use hashPassword if you're unsure -- about the implications that changing the cost brings with it. hashPasswordWithParams :: MonadIO m => Int -> Password -> m (PasswordHash Bcrypt) -- | Hash a password with the given cost and also with the given -- Salt instead of generating a random salt. Using -- hashPasswordWithSalt is strongly disadvised, and -- hashPasswordWithParams should be used instead. Never use a -- static salt in production applications! -- -- N.B.: The salt HAS to be 16 bytes or this function will throw -- an error! -- --
--   >>> let salt = Salt "abcdefghijklmnop"
--   
--   >>> hashPasswordWithSalt 10 salt (mkPassword "foobar")
--   PasswordHash {unPasswordHash = "$2b$10$WUHhXETkX0fnYkrqZU3ta.N8Utt4U77kW4RVbchzgvBvBBEEdCD/u"}
--   
-- -- (Note that we use an explicit Salt in the example above. This -- is so that the example is reproducible, but in general you should use -- hashPassword. hashPassword (and -- hashPasswordWithParams) generates a new Salt everytime -- it is called.) hashPasswordWithSalt :: Int -> Salt Bcrypt -> Password -> PasswordHash Bcrypt -- | Generate a random 16-byte bcrypt salt newSalt :: MonadIO m => m (Salt Bcrypt) -- | A salt used by a hashing algorithm. newtype Salt a Salt :: ByteString -> Salt a -- | This is an unsafe function that shows a password in plain-text. -- --
--   >>> unsafeShowPassword ("foobar" :: Password)
--   "foobar"
--   
-- -- You should generally not use this function. unsafeShowPassword :: Password -> Text -- |

Argon2

-- -- Argon2 is probably the newest password algorithm out there. -- Argon2 was selected as the winner of the Password Hashing Competition -- in July 2015. -- -- It has three variants, namely Argon2d, Argon2i and -- Argon2id. These protect against GPU cracking attacks, -- side-channel attacks, and both, respectively. -- -- All three modes allow specification by three parameters that control: -- -- -- --

Other algorithms

-- -- In comparison to other algorithms, Argon2 is the least -- "battle-tested", being the newest algorithm out there. -- -- It is, however, recommended over Scrypt most of the -- time, and it also seems like it might become the go-to password -- algorithm if no vulnarabilities are discovered within the next couple -- of years. module Data.Password.Argon2 -- | Phantom type for Argon2 data Argon2 -- | A plain-text password. -- -- This represents a plain-text password that has NOT been hashed. -- -- You should be careful with Password. Make sure not to write it -- to logs or store it in a database. -- -- You can construct a Password by using the mkPassword -- function or as literal strings together with the OverloadedStrings -- pragma (or manually, by using fromString on a String). -- Alternatively, you could also use some of the instances in the -- password-instances library. data Password -- | Construct a Password mkPassword :: Text -> Password -- | Hash the Password using the Argon2 hash algorithm -- --
--   >>> hashPassword $ mkPassword "foobar"
--   PasswordHash {unPasswordHash = "$argon2id$v=19$m=65536,t=2,p=1$...$..."}
--   
hashPassword :: MonadIO m => Password -> m (PasswordHash Argon2) -- | A hashed password. -- -- This represents a password that has been put through a hashing -- function. The hashed password can be stored in a database. newtype PasswordHash a PasswordHash :: Text -> PasswordHash a [unPasswordHash] :: PasswordHash a -> Text -- | Check a Password against a PasswordHash Argon2. -- -- Returns PasswordCheckSuccess on success. -- --
--   >>> let pass = mkPassword "foobar"
--   
--   >>> passHash <- hashPassword pass
--   
--   >>> checkPassword pass passHash
--   PasswordCheckSuccess
--   
-- -- Returns PasswordCheckFail if an incorrect Password or -- PasswordHash Argon2 is used. -- --
--   >>> let badpass = mkPassword "incorrect-password"
--   
--   >>> checkPassword badpass passHash
--   PasswordCheckFail
--   
-- -- This should always fail if an incorrect password is given. -- --
--   \(Blind badpass) -> let correctPasswordHash = hashPasswordWithSalt testParams salt "foobar" in checkPassword badpass correctPasswordHash == PasswordCheckFail
--   
checkPassword :: Password -> PasswordHash Argon2 -> PasswordCheck -- | The result of checking a password against a hashed version. This is -- returned by the checkPassword functions. data PasswordCheck -- | The password check was successful. The plain-text password matches the -- hashed password. PasswordCheckSuccess :: PasswordCheck -- | The password check failed. The plain-text password does not match the -- hashed password. PasswordCheckFail :: PasswordCheck -- | Hash a password using the Argon2 algorithm with the given -- Argon2Params. -- -- N.B.: If you have any doubt in your knowledge of cryptography -- and/or the Argon2 algorithm, please just use -- hashPassword. -- -- Advice to set the parameters: -- -- hashPasswordWithParams :: MonadIO m => Argon2Params -> Password -> m (PasswordHash Argon2) -- | Default parameters for the Argon2 algorithm. -- --
--   >>> defaultParams
--   Argon2Params {argon2Salt = 16, argon2Variant = Argon2id, argon2Version = Version13, argon2MemoryCost = 65536, argon2TimeCost = 2, argon2Parallelism = 1, argon2OutputLength = 32}
--   
defaultParams :: Argon2Params -- | Parameters used in the Argon2 hashing algorithm. data Argon2Params Argon2Params :: Word32 -> Variant -> Version -> Word32 -> Word32 -> Word32 -> Word32 -> Argon2Params -- | Bytes to randomly generate as a unique salt, default is 16 -- -- Limits are min: 8, and max: (2 ^ 32) - 1 [argon2Salt] :: Argon2Params -> Word32 -- | Which variant of Argon2 to use, default is Argon2id [argon2Variant] :: Argon2Params -> Variant -- | Which version of Argon2 to use, default is Version13 [argon2Version] :: Argon2Params -> Version -- | Memory cost, given in kibibytes, default is 65536 (i.e. -- 64MB) -- -- Limits are min: 8 * argon2Parallelism, and max is -- addressing space / 2, or (2 ^ 32) - 1, whichever is lower. [argon2MemoryCost] :: Argon2Params -> Word32 -- | Amount of computation realized, default is 2 -- -- Limits are min: 1, and max: (2 ^ 32) - 1 [argon2TimeCost] :: Argon2Params -> Word32 -- | Parallelism factor, default is 1 -- -- Limits are min: 1, and max: (2 ^ 24) - 1 [argon2Parallelism] :: Argon2Params -> Word32 -- | Output key length in bytes, default is 32 -- -- Limits are min: 4, and max: (2 ^ 32) - 1 [argon2OutputLength] :: Argon2Params -> Word32 -- | Which variant of Argon2 to use. You should choose the variant that is -- most applicable to your intention to hash inputs. data Variant -- | Argon2d is faster than Argon2i and uses data-depending memory access, -- which makes it suitable for cryptocurrencies and applications with no -- threats from side-channel timing attacks. Argon2d :: Variant -- | Argon2i uses data-independent memory access, which is preferred for -- password hashing and password-based key derivation. Argon2i is slower -- as it makes more passes over the memory to protect from tradeoff -- attacks. Argon2i :: Variant -- | Argon2id is a hybrid of Argon2i and Argon2d, using a combination of -- data-depending and data-independent memory accesses, which gives some -- of Argon2i's resistance to side-channel cache timing attacks and much -- of Argon2d's resistance to GPU cracking attacks Argon2id :: Variant -- | Which version of Argon2 to use data Version Version10 :: Version Version13 :: Version -- | Hash a password with the given Argon2Params and also with the -- given Salt instead of a random generated salt using -- argon2Salt from Argon2Params. (cf. -- hashPasswordWithParams) Using hashPasswordWithSalt is -- strongly disadvised and hashPasswordWithParams should be -- used instead. Never use a static salt in production -- applications! -- -- N.B.: The salt HAS to be 8 bytes or more, or this function will -- throw an error! -- --
--   >>> let salt = Salt "abcdefghijklmnop"
--   
--   >>> hashPasswordWithSalt defaultParams salt (mkPassword "foobar")
--   PasswordHash {unPasswordHash = "$argon2id$v=19$m=65536,t=2,p=1$YWJjZGVmZ2hpamtsbW5vcA==$BztdyfEefG5V18ZNlztPrfZaU5duVFKZiI6dJeWht0o="}
--   
-- -- (Note that we use an explicit Salt in the example above. This -- is so that the example is reproducible, but in general you should use -- hashPassword. hashPassword generates a new Salt -- everytime it is called.) hashPasswordWithSalt :: Argon2Params -> Salt Argon2 -> Password -> PasswordHash Argon2 -- | Generate a random 16-byte Argon2 salt newSalt :: MonadIO m => m (Salt Argon2) -- | A salt used by a hashing algorithm. newtype Salt a Salt :: ByteString -> Salt a -- | This is an unsafe function that shows a password in plain-text. -- --
--   >>> unsafeShowPassword ("foobar" :: Password)
--   "foobar"
--   
-- -- You should generally not use this function. unsafeShowPassword :: Password -> Text instance GHC.Show.Show Data.Password.Argon2.Argon2Params instance GHC.Classes.Eq Data.Password.Argon2.Argon2Params -- |

PBKDF2

-- -- The PBKDF2 algorithm is one of the oldest and most solid password -- algorithms out there. It has also, however, been shown to be the least -- secure out of all major password algorithms. The main reason for this -- is that is doesn't make use of any memory cost or other method of -- making it difficult for specialized hardware attacks, like GPU -- cracking attacks. -- -- It is still, however used all over the world, since it has been shown -- to be a very reliable way to encrypt passwords. Though it is most -- definitely better than trying to develop a password algorithm on your -- own, or god-forbid, not using any encryption on your stored -- passwords. -- --

Other algorithms

-- -- Seeing as PBKDF2 is shown to be very weak in terms of protection -- against GPU cracking attacks, it is generally advised to go with -- Bcrypt, if not Scrypt or -- Argon2. When unsure, Bcrypt would -- probably be the safest option, as it has no memory cost which could -- become a problem if not properly calibrated to the machine doing the -- password verifications. module Data.Password.PBKDF2 -- | Phantom type for PBKDF2 data PBKDF2 -- | A plain-text password. -- -- This represents a plain-text password that has NOT been hashed. -- -- You should be careful with Password. Make sure not to write it -- to logs or store it in a database. -- -- You can construct a Password by using the mkPassword -- function or as literal strings together with the OverloadedStrings -- pragma (or manually, by using fromString on a String). -- Alternatively, you could also use some of the instances in the -- password-instances library. data Password -- | Construct a Password mkPassword :: Text -> Password -- | Hash the Password using the PBKDF2 hash algorithm -- --
--   >>> hashPassword $ mkPassword "foobar"
--   PasswordHash {unPasswordHash = "sha512:25000:...:..."}
--   
hashPassword :: MonadIO m => Password -> m (PasswordHash PBKDF2) -- | A hashed password. -- -- This represents a password that has been put through a hashing -- function. The hashed password can be stored in a database. newtype PasswordHash a PasswordHash :: Text -> PasswordHash a [unPasswordHash] :: PasswordHash a -> Text -- | Check a Password against a PasswordHash PBKDF2. -- -- Returns PasswordCheckSuccess on success. -- --
--   >>> let pass = mkPassword "foobar"
--   
--   >>> passHash <- hashPassword pass
--   
--   >>> checkPassword pass passHash
--   PasswordCheckSuccess
--   
-- -- Returns PasswordCheckFail if an incorrect Password or -- PasswordHash PBKDF2 is used. -- --
--   >>> let badpass = mkPassword "incorrect-password"
--   
--   >>> checkPassword badpass passHash
--   PasswordCheckFail
--   
-- -- This should always fail if an incorrect password is given. -- --
--   \(Blind badpass) -> let correctPasswordHash = hashPasswordWithSalt testParams salt "foobar" in checkPassword badpass correctPasswordHash == PasswordCheckFail
--   
checkPassword :: Password -> PasswordHash PBKDF2 -> PasswordCheck -- | The result of checking a password against a hashed version. This is -- returned by the checkPassword functions. data PasswordCheck -- | The password check was successful. The plain-text password matches the -- hashed password. PasswordCheckSuccess :: PasswordCheck -- | The password check failed. The plain-text password does not match the -- hashed password. PasswordCheckFail :: PasswordCheck -- | Hash a password using the PBKDF2 algorithm with the given -- PBKDF2Params. -- -- N.B.: If you have any doubt in your knowledge of cryptography -- and/or the PBKDF2 algorithm, please just use -- hashPassword. hashPasswordWithParams :: MonadIO m => PBKDF2Params -> Password -> m (PasswordHash PBKDF2) -- | Default parameters for the PBKDF2 algorithm. -- --
--   >>> defaultParams
--   PBKDF2Params {pbkdf2Salt = 16, pbkdf2Algorithm = PBKDF2_SHA512, pbkdf2Iterations = 25000, pbkdf2OutputLength = 64}
--   
defaultParams :: PBKDF2Params -- | Parameters used in the PBKDF2 hashing algorithm. data PBKDF2Params PBKDF2Params :: Word32 -> PBKDF2Algorithm -> Word32 -> Word32 -> PBKDF2Params -- | Bytes to randomly generate as a unique salt, default is 16 [pbkdf2Salt] :: PBKDF2Params -> Word32 -- | Which algorithm to use for hashing, default is -- PBKDF2_SHA512 [pbkdf2Algorithm] :: PBKDF2Params -> PBKDF2Algorithm -- | Rounds to hash, default is 25,000 [pbkdf2Iterations] :: PBKDF2Params -> Word32 -- | Output key length in bytes, default is 64 -- -- Limits are min: 1, max: the amount of entropy of the hashing -- algorithm. This is limited automatically to 16, 20, 32, 64 -- for MD5, SHA1, SHA256, SHA512, respectively. [pbkdf2OutputLength] :: PBKDF2Params -> Word32 -- | Type of algorithm to use for hashing PBKDF2 passwords. -- -- N.B.: PBKDF2_MD5 and PBKDF2_SHA1 are not considered very -- secure. data PBKDF2Algorithm PBKDF2_MD5 :: PBKDF2Algorithm PBKDF2_SHA1 :: PBKDF2Algorithm PBKDF2_SHA256 :: PBKDF2Algorithm PBKDF2_SHA512 :: PBKDF2Algorithm -- | Hash a password with the given PBKDF2Params and also with the -- given Salt instead of a randomly generated salt using -- pbkdf2Salt from PBKDF2Params. (cf. -- hashPasswordWithParams) Using hashPasswordWithSalt is -- strongly disadvised and hashPasswordWithParams should be -- used instead. Never use a static salt in production -- applications! -- --
--   >>> let salt = Salt "abcdefghijklmnop"
--   
--   >>> hashPasswordWithSalt defaultParams salt (mkPassword "foobar")
--   PasswordHash {unPasswordHash = "sha512:25000:YWJjZGVmZ2hpamtsbW5vcA==:JRElYYrOMe9OIV4LDxaLTgO9ho8fFBVofXoQcdngi7AcuH6Amvmlj2B0y6y1UtQciXXBepSCS+rpy8/vDDQvoA=="}
--   
-- -- (Note that we use an explicit Salt in the example above. This -- is so that the example is reproducible, but in general you should use -- hashPassword. hashPassword (and -- hashPasswordWithParams) generates a new Salt everytime -- it is called.) hashPasswordWithSalt :: PBKDF2Params -> Salt PBKDF2 -> Password -> PasswordHash PBKDF2 -- | Generate a random 16-byte PBKDF2 salt newSalt :: MonadIO m => m (Salt PBKDF2) -- | A salt used by a hashing algorithm. newtype Salt a Salt :: ByteString -> Salt a -- | This is an unsafe function that shows a password in plain-text. -- --
--   >>> unsafeShowPassword ("foobar" :: Password)
--   "foobar"
--   
-- -- You should generally not use this function. unsafeShowPassword :: Password -> Text instance GHC.Show.Show Data.Password.PBKDF2.PBKDF2Params instance GHC.Classes.Eq Data.Password.PBKDF2.PBKDF2Params instance GHC.Show.Show Data.Password.PBKDF2.PBKDF2Algorithm instance GHC.Classes.Eq Data.Password.PBKDF2.PBKDF2Algorithm -- |

scrypt

-- -- The scrypt algorithm is a fairly new one. First published in -- 2009, but published by the IETF in 2016 as RFC 7914. Originally -- used for the Tarsnap backup service, it is designed to be costly by -- requiring large amounts of memory. -- --

Other algorithms

-- -- scrypt does increase the memory requirement in contrast to -- Bcrypt and PBKDF2, but it turns out it -- is not as optimal as it could be, and thus others have set out to -- search for other algorithms that do fulfill on their promises. -- Argon2 seems to be the winner in that search. -- -- That is not to say using scrypt somehow means your passwords -- won't be properly protected. The cryptography is sound and thus is -- fine for protection against brute-force attacks. Because of the memory -- cost, it is generally advised to use Bcrypt if you're -- not sure this might be a problem on your system. module Data.Password.Scrypt -- | Phantom type for Argon2 data Scrypt -- | A plain-text password. -- -- This represents a plain-text password that has NOT been hashed. -- -- You should be careful with Password. Make sure not to write it -- to logs or store it in a database. -- -- You can construct a Password by using the mkPassword -- function or as literal strings together with the OverloadedStrings -- pragma (or manually, by using fromString on a String). -- Alternatively, you could also use some of the instances in the -- password-instances library. data Password -- | Construct a Password mkPassword :: Text -> Password -- | Hash the Password using the Scrypt hash algorithm -- --
--   >>> hashPassword $ mkPassword "foobar"
--   PasswordHash {unPasswordHash = "14|8|1|...|..."}
--   
hashPassword :: MonadIO m => Password -> m (PasswordHash Scrypt) -- | A hashed password. -- -- This represents a password that has been put through a hashing -- function. The hashed password can be stored in a database. newtype PasswordHash a PasswordHash :: Text -> PasswordHash a [unPasswordHash] :: PasswordHash a -> Text -- | Check a Password against a PasswordHash Scrypt. -- -- Returns PasswordCheckSuccess on success. -- --
--   >>> let pass = mkPassword "foobar"
--   
--   >>> passHash <- hashPassword pass
--   
--   >>> checkPassword pass passHash
--   PasswordCheckSuccess
--   
-- -- Returns PasswordCheckFail if an incorrect Password or -- PasswordHash Scrypt is used. -- --
--   >>> let badpass = mkPassword "incorrect-password"
--   
--   >>> checkPassword badpass passHash
--   PasswordCheckFail
--   
-- -- This should always fail if an incorrect password is given. -- --
--   \(Blind badpass) -> let correctPasswordHash = hashPasswordWithSalt testParams salt "foobar" in checkPassword badpass correctPasswordHash == PasswordCheckFail
--   
checkPassword :: Password -> PasswordHash Scrypt -> PasswordCheck -- | The result of checking a password against a hashed version. This is -- returned by the checkPassword functions. data PasswordCheck -- | The password check was successful. The plain-text password matches the -- hashed password. PasswordCheckSuccess :: PasswordCheck -- | The password check failed. The plain-text password does not match the -- hashed password. PasswordCheckFail :: PasswordCheck -- | Hash a password using the Scrypt algorithm with the given -- ScryptParams. -- -- N.B.: If you have any doubt in your knowledge of cryptography -- and/or the Scrypt algorithm, please just use -- hashPassword. -- -- Advice for setting the parameters: -- -- hashPasswordWithParams :: MonadIO m => ScryptParams -> Password -> m (PasswordHash Scrypt) -- | Default parameters for the Scrypt algorithm. -- --
--   >>> defaultParams
--   ScryptParams {scryptSalt = 32, scryptRounds = 14, scryptBlockSize = 8, scryptParallelism = 1, scryptOutputLength = 64}
--   
defaultParams :: ScryptParams -- | Parameters used in the Scrypt hashing algorithm. data ScryptParams ScryptParams :: Word32 -> Word32 -> Word32 -> Word32 -> Word32 -> ScryptParams -- | Bytes to randomly generate as a unique salt, default is 32 [scryptSalt] :: ScryptParams -> Word32 -- | log2(N) rounds to hash, default is 14 (i.e. 2^14 rounds) [scryptRounds] :: ScryptParams -> Word32 -- | Block size, default is 8 -- -- Limits are min: 1, and max: scryptBlockSize * -- scryptParallelism < 2 ^ 30 [scryptBlockSize] :: ScryptParams -> Word32 -- | Parallelism factor, default is 1 -- -- Limits are min: 0, and max: scryptBlockSize * -- scryptParallelism < 2 ^ 30 [scryptParallelism] :: ScryptParams -> Word32 -- | Output key length in bytes, default is 64 [scryptOutputLength] :: ScryptParams -> Word32 -- | Hash a password with the given ScryptParams and also with the -- given Salt instead of a randomly generated salt using -- scryptSalt from ScryptParams. Using -- hashPasswordWithSalt is strongly disadvised and -- hashPasswordWithParams should be used instead. Never use a -- static salt in production applications! -- -- The resulting PasswordHash has the parameters used to hash it, -- as well as the Salt appended to it, separated by |. -- -- The input Salt and resulting PasswordHash are both -- base64 encoded. -- --
--   >>> let salt = Salt "abcdefghijklmnopqrstuvwxyz012345"
--   
--   >>> hashPasswordWithSalt defaultParams salt (mkPassword "foobar")
--   PasswordHash {unPasswordHash = "14|8|1|YWJjZGVmZ2hpamtsbW5vcHFyc3R1dnd4eXowMTIzNDU=|nENDaqWBmPKapAqQ3//H0iBImweGjoTqn5SvBS8Mc9FPFbzq6w65maYPZaO+SPamVZRXQjARQ8Y+5rhuDhjIhw=="}
--   
-- -- (Note that we use an explicit Salt in the example above. This -- is so that the example is reproducible, but in general you should use -- hashPassword. hashPassword generates a new Salt -- everytime it is called.) hashPasswordWithSalt :: ScryptParams -> Salt Scrypt -> Password -> PasswordHash Scrypt -- | Generate a random 32-byte scrypt salt newSalt :: MonadIO m => m (Salt Scrypt) -- | A salt used by a hashing algorithm. newtype Salt a Salt :: ByteString -> Salt a -- | This is an unsafe function that shows a password in plain-text. -- --
--   >>> unsafeShowPassword ("foobar" :: Password)
--   "foobar"
--   
-- -- You should generally not use this function. unsafeShowPassword :: Password -> Text instance GHC.Show.Show Data.Password.Scrypt.ScryptParams instance GHC.Classes.Eq Data.Password.Scrypt.ScryptParams