idnits 2.17.1 draft-ietf-kitten-password-storage-06.txt: Checking boilerplate required by RFC 5378 and the IETF Trust (see https://trustee.ietf.org/license-info): ---------------------------------------------------------------------------- No issues found here. Checking nits according to https://www.ietf.org/id-info/1id-guidelines.txt: ---------------------------------------------------------------------------- == There are 2 instances of lines with non-ascii characters in the document. Checking nits according to https://www.ietf.org/id-info/checklist : ---------------------------------------------------------------------------- No issues found here. Miscellaneous warnings: ---------------------------------------------------------------------------- == The copyright year in the IETF Trust and authors Copyright Line does not match the current year -- The document date (6 April 2021) is 1116 days in the past. Is this intentional? Checking references for intended status: Best Current Practice ---------------------------------------------------------------------------- (See RFCs 3967 and 4897 for information about using normative references to lower-maturity documents in RFCs) ** Downref: Normative reference to an Informational RFC: RFC 4949 == Outdated reference: A later version (-13) exists of draft-irtf-cfrg-argon2-12 Summary: 1 error (**), 0 flaws (~~), 3 warnings (==), 1 comment (--). Run idnits with the --verbose option for more detailed information about the items above. -------------------------------------------------------------------------------- 2 Common Authentication Technology Next Generation S. Whited 3 Internet-Draft 6 April 2021 4 Intended status: Best Current Practice 5 Expires: 8 October 2021 7 Best practices for password hashing and storage 8 draft-ietf-kitten-password-storage-06 10 Abstract 12 This document outlines best practices for handling user passwords and 13 other authenticator secrets in client-server systems making use of 14 SASL. 16 Status of This Memo 18 This Internet-Draft is submitted in full conformance with the 19 provisions of BCP 78 and BCP 79. 21 Internet-Drafts are working documents of the Internet Engineering 22 Task Force (IETF). Note that other groups may also distribute 23 working documents as Internet-Drafts. The list of current Internet- 24 Drafts is at https://datatracker.ietf.org/drafts/current/. 26 Internet-Drafts are draft documents valid for a maximum of six months 27 and may be updated, replaced, or obsoleted by other documents at any 28 time. It is inappropriate to use Internet-Drafts as reference 29 material or to cite them other than as "work in progress." 31 This Internet-Draft will expire on 8 October 2021. 33 Copyright Notice 35 Copyright (c) 2021 IETF Trust and the persons identified as the 36 document authors. All rights reserved. 38 This document is subject to BCP 78 and the IETF Trust's Legal 39 Provisions Relating to IETF Documents (https://trustee.ietf.org/ 40 license-info) in effect on the date of publication of this document. 41 Please review these documents carefully, as they describe your rights 42 and restrictions with respect to this document. Code Components 43 extracted from this document must include Simplified BSD License text 44 as described in Section 4.e of the Trust Legal Provisions and are 45 provided without warranty as described in the Simplified BSD License. 47 Table of Contents 49 1. Introduction . . . . . . . . . . . . . . . . . . . . . . . . 2 50 1.1. Conventions and Terminology . . . . . . . . . . . . . . . 2 51 2. SASL Mechanisms . . . . . . . . . . . . . . . . . . . . . . . 3 52 3. Client Best Practices . . . . . . . . . . . . . . . . . . . . 3 53 3.1. Mechanism Pinning . . . . . . . . . . . . . . . . . . . . 4 54 3.2. Storage . . . . . . . . . . . . . . . . . . . . . . . . . 5 55 4. Server Best Practices . . . . . . . . . . . . . . . . . . . . 5 56 4.1. Additional SASL Requirements . . . . . . . . . . . . . . 5 57 4.2. Storage . . . . . . . . . . . . . . . . . . . . . . . . . 5 58 4.3. Authentication and Rotation . . . . . . . . . . . . . . . 6 59 5. KDF Recommendations . . . . . . . . . . . . . . . . . . . . . 6 60 5.1. Argon2 . . . . . . . . . . . . . . . . . . . . . . . . . 7 61 5.2. Bcrypt . . . . . . . . . . . . . . . . . . . . . . . . . 7 62 5.3. PBKDF2 . . . . . . . . . . . . . . . . . . . . . . . . . 7 63 5.4. Scrypt . . . . . . . . . . . . . . . . . . . . . . . . . 8 64 6. Password Complexity Requirements . . . . . . . . . . . . . . 9 65 7. Internationalization Considerations . . . . . . . . . . . . . 9 66 8. Security Considerations . . . . . . . . . . . . . . . . . . . 10 67 9. IANA Considerations . . . . . . . . . . . . . . . . . . . . . 10 68 10. References . . . . . . . . . . . . . . . . . . . . . . . . . 10 69 10.1. Normative References . . . . . . . . . . . . . . . . . . 10 70 10.2. Informative References . . . . . . . . . . . . . . . . . 11 71 Appendix A. Acknowledgments . . . . . . . . . . . . . . . . . . 13 72 Author's Address . . . . . . . . . . . . . . . . . . . . . . . . 13 74 1. Introduction 76 Following best practices when hashing and storing passwords for use 77 with SASL impacts a great deal more than just a user's identity. It 78 also affects usability, backwards compatibility, and interoperability 79 by determining what authentication and authorization mechanisms can 80 be used. 82 1.1. Conventions and Terminology 84 Various security-related terms are to be understood in the sense 85 defined in [RFC4949]. Some may also be defined in [NISTSP63-3] 86 Appendix A.1 and in [NISTSP132] section 3.1. 88 Throughout this document the term "password" is used to mean any 89 password, passphrase, PIN, or other memorized secret. 91 Other common terms used throughout this document include: 93 Mechanism pinning A security mechanism which allows SASL clients to 94 resist downgrade attacks. Clients that implement mechanism 95 pinning remember the perceived strength of the SASL mechanism used 96 in a previous successful authentication attempt and thereafter 97 only authenticate using mechanisms of equal or higher perceived 98 strength. 100 Pepper A secret added to a password hash like a salt. Unlike a 101 salt, peppers are secret and the same pepper may be reused for 102 many hashed passwords. They MUST NOT be stored alongside the 103 hashed password. 105 Salt In this document salt is used as defined in [RFC4949]. 107 The key words "MUST", "MUST NOT", "REQUIRED", "SHALL", "SHALL NOT", 108 "SHOULD", "SHOULD NOT", "RECOMMENDED", "NOT RECOMMENDED", "MAY", and 109 "OPTIONAL" in this document are to be interpreted as described in BCP 110 14 [RFC2119] [RFC8174] when, and only when, they appear in all 111 capitals, as shown here. 113 2. SASL Mechanisms 115 For clients and servers that support password based authentication 116 using SASL [RFC4422] it is RECOMMENDED that the following mechanisms 117 be implemented: 119 * SCRAM-SHA-256 [RFC7677] 121 * SCRAM-SHA-256-PLUS [RFC7677] 123 System entities SHOULD NOT invent their own mechanisms that have not 124 been standardized by the IETF or another reputable standards body. 125 Similarly, entities MUST NOT implement any mechanism with a usage 126 status of "OBSOLETE", or "LIMITED", or "MUST NOT be used" in the IANA 127 SASL Mechanisms Registry [IANA.sasl.mechanisms]. For example, 128 entities MUST NOT implement DIGEST-MD5 (deprecated in [RFC6331]). 130 The SASL mechanisms discussed in this document do not negotiate a 131 security layer. Because of this a strong security layer such as TLS 132 [RFC8446] MUST be negotiated before SASL mechanisms can be advertised 133 or negotiated. 135 3. Client Best Practices 136 3.1. Mechanism Pinning 138 Clients often maintain a list of preferred SASL mechanisms, generally 139 ordered by perceived strength to enable strong authentication. To 140 prevent downgrade attacks by a malicious actor that has successfully 141 executed an in-the-middle attack on a connection, or compromised a 142 trusted server's configuration, clients SHOULD implement "mechanism 143 pinning". That is, after the first successful authentication with a 144 strong mechanism, clients SHOULD make a record of the authentication 145 and thereafter only advertise and use mechanisms of equal or higher 146 perceived strength. 148 The following mechanisms are ordered by their perceived strength from 149 strongest to weakest with mechanisms of equal strength on the same 150 line. The remainder of this section is merely informative. In 151 particular this example does not imply that mechanisms in this list 152 should or should not be implemented. 154 1. EXTERNAL 156 2. SCRAM-SHA-256-PLUS 158 3. SCRAM-SHA-1-PLUS 160 4. SCRAM-SHA-256 162 5. SCRAM-SHA-1 164 6. PLAIN 166 The EXTERNAL mechanism defined in [RFC4422] appendix A is placed at 167 the top of the list. However, its perceived strength depends on the 168 underlying authentication protocol. In this example, we assume that 169 TLS [RFC8446] services are being used. 171 The channel binding ("-PLUS") variants of SCRAM [RFC5802] are listed 172 above their non-channel binding cousins, but may not always be 173 available depending on the type of channel binding data available to 174 the SASL negotiator. 176 Finally, the PLAIN mechanism sends the username and password in plain 177 text and therefore requires a strong security layer such as TLS for 178 the password to be protected in transit. However, if the server is 179 trusted to know the password PLAIN does allow for the use of a strong 180 key derivation function (KDF) for storing the authentication data at 181 rest and provides for password hash agility. 183 3.2. Storage 185 Clients SHOULD always store authentication secrets in a trusted and 186 encrypted keystore such as the system keystore, or an encrypted store 187 created specifically for the clients use. They SHOULD NOT store 188 authentication secrets as plain text. 190 If clients know that they will only ever authenticate using a 191 mechanism such as SCRAM [RFC5802] where the original password is not 192 needed after the first authentication attempt they SHOULD store the 193 SCRAM bits or the hashed and salted password instead of the original 194 password. However, if backwards compatibility with servers that only 195 support the PLAIN mechanism or other mechanisms that require using 196 the original password is required, clients MAY choose to store the 197 original password so long as an appropriate keystore is used. 199 4. Server Best Practices 201 4.1. Additional SASL Requirements 203 Servers MUST NOT support any mechanism that would require 204 authentication secrets to be stored in such a way that they could be 205 recovered in plain text from the stored information. This includes 206 mechanisms that store authentication secrets using reversable 207 encryption, obsolete hashing mechanisms such as MD5 or hashing 208 mechanisms that are cryptographically secure but designed for speed 209 such as SHA256. 211 4.2. Storage 213 Servers MUST always store passwords only after they have been salted, 214 peppered (if possible with the given authentication mechanism), and 215 hashed using a strong KDF. A distinct salt SHOULD be used for each 216 user, and each SCRAM family supported. Salts SHOULD be generated 217 using a cryptographically secure random number generator. The salt 218 MAY be stored in the same datastore as the password. A pepper stored 219 in the application configuration, or a secure location other than the 220 datastore containing the salts, SHOULD be combined with the password 221 before hashing if possible with the given authentication mechanism. 222 Peppers SHOULD NOT be combined with the salt because the salt is not 223 secret and may appear in the final hash output. 225 The following restrictions MUST be observed when generating salts and 226 peppers: 228 +=======================+==========+ 229 | Parameter | Value | 230 +=======================+==========+ 231 | Minimum Salt Length | 4 bytes | 232 +-----------------------+----------+ 233 | Minimum Pepper Length | 14 bytes | 234 +-----------------------+----------+ 236 Table 1: Common Parameters 238 4.3. Authentication and Rotation 240 When authenticating using PLAIN or similar mechanisms that involve 241 transmitting the original password to the server the password MUST be 242 hashed and compared against the salted and hashed password in the 243 database using a constant time comparison. 245 Each time a password is changed a new random salt MUST be created and 246 the iteration count and pepper (if applicable) MUST be updated to the 247 latest value required by server policy. 249 If a pepper is used, consideration should be taken to ensure that it 250 can be easily rotated. For example, multiple peppers could be 251 stored. New passwords and reset passwords would use the newest 252 pepper and a hash of the pepper using the same KDF that was used on 253 the password could then be stored in the database next to the salt so 254 that future logins can identify which pepper in the list was used. 255 This is just one example, pepper rotation schemes are outside the 256 scope of this document. 258 5. KDF Recommendations 260 When properly configured, the following commonly used KDFs create 261 suitable password hash results for server side storage. The 262 recommendations in this section may change depending on the hardware 263 being used and the security level required for the application. 265 With all KDFs proper tuning is required to ensure that it meets the 266 needs of the specific application or service. For persistent login 267 an iteration count or work factor that adds approximately a quarter 268 of a second to login may be an acceptable tradeoff since logins are 269 relatively rare. By contrast, verification tokens that are generated 270 many times per second may need to use a much lower work factor. 272 5.1. Argon2 274 Argon2 [ARGON2ESP] is the 2015 winner of the Password Hashing 275 Competition and the current OWASP recommendation for password 276 hashing. Security considerations, test vectors, and parameters for 277 tuning argon2 can be found in [I-D.irtf-cfrg-argon2]. The defaults 278 are copied here for easier reference. 280 +==================================+==============+ 281 | Parameter | Value | 282 +==================================+==============+ 283 | Degree of parallelism (p) | 4 | 284 +----------------------------------+--------------+ 285 | Minimum memory size (m) | 2 GiB | 286 +----------------------------------+--------------+ 287 | Minimum number of iterations (t) | 1 | 288 +----------------------------------+--------------+ 289 | Algorithm type (y) | Argon2id (2) | 290 +----------------------------------+--------------+ 291 | Minimum output length | 32 | 292 +----------------------------------+--------------+ 294 Table 2: Argon Parameters 296 5.2. Bcrypt 298 bcrypt [BCRYPT] is a Blowfish-based KDF. 300 +=========================+=======================+ 301 | Parameter | Value | 302 +=========================+=======================+ 303 | Recommended Cost | 12 | 304 +-------------------------+-----------------------+ 305 | Maximum Password Length | 50-72 bytes depending | 306 | | on the implementation | 307 +-------------------------+-----------------------+ 309 Table 3: Bcrypt Parameters 311 5.3. PBKDF2 313 PBKDF2 [RFC8018] is used by the SCRAM [RFC5802] family of SASL 314 mechanisms. 316 +=============================+================================+ 317 | Parameter | Value | 318 +=============================+================================+ 319 | Minimum iteration count (c) | 310,000 | 320 +-----------------------------+--------------------------------+ 321 | Hash | HMAC-SHA256 | 322 +-----------------------------+--------------------------------+ 323 | Output length (dkLen) | min(hLen, 32) (where hLen is | 324 | | the length of the chosen hash) | 325 +-----------------------------+--------------------------------+ 327 Table 4: PBKDF2 Parameters 329 When PBKDF2 is used with HMAC such as in the SCRAM [RFC5802] family 330 of SASL mechanisms the password is pre-hashed if it is longer than 331 the block size of the hash function (hLen, or 64 bytes for SHA-256). 332 Care should be taken to ensure that the implementation of PBKDF2 does 333 this before the iterations, otherwise long hashes may become 334 significantly more expensive than expected, possibly resulting in a 335 Denial-of-Service (DOS). 337 5.4. Scrypt 339 The [SCRYPT] KDF is designed to be memory-hard and sequential memory- 340 hard to prevent against custom hardware based attacks. 342 Security considerations, test vectors, and further notes on tuning 343 scrypt may be found in [RFC7914]. 345 +=======================================+================+ 346 | Parameter | Value | 347 +=======================================+================+ 348 | Minimum CPU/Memory cost parameter (N) | 32768 (N=2^15) | 349 +---------------------------------------+----------------+ 350 | Blocksize (r) | 8 | 351 +---------------------------------------+----------------+ 352 | Parallelization parameter (p) | 1 | 353 +---------------------------------------+----------------+ 354 | Minimum output length (dkLen) | 32 | 355 +---------------------------------------+----------------+ 357 Table 5: Scrypt Parameters 359 6. Password Complexity Requirements 361 Before any other password complexity requirements are checked, the 362 preparation and enforcement steps of the OpaqueString profile of 363 [RFC8265] SHOULD be applied (for more information see the 364 Internationalization Considerations section). Entities SHOULD 365 enforce a minimum length of 8 characters for user passwords. If 366 using a mechanism such as PLAIN where the server performs hashing on 367 the original password, a maximum length between 64 and 128 characters 368 MAY be imposed to prevent denial of service (DoS) attacks. Entities 369 SHOULD NOT apply any other password restrictions. 371 In addition to these password complexity requirements, servers SHOULD 372 maintain a password blocklist and reject attempts by a claimant to 373 use passwords on the blocklist during registration or password reset. 374 The contents of this blocklist are a matter of server policy. Some 375 common recommendations include lists of common passwords that are not 376 otherwise prevented by length requirements, and passwords present in 377 known breaches. 379 7. Internationalization Considerations 381 The PRECIS framework (Preparation, Enforcement, and Comparison of 382 Internationalized Strings) defined in [RFC8264] is used to enforce 383 internationalization rules on strings and to prevent common 384 application security issues arrising from allowing the full range of 385 Unicode codepoints in usernames, passwords, and other identifiers. 386 The OpaqueString profile of [RFC8265] is used in this document to 387 ensure that codepoints in passwords are treated carefully and 388 consistently. This ensures that users typing certain characters on 389 different keyboards that may provide different versions of the same 390 character will still be able to log in. For example, some keyboards 391 may output the full-width version of a character while other 392 keyboards output the half-width version of the same character. The 393 Width Mapping rule of the OpaqueString profile addresses this and 394 ensures that comparison succeeds and the claimant is able to be 395 authenticated. 397 When enforcing a minimum password length the authentication server 398 SHOULD NOT count bytes as single Unicode scalar values may take up 399 many bytes. Similarly, a single emoji may be constructed from many 400 Unicode scalar values, so it may not be appropriate to count scalar 401 values or code points. Instead consider counting the number Grapheme 402 Clusters as defined in [UAX29]. 404 8. Security Considerations 406 This document contains recommendations that are likely to change over 407 time. It should be reviewed regularly to ensure that it remains 408 accurate and up to date. Many of the recommendations in this 409 document were taken from [OWASP.CS.passwords], [NISTSP63b], and 410 [NISTSP132]. 412 The "-PLUS" variants of SCRAM [RFC5802] support channel binding to 413 their underlying security layer, but lack a mechanism for negotiating 414 what type of channel binding to use. In [RFC5802] the tls-unique 415 [RFC5929] channel binding mechanism is specified as the default, and 416 it is therefore likely to be used in most applications that support 417 channel binding. However, in the absence of the TLS extended master 418 secret fix [RFC7627] and the renegotiation indication TLS extension 419 [RFC5746] the tls-unique and tls-server-endpoint channel binding data 420 can be forged by an attacker that can MITM the connection. Before 421 advertising a channel binding SASL mechanism, entities MUST ensure 422 that both the TLS extended master secret fix and the renegotiation 423 indication extension are in place and that the connection has not 424 been renegotiated. 426 For TLS 1.3 [RFC8446] no channel binding types are currently defined. 427 Channel binding SASL mechanisms MUST NOT be advertised or negotiated 428 over a TLS 1.3 channel until such types are defined. 430 9. IANA Considerations 432 This document has no actions for IANA. 434 10. References 436 10.1. Normative References 438 [IANA.sasl.mechanisms] 439 IETF, "Simple Authentication and Security Layer (SASL) 440 Mechanisms", November 2015, 441 . 444 [RFC2119] Bradner, S., "Key words for use in RFCs to Indicate 445 Requirement Levels", BCP 14, RFC 2119, 446 DOI 10.17487/RFC2119, March 1997, 447 . 449 [RFC4949] Shirey, R., "Internet Security Glossary, Version 2", 450 FYI 36, RFC 4949, DOI 10.17487/RFC4949, August 2007, 451 . 453 [RFC5746] Rescorla, E., Ray, M., Dispensa, S., and N. Oskov, 454 "Transport Layer Security (TLS) Renegotiation Indication 455 Extension", RFC 5746, DOI 10.17487/RFC5746, February 2010, 456 . 458 [RFC5929] Altman, J., Williams, N., and L. Zhu, "Channel Bindings 459 for TLS", RFC 5929, DOI 10.17487/RFC5929, July 2010, 460 . 462 [RFC7627] Bhargavan, K., Ed., Delignat-Lavaud, A., Pironti, A., 463 Langley, A., and M. Ray, "Transport Layer Security (TLS) 464 Session Hash and Extended Master Secret Extension", 465 RFC 7627, DOI 10.17487/RFC7627, September 2015, 466 . 468 [RFC8174] Leiba, B., "Ambiguity of Uppercase vs Lowercase in RFC 469 2119 Key Words", BCP 14, RFC 8174, DOI 10.17487/RFC8174, 470 May 2017, . 472 10.2. Informative References 474 [ARGON2ESP] 475 Biryukov, A., Dinu, D., and D. Khovratovich, "Argon2: New 476 Generation of Memory-Hard Functions for Password Hashing 477 and Other Applications", Euro SnP 2016, March 2016, 478 . 480 [BCRYPT] Provos, N. and D. Mazières, "A Future-Adaptable Password 481 Scheme", USENIX 1999 482 https://www.usenix.org/legacy/event/usenix99/provos/ 483 provos.pdf, June 1999. 485 [I-D.irtf-cfrg-argon2] 486 Biryukov, A., Dinu, D., Khovratovich, D., and S. 487 Josefsson, "The memory-hard Argon2 password hash and 488 proof-of-work function", Work in Progress, Internet-Draft, 489 draft-irtf-cfrg-argon2-12, 8 September 2020, 490 . 492 [NISTSP132] 493 Turan, M., Barker, E., Burr, W., and L. Chen, 494 "Recommendation for Password-Based Key Derivation Part 1: 495 Storage Applications", NIST Special Publication SP 496 800-132, DOI 10.6028/NIST.SP.800-132, December 2010, 497 . 500 [NISTSP63-3] 501 Grassi, P., Garcia, M., and J. Fenton, "Digital Identity 502 Guidelines", NIST Special Publication SP 800-63-3, 503 DOI 10.6028/NIST.SP.800-63-3, June 2017, 504 . 507 [NISTSP63b] 508 Grassi, P., Fenton, J., Newton, E., Perlner, R., 509 Regenscheid, A., Burr, W., Richer, J., Lefkovitz, N., 510 Danker, J., Choong, Y., Greene, K., and M. Theofanos, 511 "Digital Identity Guidelines: Authentication and Lifecycle 512 Management", NIST Special Publication SP 800-63b, 513 DOI 10.6028/NIST.SP.800-63b, June 2017, 514 . 517 [OWASP.CS.passwords] 518 Manico, J., Saad, E., Maćkowski, J., and R. Bailey, 519 "Password Storage", OWASP Cheat Sheet Password Storage, 520 April 2020, 521 . 524 [RFC4422] Melnikov, A., Ed. and K. Zeilenga, Ed., "Simple 525 Authentication and Security Layer (SASL)", RFC 4422, 526 DOI 10.17487/RFC4422, June 2006, 527 . 529 [RFC5802] Newman, C., Menon-Sen, A., Melnikov, A., and N. Williams, 530 "Salted Challenge Response Authentication Mechanism 531 (SCRAM) SASL and GSS-API Mechanisms", RFC 5802, 532 DOI 10.17487/RFC5802, July 2010, 533 . 535 [RFC6331] Melnikov, A., "Moving DIGEST-MD5 to Historic", RFC 6331, 536 DOI 10.17487/RFC6331, July 2011, 537 . 539 [RFC7677] Hansen, T., "SCRAM-SHA-256 and SCRAM-SHA-256-PLUS Simple 540 Authentication and Security Layer (SASL) Mechanisms", 541 RFC 7677, DOI 10.17487/RFC7677, November 2015, 542 . 544 [RFC7914] Percival, C. and S. Josefsson, "The scrypt Password-Based 545 Key Derivation Function", RFC 7914, DOI 10.17487/RFC7914, 546 August 2016, . 548 [RFC8018] Moriarty, K., Ed., Kaliski, B., and A. Rusch, "PKCS #5: 549 Password-Based Cryptography Specification Version 2.1", 550 RFC 8018, DOI 10.17487/RFC8018, January 2017, 551 . 553 [RFC8264] Saint-Andre, P. and M. Blanchet, "PRECIS Framework: 554 Preparation, Enforcement, and Comparison of 555 Internationalized Strings in Application Protocols", 556 RFC 8264, DOI 10.17487/RFC8264, October 2017, 557 . 559 [RFC8265] Saint-Andre, P. and A. Melnikov, "Preparation, 560 Enforcement, and Comparison of Internationalized Strings 561 Representing Usernames and Passwords", RFC 8265, 562 DOI 10.17487/RFC8265, October 2017, 563 . 565 [RFC8446] Rescorla, E., "The Transport Layer Security (TLS) Protocol 566 Version 1.3", RFC 8446, DOI 10.17487/RFC8446, August 2018, 567 . 569 [SCRYPT] Percival, C., "Stronger key derivation via sequential 570 memory-hard functions", 571 BSDCan'09 http://www.tarsnap.com/scrypt/scrypt.pdf, May 572 2009. 574 [UAX29] Davis, M. and C. Chapman, "Unicode Text Segmentation", 575 February 2020, . 577 Appendix A. Acknowledgments 579 The author would like to thank the civil servants at the National 580 Institute of Standards and Technology for their work on the Special 581 Publications series. U.S. executive agencies are an undervalued 582 national treasure, and they deserve our thanks. 584 Thanks also to Cameron Paul, Thomas Copeland, Robbie Harwood, Jim 585 Fenton, and Alexey Melnikov for their reviews and suggestions. 587 Author's Address 589 Sam Whited 590 Atlanta, GA 591 United States of America 593 Email: sam@samwhited.com 594 URI: https://blog.samwhited.com/