h*ZV      !"#$%&'()*+,-./0123456789:;<=>?@ABCDEFGHIJKLMNOPQRSTUVWXYZ[\]^_`abcdefghijklmnopqrstuvwxyz{|}~3.0.4.0.(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 "=" (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$..."}passwordDefault parameters for the  algorithm. defaultParams10password 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"%&$ZpasswordParameters 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 0 are not considered very secure.3passwordParameters used in the 9 hashing algorithm.5password8Bytes to randomly generate as a unique salt, default is 166password/Which algorithm to use for hashing, default is 27passwordRounds to hash, default is 25,0008password'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.9passwordPhantom type for PBKDF2:password Hash the   using the 9 hash algorithm"hashPassword $ mkPassword "foobar"6PasswordHash {unPasswordHash = "sha512:25000:...:..."};passwordDefault parameters for the 9 algorithm. defaultParamsPBKDF2Params {pbkdf2Salt = 16, pbkdf2Algorithm = PBKDF2_SHA512, pbkdf2Iterations = 25000, pbkdf2OutputLength = 64}<passwordHash a password with the given 3 and also with the given - instead of a randomly generated salt using 5 from 3. (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 :. : (and =) generates a new  everytime it is called.)passwordOnly for internal use=passwordHash a password using the 9 algorithm with the given 3.N.B.: If you have any doubt in your knowledge of cryptography and/or the 9 algorithm, please just use :.>passwordCheck a   against a   9.Returns  on success.let pass = mkPassword "foobar"passHash <- hashPassword passcheckPassword pass passHashPasswordCheckSuccessReturns  if an incorrect   or   9 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 3 from a   9.'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 salt9 : >=;?345678.2/01<@ 9 : >=;?345678.2/01<@ .(c) Dennis Gosnell, 2019; Felix Paulusma, 2020BSD-style (see LICENSE file)cdep.illabout@gmail.com experimentalPOSIX Safe-Inferred"%&?3EpasswordParameters used in the L hashing algorithm.Gpassword8Bytes to randomly generate as a unique salt, default is 32Hpassword#log2(N) rounds to hash, default is 14 (i.e. 2^14 rounds)IpasswordBlock size, default is 8Limits are min: 1 , and max: ,scryptBlockSize * scryptParallelism < 2 ^ 30JpasswordParallelism factor, default is 1Limits are min: 0 , and max: ,scryptBlockSize * scryptParallelism < 2 ^ 30Kpassword'Output key length in bytes, default is 64LpasswordPhantom type for scryptMpassword Hash the   using the L hash algorithm"hashPassword $ mkPassword "foobar"0PasswordHash {unPasswordHash = "14|8|1|...|..."}NpasswordDefault parameters for the L algorithm. defaultParamsScryptParams {scryptSalt = 32, scryptRounds = 14, scryptBlockSize = 8, scryptParallelism = 1, scryptOutputLength = 64}OpasswordHash a password with the given E and also with the given - instead of a randomly generated salt using G from E . Using O is strongly  disadvised and P 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 M. M generates a new  everytime it is called.)passwordOnly for internal usePpasswordHash a password using the L algorithm with the given E.N.B.: If you have any doubt in your knowledge of cryptography and/or the L algorithm, please just use M."Advice for setting the parameters:Memory used is about: (2 ^ H) * I * 128 Increasing I and H+ will increase CPU time and memory used. Increasing J will increase CPU time. (since this implementation, like most, runs the J+ parameter in sequence, not in parallel)QpasswordCheck a   against a   L.Returns  on success.let pass = mkPassword "foobar"passHash <- hashPassword passcheckPassword pass passHashPasswordCheckSuccessReturns  if an incorrect   or   L 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 == PasswordCheckFailRpassword Extracts E from a   L.'Returns 'Just ScryptParams' on success.let pass = mkPassword "foobar"passHash <- hashPassword pass,extractParams passHash == Just defaultParamsTrueSpasswordGenerate a random 32-byte scrypt saltL M QPNREFGHIJKOS L M QPNREFGHIJKOS ,(c) Hiroto Shioi, 2020; Felix Paulusma, 2020BSD-style (see LICENSE file)cdep.illabout@gmail.com experimentalPOSIX Safe-Inferred"%&VK)VpasswordResult of validating a  .YpasswordPossible reasons for a r to be invalidZpassword Value of t is bigger than u )InvalidLength minimumLength maximumLength[password Value of u 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 w + v + y + x) >CategoryAmountsAboveMaxLength maximumLength totalRequiredChars]passwordz does not return  for a h that requires at least d characters in the password^passwordPossible reasons for a   to be invalid._password Length of   is too short.`password Length of   is too long.apassword 0 does not contain required number of characters.bpassword ( contains characters that cannot be usedhpasswordCharacter categoriesipasswordUppercase lettersjpasswordLowercase letterskpasswordSpecial characterslpassword ASCII digitsmpasswordPredicate which defines the characters that can be used for a password.ppasswordA r" that has been checked to be validqpassword#In case you'd want to retrieve the r from the prpassword#Set of policies used to validate a  .When defining your own r, please keep in mind that: The value of u must be bigger than 0 The value of u must be bigger than t.If any other field has a negative value (e.g. w), 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 u. The provided m needs to allow at least one of the characters in the categories which require more than 0 characters. (e.g. if w is > 0, the z. must allow at least one of the characters in  ['a'..'z'])9or else the validation functions will return one or more Ys.8If you're unsure of what to do, please use the default: }tpassword Required password minimum lengthupassword Required password maximum lengthvpassword(Required number of upper-case characterswpassword(Required number of lower-case charactersxpassword%Required number of special charactersypassword)Required number of ASCII-digit characterszpassword:Which characters are acceptable for use in passwords (cf. ~){passwordAll  fields of the r in a row|passwordDefault value for the r.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 h' into its associated predicate functionpasswordThis function is equivalent to:  policy password == W2let pass = mkPassword "This_Is_Valid_PassWord1234"+isValidPassword defaultPasswordPolicy_ passTruepasswordChecks if a given   adheres to the provided p.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 m to return 5 on at least one of the characters that is required.For instance, if r states that the password requires at least one uppercase letter, then m6 should return True on at least one uppercase letter.password)Template Haskell validation function for rs. -{-# LANGUAGE TemplateHaskell #-} myPolicy :: r myPolicy = |'{ specialChars = 1 } myValidPolicy :: p myValidPolicy = $( myPolicy) For technical reasons, the z field is ignored and the ~; is used. If, for any reason, you do need to use a custom m , 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 r! is valid and converts it into a p.,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 zpassword)N.B. This will not check equality on the z1VWXrstuvwxyzpq|}mno~^_`abYZ[\]hlijkgfedc{1VWXrstuvwxyzpq|}mno~^_`abYZ[\]hlijkgfedc{ Safe-InferredV        !"#$%&&'()*+,-. !"#$%/01234566789:; !"#$%<=>?@@ABCDEF !"#$%GHIJKLMNOPQRSTUVWXYZ[\]^_``abcddefghijklmnopqrstuvwxyz{|}~%'password-3.0.4.0-Hu7xvDs4cPPCCJdwrqTdPMData.Password.Argon2Data.Password.BcryptData.Password.PBKDF2Data.Password.ScryptData.Password.ValidatepasswordData.Password.InternalPaths_password&cryptonite-0.30-AdxcGyxmJWN4yRsYiSmyPdCrypto.KDF.Argon2Version Version10 Version13VariantArgon2dArgon2iArgon2id-password-types-1.0.0.0-9DEWeYUq9W4AyLbwJKxpqUData.Password.TypesSaltgetSalt PasswordHashunPasswordHashPassword mkPasswordunsafeShowPassword PasswordCheckPasswordCheckSuccessPasswordCheckFailBcrypt hashPassword defaultParamshashPasswordWithSalthashPasswordWithParams checkPassword extractParamsnewSalt Argon2Params argon2Salt argon2Variant argon2Versionargon2MemoryCostargon2TimeCostargon2Parallelismargon2OutputLengthArgon2$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-2.0.2Data.Text.InternalText$memory-0.18.0-IRodWJGBsbl80d7UtDNPOJData.ByteArray.BytesBytes fromBytesfrom64bytestring-0.11.5.2Data.ByteString.Internal.Type ByteStringreadTbase Text.ReadreadshowTGHC.Showshow unsafePad64GHC.Realremghc-prim GHC.TypesInthashPasswordWithSalt' splitMaybevariantToLetterletterToVariant numToVersion versionToNummaxOutputLengthTrueCharversion getBinDir getLibDir getDynLibDir getDataDir getLibexecDirgetDataFileName getSysconfDir