úÎ!ãwÝOQ      !"#$%&'()*+,-./0123456789:;<=>?@ABCDEFGHIJKLMNOP.(c) Dennis Gosnell, 2019; Felix Paulusma, 2020BSD-style (see LICENSE file)cdep.illabout@gmail.com experimentalPOSIXNoneMXÓpasswordUThe result of checking a password against a hashed version. This is returned by the  checkPassword functions.passwordXThe password check was successful. The plain-text password matches the hashed password. passwordWThe password check failed. The plain-text password does not match the hashed password. passwordA hashed password.zThis represents a password that has been put through a hashing function. The hashed password can be stored in a database. password#A salt used by a hashing algorithm.passwordA plain-text password./This represents a plain-text password that has NOT been hashed.You should be careful with ?. Make sure not to write it to logs or store it in a database.You can construct a  by using the d function or as literal strings together with the OverloadedStrings pragma (or manually, by using Q on a RC). Alternatively, you could also use some of the instances in the  5http://hackage.haskell.org/package/password-instancespassword-instances library.password Construct a password#Generate a random x-byte-long salt.password?This is an unsafe function that shows a password in plain-text.)unsafeShowPassword ("foobar" :: Password)"foobar"+You should generally not use this function.Spassword Converting T to UVpassword Converting U to TWpasswordDecodes a base64 T to a regular X (if possible)YpasswordSame as Z but works on T[passwordSame as \ but works on T]password CAREFUL: ^-ing a  will always print "**PASSWORD**"show ("hello" :: Password)"**PASSWORD**" _SVWY[.(c) Dennis Gosnell, 2019; Felix Paulusma, 2020BSD-style (see LICENSE file)cdep.illabout@gmail.com experimentalPOSIXNone!     (c) Felix Paulusma, 2020BSD-style (see LICENSE file)cdep.illabout@gmail.com experimentalPOSIXNoneL¢passwordPhantom type for bcryptpassword Hash the  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$..."}password<Hash a password with the given cost and also with the given  - instead of generating a random salt. Using  is strongly  disadvised, and  should be used instead. Never use a static salt in production applications!N.B.C: The salt HAS to be 16 bytes or this function will throw an error!"let salt = Salt "abcdefghijklmnop"2hashPasswordWithSalt 10 salt (mkPassword "foobar")^PasswordHash {unPasswordHash = "$2b$10$WUHhXETkX0fnYkrqZU3ta.N8Utt4U77kW4RVbchzgvBvBBEEdCD/u"}(Note that we use an explicit  d in the example above. This is so that the example is reproducible, but in general you should use .  (and ) generates a new   everytime it is called.)passwordHash a password using the bcrypt algorithm with the given cost. The higher the cost, the longer  and î 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 P if you're unsure about the implications that changing the cost brings with it.passwordCheck a  against a   .Returns  on success.let pass = mkPassword "foobar"passHash <- hashPassword passcheckPassword pass passHashPasswordCheckSuccessReturns   if an incorrect  or    is used.-let badpass = mkPassword "incorrect-password"checkPassword badpass passHashPasswordCheckFail:This should always fail if an incorrect password is given.”\(Blind badpass) -> let correctPasswordHash = hashPasswordWithSalt 8 salt "foobar" in checkPassword badpass correctPasswordHash == PasswordCheckFailpasswordGenerate a random 16-byte bcrypt saltpassword}The cost parameter. Should be between 4 and 31 (inclusive). Values which lie outside this range will be adjusted accordingly.password@The salt. MUST be 16 bytes in length or an error will be raised.passwordThe password to be hashed.password#The bcrypt hash in standard format.password}The cost parameter. Should be between 4 and 31 (inclusive). Values which lie outside this range will be adjusted accordingly.passwordThe password to be hashed.password#The bcrypt hash in standard format.    (c) Felix Paulusma, 2020BSD-style (see LICENSE file)cdep.illabout@gmail.com experimentalPOSIXNone"#X_‚ÒpasswordParameters used in the " hashing algorithm.password8Bytes to randomly generate as a unique salt, default is 16Limits are min: 8 , and max:  (2 ^ 32) - 1password+Which variant of Argon2 to use, default is password+Which version of Argon2 to use, default is passwordMemory cost, given in  kibibytes , default is 65536 (i.e. 64MB)Limits are min: 8 *  ', and max is addressing space / 2, or  (2 ^ 32) - 1, whichever is lower.password+Amount of computation realized, default is 2Limits are min: 1 , and max:  (2 ^ 32) - 1 passwordParallelism factor, default is 1Limits are min: 1 , and max:  (2 ^ 24) - 1!password'Output key length in bytes, default is 32Limits are min: 4 , and max:  (2 ^ 32) - 1"passwordPhantom type for Argon2#password Hash the  using the " hash algorithm"hashPassword $ mkPassword "foobar"HPasswordHash {unPasswordHash = "$argon2id$v=19$m=65536,t=2,p=1$...$..."}$passwordDefault parameters for the " algorithm. defaultParams±Argon2Params {argon2Salt = 16, argon2Variant = Argon2id, argon2Version = Version13, argon2MemoryCost = 65536, argon2TimeCost = 2, argon2Parallelism = 1, argon2OutputLength = 32}%passwordHash a password with the given  and also with the given  + instead of a random generated salt using  from . (cf. & ) Using % is strongly  disadvised and & should be used instead. 3Never use a static salt in production applications!N.B.K: 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  d in the example above. This is so that the example is reproducible, but in general you should use #. # generates a new   everytime it is called.)`passwordOnly for internal use&passwordHash a password using the " algorithm with the given .N.B.F: If you have any doubt in your knowledge of cryptography and/or the " algorithm, please just use #.Advice to set the parameters:JFigure out how many threads you can use, choose "parallelism" accordingly.IFigure out how much memory you can use, choose "memory cost" accordingly.Decide on the maximum time xS you can spend on it, choose the largest "time cost" such that it takes less than x/ with your system and other parameter choices.'passwordCheck a  against a   ".Returns  on success.let pass = mkPassword "foobar"passHash <- hashPassword passcheckPassword pass passHashPasswordCheckSuccessReturns   if an incorrect  or   " is used.-let badpass = mkPassword "incorrect-password"checkPassword badpass passHashPasswordCheckFail:This should always fail if an incorrect password is given.\(Blind badpass) -> let correctPasswordHash = hashPasswordWithSalt testParams salt "foobar" in checkPassword badpass correctPasswordHash == PasswordCheckFail(passwordGenerate a random 16-byte Argon2 saltapassword!Makes a letter out of the variantbpassword0Parses the variant parameter in the encoded hashcpassword-Parses the "v=" parameter in the encoded hashdpassword7Makes number for the "v=" parameter in the encoded hash"  !"#$%&'(""# ' &$ !%( (c) Felix Paulusma, 2020BSD-style (see LICENSE file)cdep.illabout@gmail.com experimentalPOSIXNone"#_­!+password6Type of algorithm to use for hashing PBKDF2 passwords.N.B.: , and - are not considered very secure.0passwordParameters used in the 6 hashing algorithm.2password8Bytes to randomly generate as a unique salt, default is 163password/Which algorithm to use for hashing, default is /4passwordRounds to hash, default is 25,0005password'Output key length in bytes, default is 64Limits 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.6passwordPhantom type for PBKDF27password Hash the  using the 6 hash algorithm"hashPassword $ mkPassword "foobar"6PasswordHash {unPasswordHash = "sha512:25000:...:..."}8passwordDefault parameters for the 6 algorithm. defaultParamsrPBKDF2Params {pbkdf2Salt = 16, pbkdf2Algorithm = PBKDF2_SHA512, pbkdf2Iterations = 25000, pbkdf2OutputLength = 64}9passwordHash a password with the given 0 and also with the given  - instead of a randomly generated salt using 2 from 0. (cf. : ) Using 9 is strongly  disadvised and : should be used instead. 3Never 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  d in the example above. This is so that the example is reproducible, but in general you should use 7. 7 (and :) generates a new   everytime it is called.)epasswordOnly for internal use:passwordHash a password using the 6 algorithm with the given 0.N.B.F: If you have any doubt in your knowledge of cryptography and/or the 6 algorithm, please just use 7.;passwordCheck a  against a   6.Returns  on success.let pass = mkPassword "foobar"passHash <- hashPassword passcheckPassword pass passHashPasswordCheckSuccessReturns   if an incorrect  or   6 is used.-let badpass = mkPassword "incorrect-password"checkPassword badpass passHashPasswordCheckFail:This should always fail if an incorrect password is given.\(Blind badpass) -> let correctPasswordHash = hashPasswordWithSalt testParams salt "foobar" in checkPassword badpass correctPasswordHash == PasswordCheckFailfpassword:Depending on the given algorithm limits the output length.<passwordGenerate a random 16-byte PBKDF2 salt +/,-.0123456789:;<67 ; :8012345+/,-.9< .(c) Dennis Gosnell, 2019; Felix Paulusma, 2020BSD-style (see LICENSE file)cdep.illabout@gmail.com experimentalPOSIXNone"#Ü$ApasswordParameters used in the H hashing algorithm.Cpassword8Bytes to randomly generate as a unique salt, default is 32Dpassword#log2(N) rounds to hash, default is 14 (i.e. 2^14 rounds)EpasswordBlock size, default is 8Limits are min: 1 , and max: ,scryptBlockSize * scryptParallelism < 2 ^ 30FpasswordParallelism factor, default is 1Limits are min: 0 , and max: ,scryptBlockSize * scryptParallelism < 2 ^ 30Gpassword'Output key length in bytes, default is 64HpasswordPhantom type for Argon2Ipassword Hash the  using the H hash algorithm"hashPassword $ mkPassword "foobar"0PasswordHash {unPasswordHash = "14|8|1|...|..."}JpasswordDefault parameters for the H algorithm. defaultParamsvScryptParams {scryptSalt = 32, scryptRounds = 14, scryptBlockSize = 8, scryptParallelism = 1, scryptOutputLength = 64}KpasswordHash a password with the given A and also with the given  - instead of a randomly generated salt using C from A . Using K is strongly  disadvised and L should be used instead. 3Never use a static salt in production applications!The resulting  5 has the parameters used to hash it, as well as the   appended to it, separated by |. The input   and resulting   are both base64 encoded.2let salt = Salt "abcdefghijklmnopqrstuvwxyz012345"=hashPasswordWithSalt defaultParams salt (mkPassword "foobar")®PasswordHash {unPasswordHash = "14|8|1|YWJjZGVmZ2hpamtsbW5vcHFyc3R1dnd4eXowMTIzNDU=|nENDaqWBmPKapAqQ3//H0iBImweGjoTqn5SvBS8Mc9FPFbzq6w65maYPZaO+SPamVZRXQjARQ8Y+5rhuDhjIhw=="}(Note that we use an explicit  d in the example above. This is so that the example is reproducible, but in general you should use I. I generates a new   everytime it is called.)gpasswordOnly for internal useLpasswordHash a password using the H algorithm with the given A.N.B.F: If you have any doubt in your knowledge of cryptography and/or the H algorithm, please just use I."Advice for setting the parameters:Memory used is about: (2 ^ D) * E * 128 Increasing E and D+ will increase CPU time and memory used. Increasing FL will increase CPU time. (since this implementation, like most, runs the F+ parameter in sequence, not in parallel)MpasswordCheck a  against a   H.Returns  on success.let pass = mkPassword "foobar"passHash <- hashPassword passcheckPassword pass passHashPasswordCheckSuccessReturns   if an incorrect  or   H is used.-let badpass = mkPassword "incorrect-password"checkPassword badpass passHashPasswordCheckFail:This should always fail if an incorrect password is given.\(Blind badpass) -> let correctPasswordHash = hashPasswordWithSalt testParams salt "foobar" in checkPassword badpass correctPasswordHash == PasswordCheckFailNpasswordGenerate a random 32-byte scrypt salt ABCDEFGHIJKLMNHI M LJABCDEFGKN SafeÝ*hijklmnop             !"#$%&'()*+,-./01123456)789:;;<=>?@A)BCDEFDGHIJKLMNOPQRSTUDVWXDYZ[DY\]^_`a]b]cdefghijk'password-2.0.0.0-3dziCrsvfBKD6APaVXwDIbData.Password.Argon2 Data.PasswordData.Password.BcryptData.Password.PBKDF2Data.Password.ScryptData.Password.InternalPaths_password&cryptonite-0.26-IijLzbS4q70FSbXhABK4XrCrypto.KDF.Argon2Argon2idArgon2iArgon2dVariant Version13 Version10Version PasswordCheckPasswordCheckSuccessPasswordCheckFail PasswordHashunPasswordHashSaltPassword mkPasswordnewSaltunsafeShowPasswordBcrypt hashPasswordhashPasswordWithSalthashPasswordWithParams checkPassword Argon2Params argon2Salt argon2Variant argon2Versionargon2MemoryCostargon2TimeCostargon2Parallelismargon2OutputLengthArgon2 defaultParams$fEqArgon2Params$fShowArgon2ParamsPBKDF2Algorithm PBKDF2_MD5 PBKDF2_SHA1 PBKDF2_SHA256 PBKDF2_SHA512 PBKDF2Params pbkdf2Saltpbkdf2Algorithmpbkdf2Iterationspbkdf2OutputLengthPBKDF2$fEqPBKDF2Algorithm$fShowPBKDF2Algorithm$fEqPBKDF2Params$fShowPBKDF2Params ScryptParams scryptSalt scryptRoundsscryptBlockSizescryptParallelismscryptOutputLengthScrypt$fEqScryptParams$fShowScryptParamsbase Data.String fromStringGHC.BaseStringtoBytes text-1.2.3.1Data.Text.InternalText$memory-0.15.0-BDpL7xANPQtKTtLLiFSTuVData.ByteArray.BytesBytes fromBytesfrom64bytestring-0.10.8.2Data.ByteString.Internal ByteStringreadT Text.ReadreadshowTGHC.Showshow$fShowPasswordShowhashPasswordWithSalt'variantToLetterletterToVariant numToVersion versionToNummaxOutputLengthversion getBinDir getLibDir getDynLibDir getDataDir getLibexecDir getSysconfDirgetDataFileName