h&ZV      !"#$%&'()*+,-./0123456789:;<=>?@ABCDEFGHIJKLMNOPQRSTUVWXYZ[\]^_`abcdefghijklmnopqrstuvwxyz{|}~.(c) Dennis Gosnell, 2019; Felix Paulusma, 2020BSD-style (see LICENSE file)cdep.illabout@gmail.com experimentalPOSIX Safe-Inferred" passwordThe result of checking a password against a hashed version. This is returned by the  checkPassword functions.passwordThe password check was successful. The plain-text password matches the hashed password.passwordThe password check failed. The plain-text password does not match the hashed password.password#Generate a random x-byte-long salt.:{quickCheck $ \w -> ioProperty $ do let i :: Num a => a& i = fromIntegral (w :: Word16) Salt bs <- newSalt i pure $ B.length bs === i:}+++ OK, passed 100 tests.password Converting  to password Converting  to passwordDecodes a base64  to a regular  (if possible)passwordSame as  but works on passwordSame as  but works on password&(UNSAFE) Pad a base64 text to "length  4 == 0" with "="\bs -> let b64 = encodeBase64 bs in unsafePad64 (T.dropWhileEnd (== '=') b64) == b64 (c) Felix Paulusma, 2020BSD-style (see LICENSE file)cdep.illabout@gmail.com experimentalPOSIX Safe-InferredpasswordPhantom 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 let correctPasswordHash = hashPasswordWithSalt 8 salt "foobar" in checkPassword badpass correctPasswordHash == PasswordCheckFailpassword"Extracts the cost parameter as an  from a   let pass = mkPassword "foobar"passHash <- hashPassword pass!extractParams passHash == Just 10TruepasswordGenerate a random 16-byte bcrypt saltpasswordThe cost parameter. Should be between 4 and 31 (inclusive). Values which lie outside this range will be adjusted accordingly.passwordThe 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.passwordThe 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 experimentalPOSIX Safe-Inferred"%&$LpasswordParameters 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"PasswordHash {unPasswordHash = "$argon2id$v=19$m=65536,t=2,p=1$...$..."}%passwordDefault parameters for the # algorithm. defaultParamsArgon2Params {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.: 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  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.: If you have any doubt in your knowledge of cryptography and/or the # algorithm, please just use $.Advice to set the parameters:Figure out how many threads you can use, choose "parallelism" accordingly.Figure out how much memory you can use, choose "memory cost" accordingly.Decide on the maximum time x 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)password Extracts  from a   #.'Returns 'Just Argon2Params' on success.let pass = mkPassword "foobar"passHash <- hashPassword pass,extractParams passHash == Just defaultParamsTruepasswordStrips the given match if it matches and uses the function on the remainder of the given text.*passwordGenerate a random 16-byte Argon2 saltpassword!Makes a letter out of the variantpassword0Parses the variant parameter in the encoded hashpassword-Parses the "v=" parameter in the encoded hashpassword7Makes number for the "v=" parameter in the encoded hash$   !"#$%&'()*$# $ ('%) !"&* (c) Felix Paulusma, 2020BSD-style (see LICENSE file)cdep.illabout@gmail.com experimentalPOSIX Safe-Inferred"%&1-password6Type of algorithm to use for hashing PBKDF2 passwords.N.B.: . and / are not considered very secure.2passwordParameters used in the 8 hashing algorithm.4password8Bytes to randomly generate as a unique salt, default is 165password/Which algorithm to use for hashing, default is 16passwordRounds to hash, default is 25,0007password'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.8passwordPhantom type for PBKDF29password Hash the   using the 8 hash algorithm"hashPassword $ mkPassword "foobar"6PasswordHash {unPasswordHash = "sha512:25000:...:..."}:passwordDefault parameters for the 8 algorithm. defaultParamsPBKDF2Params {pbkdf2Salt = 16, pbkdf2Algorithm = PBKDF2_SHA512, pbkdf2Iterations = 25000, pbkdf2OutputLength = 64};passwordHash a password with the given 2 and also with the given - instead of a randomly generated salt using 4 from 2. (cf. < ) Using ; 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  in the example above. This is so that the example is reproducible, but in general you should use 9. 9 (and <) generates a new  everytime it is called.)passwordOnly for internal use<passwordHash a password using the 8 algorithm with the given 2.N.B.: If you have any doubt in your knowledge of cryptography and/or the 8 algorithm, please just use 9.=passwordCheck a   against a   8.Returns  on success.let pass = mkPassword "foobar"passHash <- hashPassword passcheckPassword pass passHashPasswordCheckSuccessReturns  if an incorrect   or   8 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>password Extracts 2 from a   8.'Returns 'Just PBKDF2Params' on success.let pass = mkPassword "foobar"passHash <- hashPassword pass,extractParams passHash == Just defaultParamsTruepassword:Depending on the given algorithm limits the output length.?passwordGenerate a random 16-byte PBKDF2 salt  -1./023456789:;<=>?8 9 =<:>234567-1./0;? .(c) Dennis Gosnell, 2019; Felix Paulusma, 2020BSD-style (see LICENSE file)cdep.illabout@gmail.com experimentalPOSIX Safe-Inferred"%&?#DpasswordParameters used in the K hashing algorithm.Fpassword8Bytes to randomly generate as a unique salt, default is 32Gpassword#log2(N) rounds to hash, default is 14 (i.e. 2^14 rounds)HpasswordBlock size, default is 8Limits are min: 1 , and max: ,scryptBlockSize * scryptParallelism < 2 ^ 30IpasswordParallelism factor, default is 1Limits are min: 0 , and max: ,scryptBlockSize * scryptParallelism < 2 ^ 30Jpassword'Output key length in bytes, default is 64KpasswordPhantom type for scryptLpassword Hash the   using the K hash algorithm"hashPassword $ mkPassword "foobar"0PasswordHash {unPasswordHash = "14|8|1|...|..."}MpasswordDefault parameters for the K algorithm. defaultParamsScryptParams {scryptSalt = 32, scryptRounds = 14, scryptBlockSize = 8, scryptParallelism = 1, scryptOutputLength = 64}NpasswordHash a password with the given D and also with the given - instead of a randomly generated salt using F from D . Using N is strongly  disadvised and O 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  in the example above. This is so that the example is reproducible, but in general you should use L. L generates a new  everytime it is called.)passwordOnly for internal useOpasswordHash a password using the K algorithm with the given D.N.B.: If you have any doubt in your knowledge of cryptography and/or the K algorithm, please just use L."Advice for setting the parameters:Memory used is about: (2 ^ G) * H * 128 Increasing H and G+ will increase CPU time and memory used. Increasing I will increase CPU time. (since this implementation, like most, runs the I+ parameter in sequence, not in parallel)PpasswordCheck a   against a   K.Returns  on success.let pass = mkPassword "foobar"passHash <- hashPassword passcheckPassword pass passHashPasswordCheckSuccessReturns  if an incorrect   or   K 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 == PasswordCheckFailQpassword Extracts D from a   K.'Returns 'Just ScryptParams' on success.let pass = mkPassword "foobar"passHash <- hashPassword pass,extractParams passHash == Just defaultParamsTrueRpasswordGenerate a random 32-byte scrypt salt  DEFGHIJKLMNOPQRK L POMQDEFGHIJNR ,(c) Hiroto Shioi, 2020; Felix Paulusma, 2020BSD-style (see LICENSE file)cdep.illabout@gmail.com experimentalPOSIX Safe-Inferred"%&V:)UpasswordResult of validating a  .XpasswordPossible reasons for a q to be invalidYpassword Value of s is bigger than t )InvalidLength minimumLength maximumLengthZpassword Value of t is zero or less  MaxLengthBelowZero maximumLength[passwordThe total of the character category amount requirements are higher than the maximum length of the password. (i.e. the  signifies the total of v + u + x + w) >CategoryAmountsAboveMaxLength maximumLength totalRequiredChars\passwordy does not return  for a g that requires at least c characters in the password]passwordPossible reasons for a   to be invalid.^password Length of   is too short._password Length of   is too long.`password 0 does not contain required number of characters.apassword ( contains characters that cannot be usedgpasswordCharacter categorieshpasswordUppercase lettersipasswordLowercase lettersjpasswordSpecial characterskpassword ASCII digitslpasswordPredicate which defines the characters that can be used for a password.opasswordA q" that has been checked to be validppassword#In case you'd want to retrieve the q from the oqpassword#Set of policies used to validate a  .When defining your own q, please keep in mind that: The value of t must be bigger than 0 The value of t must be bigger than s.If any other field has a negative value (e.g. v), it will be defaulted to 0The total sum of all character category values (i.e. all fields ending in -Chars*) must not be larger than the value of t. The provided l needs to allow at least one of the characters in the categories which require more than 0 characters. (e.g. if v is > 0, the y. must allow at least one of the characters in  ['a'..'z'])9or else the validation functions will return one or more Xs.8If you're unsure of what to do, please use the default: |spassword Required password minimum lengthtpassword Required password maximum lengthupassword(Required number of upper-case charactersvpassword(Required number of lower-case characterswpassword%Required number of special charactersxpassword)Required number of ASCII-digit charactersypassword:Which characters are acceptable for use in passwords (cf. })zpasswordAll  fields of the q in a row{passwordDefault value for the q.Enforces that a password must be between 8-64 characters long, though can easily be adjusted by using record update syntax: 7myPolicy = defaultPasswordPolicy{ minimumLength = 12 } ?Do note that this being a default policy doesn't make it a good }|password Unchangeable {, but guaranteed to be valid.}passwordThe default character set consists of uppercase and lowercase letters, numbers, and special characters from the ASCII+ character set. (i.e. everything from the ASCII# set except the control characters)~passwordCheck if given  is a special character. (i.e. any non-alphanumeric non-control ASCII character)password Convert a g' into its associated predicate functionpasswordThis function is equivalent to:  policy password == V2let pass = mkPassword "This_Is_Valid_PassWord1234"+isValidPassword defaultPasswordPolicy_ passTruepasswordChecks if a given   adheres to the provided o.In case of an invalid password, returns the reasons why it wasn't valid.2let pass = mkPassword "This_Is_Valid_Password1234",validatePassword defaultPasswordPolicy_ pass ValidPasswordpassword Validate l to return 5 on at least one of the characters that is required.For instance, if q states that the password requires at least one uppercase letter, then l6 should return True on at least one uppercase letter.password)Template Haskell validation function for qs. -{-# LANGUAGE TemplateHaskell #-} myPolicy :: q myPolicy = {'{ specialChars = 1 } myValidPolicy :: o myValidPolicy = $( myPolicy) For technical reasons, the y field is ignored and the }; is used. If, for any reason, you do need to use a custom l , please use  and either handle the failure case at runtime and/or use a unit test to make sure your policy is valid.passwordVerifies that a q! is valid and converts it into a o.,validatePasswordPolicy defaultPasswordPolicy Right (...)passwordDefault character setShould be all non-control characters in the ASCII character set.password&N.B. This will not check order on the ypassword)N.B. This will not check equality on the y1UVWXYZ[\]^_`abcdefgkhijlmnopqrstuvwxyz{|}~1UVWqrstuvwxyop{|lmn}]^_`aXYZ[\gkhijfedcb~z Safe-InferredV            !"#$$%&'()*+,- !"#./01234556789:- !"#;<=>??@ABCDE- !"#FGHIJKLMNOPQRSTUVWXYZ[\]^__`abccdefghijklmnopqrstuvwxyz{|}~#'password-3.0.2.1-Bts7XZiGUfzFIght463aSxData.Password.Argon2Data.Password.BcryptData.Password.PBKDF2Data.Password.ScryptData.Password.ValidateData.Password.InternalPaths_password&cryptonite-0.30-IZfEazaz9XYH7qnNzjXtaaCrypto.KDF.Argon2Argon2idArgon2iArgon2dVariant Version13 Version10Version-password-types-1.0.0.0-2MhSbjybWB12DfqPPJHolEData.Password.TypesunsafeShowPassword mkPasswordPasswordunPasswordHash PasswordHashgetSaltSalt PasswordCheckPasswordCheckSuccessPasswordCheckFailBcrypt hashPasswordhashPasswordWithSalthashPasswordWithParams checkPassword extractParamsnewSalt Argon2Params argon2Salt argon2Variant argon2Versionargon2MemoryCostargon2TimeCostargon2Parallelismargon2OutputLengthArgon2 defaultParams$fEqArgon2Params$fShowArgon2ParamsPBKDF2Algorithm PBKDF2_MD5 PBKDF2_SHA1 PBKDF2_SHA256 PBKDF2_SHA512 PBKDF2Params pbkdf2Saltpbkdf2Algorithmpbkdf2Iterationspbkdf2OutputLengthPBKDF2$fEqPBKDF2Params$fShowPBKDF2Params$fEqPBKDF2Algorithm$fShowPBKDF2Algorithm ScryptParams scryptSalt scryptRoundsscryptBlockSizescryptParallelismscryptOutputLengthScrypt$fEqScryptParams$fShowScryptParamsValidationResult ValidPasswordInvalidPasswordInvalidPolicyReason InvalidLengthMaxLengthBelowZeroCategoryAmountsAboveMaxLengthInvalidCharSetPredicate InvalidReasonPasswordTooShortPasswordTooLongNotEnoughReqCharsInvalidCharactersProvidedAmount MinimumAmountProvidedLength MaximumLength MinimumLengthCharacterCategory Uppercase LowercaseSpecialDigitCharSetPredicategetCharSetPredicateValidPasswordPolicyfromValidPasswordPolicyPasswordPolicy minimumLength maximumLengthuppercaseCharslowercaseChars specialChars digitCharscharSetPredicate allButCSPdefaultPasswordPolicydefaultPasswordPolicy_defaultCharSetPredicate isSpecialcategoryToPredicateisValidPasswordvalidatePasswordvalidateCharSetPredicatevalidatePasswordPolicyTHvalidatePasswordPolicydefaultCharSet$fShowPasswordPolicy$fOrdPasswordPolicy$fEqPasswordPolicy$fEqValidationResult$fShowValidationResult$fEqInvalidPolicyReason$fOrdInvalidPolicyReason$fShowInvalidPolicyReason$fEqInvalidReason$fOrdInvalidReason$fShowInvalidReason$fEqCharacterCategory$fOrdCharacterCategory$fShowCharacterCategory$fEqValidPasswordPolicy$fOrdValidPasswordPolicy$fShowValidPasswordPolicytoBytes text-1.2.5.0Data.Text.InternalText$memory-0.18.0-6kuxJXXMyNMJRwhOy3Nxc9Data.ByteArray.BytesBytes fromBytesfrom64bytestring-0.11.3.1Data.ByteString.Internal ByteStringreadTbase Text.ReadreadshowTGHC.Showshow unsafePad64GHC.Realremghc-prim GHC.TypesInthashPasswordWithSalt' splitMaybevariantToLetterletterToVariant numToVersion versionToNummaxOutputLengthTrueCharversiongetDataFileName getBinDir getLibDir getDynLibDir getDataDir getLibexecDir getSysconfDir