ScaffoldBench

RunOpus 5.5repeat 2

Orchestrator-workers on OWASP vs NIST on password hashing

claude-opus-5-5__orchestrator-workers__research-password-hashing__r2

Score

1.000

passed
design ran as designed
Cost
$1.19
+ $0.139 judging
Latency
2m 15s
setup 0.0s, grading 6.4s
Turns
49
Tool calls
43
Subagents
3
Tokens in / out
388k / 26k
297,915 read from cache

Did the design run?

every check held
  • Run completed: heldharness.run-completedThe environment was built, the architecture returned and grading finished, none of them throwing.
  • No API failures: heldharness.apiNo model call failed at the API.
  • Every call ended: heldharness.calls-endedEvery call ended with a result, or was stopped by the run's own limits.
  • No harness tool denied: heldharness.harness-toolsThe sandbox guard never denied a harness tool, nor a tool the session itself offered.
  • Tool servers connected: heldharness.mcp-connectedEvery tool server the harness gave a call was connected when the session started.
  • No foreign tool servers: heldharness.mcp-hermeticNo call loaded a tool server the harness did not give it.
  • Builtin tools: heldharness.builtin-toolsA check recorded with the run.
  • Structured replies arrived: heldharness.structured-outputEvery call that asked for structured output and ran to the end got it.
  • No silent fallbacks: heldharness.not-degradedNo phase fell back on a default (an empty plan, a default winner) instead of its output.
  • Judge answered: heldharness.judgeAt least one grading call returned a usable verdict.
  • The task was decomposed: heldorchestrator-workers.decompositionThe orchestrator’s reply was read through its schema and held at least one subtask.
  • The fan-out happened: heldorchestrator-workers.fan-outEvery subtask got a worker, every worker ran, and the recorded subagent count matches.
  • The synthesis wrote the answer: heldorchestrator-workers.synthesisThe final answer came from the synthesis call, not from a worker’s report standing in for it.
  • Each call was shown the right tools: heldorchestrator-workers.toolsThe orchestrator and the synthesis were shown no tools and every worker the task’s full toolset.

Phases

Decompose: 0.0s to 14.4s, finished, 0 tool calls, $0.035
Worker 1: owasp: 14.4s to 1m 2s, finished, 3 tool calls, $0.190
Worker 2: nist-800-63b: 14.4s to 1m 16s, finished, 15 tool calls, $0.280
Worker 3: fips-kdf: 14.4s to 1m 16s, finished, 25 tool calls, $0.416
Synthesize: 1m 16s to 2m 15s, finished, 0 tool calls, $0.267

Drawn from the phase records: timing and cost per call, no tool calls or messages.

PhaseDurationCostTurnsToolsModel
Decompose14.4s$0.03520claude-opus-5-5
Worker 1: owasp47.7s$0.19043claude-opus-5-5
Worker 2: nist-800-63b1m 1s$0.2801615claude-opus-5-5
Worker 3: fips-kdf1m 2s$0.4162625claude-opus-5-5
Synthesize58.6s$0.26710claude-opus-5-5

The call-by-call replay is not published for this run. Traces are large, so the repository keeps 9 of this run set’s 900 and leaves the rest out; the score, phases and final answer on this page come from the committed run record.

Runs you can replay

Record this cell yourself: npm run bench -- run --strategies orchestrator-workers --tasks research-password-hashing --models claude-opus-5-5 --repeats 1

Score breakdown

  • passStates that OWASP recommends Argon2id first, with a minimum configuration of 19 MiB of memory, an iteration count of 2 and 1 degree of parallelism.
    1.00weight 0.19

    met, backed by verified evidence E1. “**Argon2id.** Minimum 19 MiB of memory, 2 iterations and parallelism 1.”

  • passStates OWASP's alternatives as conditions: scrypt if Argon2id is not available, bcrypt only for legacy systems, and PBKDF2 (at least 600,000 iterations with HMAC-SHA-256) if FIPS-140 compliance is required.
    1.00weight 0.13

    met, backed by verified evidence E2, E3, E4. “**PBKDF2, when FIPS-140 compliance is required.** Use at least 600,000 iterations with HMAC-SHA-256.”

  • passStates that the current NIST SP 800-63B (revision 4) requires passwords to be salted and hashed with a suitable password hashing scheme that takes a cost factor, and says an approved scheme from the latest revision of SP 800-132 (or updated NIST guidelines) SHOULD be used.
    1.00weight 0.19

    met, backed by verified evidence E15, E17, E16. “Passwords must be salted and hashed with a "suitable password hashing scheme." Such a scheme takes a password, a salt and a cost factor.”

  • passStates that the superseded revision 3 named PBKDF2 and Balloon as example key derivation functions and said a memory-hard function SHOULD be used, and that revision 4 no longer contains that wording.
    1.00weight 0.13

    met, backed by verified evidence E26. “It named PBKDF2 and Balloon as examples.”

  • passExplains that for this team the two do not actually conflict: OWASP's own guidance is to use PBKDF2 (HMAC-SHA-256, at least 600,000 iterations) when FIPS-140 compliance is required, and NIST permits PBKDF2, so PBKDF2-HMAC-SHA-256 satisfies both; Argon2id remains OWASP's choice only where FIPS does not apply.
    1.00weight 0.25

    met, backed by verified evidence E4, E5, E17. “The two sources don't really conflict. OWASP itself says to use PBKDF2 when FIPS-140 compliance is required.”

  • passStates at least one requirement both sources share, such as a unique salt for every password or a deliberately expensive hash with a tunable cost (work) factor instead of a fast general-purpose hash.
    1.00weight 0.13

    met, backed by verified evidence E9, E15, E19. “A unique random salt per password, at least 32 bits to satisfy NIST.”

Penalties

No penalties were applied.

Scorer metadata

corpus
{"version":2,"snapshot":"2026-10-01","hash":"e12dc326c69a32d91f85f6355dc63e2a7d672b605685a1ffa1582a42bb1c561e","documents":5}
opened documents
["owasp-password-storage","nist-sp800-63b-4","nist-sp800-63b-3","rfc9106"]
opened by role
{"primary":["owasp-password-storage","nist-sp800-63b-4"],"superseded":["nist-sp800-63b-3"],"secondary":["rfc9106"]}
displayed share
{"owasp-password-storage":1,"nist-sp800-63b-4":0.1576,"nist-sp800-63b-3":0.0544,"owasp-authentication":0.0466,"rfc9106":0.5148}
cited count
4
verified count
4
hallucinated count
0
citation integrity
1
hallucinated urls
[]
evidence block
true
evidence block repaired
false
evidence count
29
verified quote count
29
verified quote rate
1
evidence
[{"url":"https://cheatsheetseries.owasp.org/cheatsheets/Password_Storage_Cheat_Sheet.html","claim":"OWASP's primary recommendation is Argon2id with at least 19 MiB memory, 2 iterations, parallelism 1.","quote":"Use Argon2id with a minimum configuration of 19 MiB of memory, an iteration count of 2, and 1 degree of parallelism.","verified":true,"document":"owasp-password-storage"},{"url":"https://cheatsheetseries.owasp.org/cheatsheets/Password_Storage_Cheat_Sheet.html","claim":"OWASP's second choice is scrypt with N=2^17, r=8, p=1.","quote":"If Argon2id is not available, use scrypt with a minimum CPU/memory cost parameter of (2^17), a minimum block size of 8 (1024 bytes), and a parallelization parameter of 1.","verified":true,"document":"owasp-password-storage"},{"url":"https://cheatsheetseries.owasp.org/cheatsheets/Password_Storage_Cheat_Sheet.html","claim":"OWASP limits bcrypt to legacy systems, with work factor of at least 10 and a 72-byte password limit.","quote":"For legacy systems using bcrypt, use a work factor of 10 or more and with a password limit of 72 bytes.","verified":true,"document":"owasp-password-storage"},{"url":"https://cheatsheetseries.owasp.org/cheatsheets/Password_Storage_Cheat_Sheet.html","claim":"OWASP recommends PBKDF2-HMAC-SHA-256 with at least 600,000 iterations when FIPS-140 compliance is required.","quote":"If FIPS-140 compliance is required, use PBKDF2 with a work factor of 600,000 or more and set with an internal hash function of HMAC-SHA-256.","verified":true,"document":"owasp-password-storage"},{"url":"https://cheatsheetseries.owasp.org/cheatsheets/Password_Storage_Cheat_Sheet.html","claim":"OWASP justifies PBKDF2 by saying it is permitted by SP 800-63B-4 and has FIPS-140 validated implementations.","quote":"Since PBKDF2 is permitted by NIST SP 800-63B-4 and has FIPS-140 validated implementations, it should be the preferred algorithm when these are required.","verified":true,"document":"owasp-password-storage"},{"url":"https://cheatsheetseries.owasp.org/cheatsheets/Password_Storage_Cheat_Sheet.html","claim":"OWASP gives 220,000 iterations for PBKDF2-HMAC-SHA512.","quote":"PBKDF2-HMAC-SHA512: 220,000 iterations","verified":true,"document":"owasp-password-storage"},{"url":"https://cheatsheetseries.owasp.org/cheatsheets/Password_Storage_Cheat_Sheet.html","claim":"OWASP treats PBKDF2-HMAC-SHA1 as legacy only.","quote":"PBKDF2-HMAC-SHA1: 1,400,000 iterations — legacy only, do not select for new systems. NIST SP 800-131A Rev. 2 disallows SHA-1 for new use after 2030.","verified":true,"document":"owasp-password-storage"},{"url":"https://cheatsheetseries.owasp.org/cheatsheets/Password_Storage_Cheat_Sheet.html","claim":"OWASP prescribes a peppered HMAC-SHA384 pre-hash if bcrypt must pre-hash passwords.","quote":"To summarize if bcrypt has to be used and the password should to be pre-hashed you should do bcrypt(base64(hmac-sha384(data:$password, key:$pepper)), $salt, $cost) and store the pepper not in the database.","verified":true,"document":"owasp-password-storage"},{"url":"https://cheatsheetseries.owasp.org/cheatsheets/Password_Storage_Cheat_Sheet.html","claim":"OWASP requires a unique salt per password.","quote":"A unique salt must be added to each password to prevent attackers from using precomputed lookup tables like rainbow tables.","verified":true,"document":"owasp-password-storage"},{"url":"https://cheatsheetseries.owasp.org/cheatsheets/Password_Storage_Cheat_Sheet.html","claim":"OWASP treats a pepper as optional defense in depth.","quote":"Consider using a pepper to provide additional defense in depth (though alone, it provides no additional secure characteristics).","verified":true,"document":"owasp-password-storage"},{"url":"https://cheatsheetseries.owasp.org/cheatsheets/Password_Storage_Cheat_Sheet.html","claim":"OWASP says peppers belong in secrets vaults or HSMs.","quote":"Peppers are secrets and should be stored in \"secrets vaults\" or HSMs (Hardware Security Modules).","verified":true,"document":"owasp-password-storage"},{"url":"https://cheatsheetseries.owasp.org/cheatsheets/Password_Storage_Cheat_Sheet.html","claim":"OWASP's introduction omits scrypt, an internal inconsistency with its detailed sections.","quote":"Instead, they must be protected using strong, slow hashing algorithms such as Argon2id, bcrypt, or PBKDF2.","verified":true,"document":"owasp-password-storage"},{"url":"https://pages.nist.gov/800-63-4/sp800-63b.html","claim":"SP 800-63B Rev 4 supersedes the earlier SP 800-63B.","quote":"This publication supersedes NIST Special Publication (SP) 800-63B.","verified":true,"document":"nist-sp800-63b-4"},{"url":"https://pages.nist.gov/800-63-3/sp800-63b.html","claim":"Rev 3 is marked superseded as of August 1, 2025.","quote":"This revision of NIST SP 800-63 has been superseded by NIST SP 800-63-4 as of August 1, 2025.","verified":true,"document":"nist-sp800-63b-3"},{"url":"https://pages.nist.gov/800-63-4/sp800-63b.html","claim":"Rev 4 requires salted hashing with a suitable password hashing scheme.","quote":"Passwords SHALL be salted and hashed using a suitable password hashing scheme.","verified":true,"document":"nist-sp800-63b-4"},{"url":"https://pages.nist.gov/800-63-4/sp800-63b.html","claim":"Rev 4 says the cost factor should be as high as practical.","quote":"The chosen cost factor SHOULD be as high as practical without negatively impacting verifier performance.","verified":true,"document":"nist-sp800-63b-4"},{"url":"https://pages.nist.gov/800-63-4/sp800-63b.html","claim":"Rev 4 points to SP 800-132 for an approved scheme, as a SHOULD, rather than naming an algorithm.","quote":"An approved password hashing scheme published in the latest revision of [SP800-132] or updated NIST guidelines on password hashing schemes SHOULD be used.","verified":true,"document":"nist-sp800-63b-4"},{"url":"https://pages.nist.gov/800-63-4/sp800-63b.html","claim":"Rev 4 cites SP 800-132 as the 2010 Recommendation for Password-Based Key Derivation.","quote":"[SP800-132] Turan M, Barker E, Burr W, Chen L (2010) Recommendation for Password-Based Key Derivation.","verified":true,"document":"nist-sp800-63b-4"},{"url":"https://pages.nist.gov/800-63-4/sp800-63b.html","claim":"Rev 4 requires a salt of at least 32 bits.","quote":"The salt SHALL be at least 32 bits in length and chosen to minimize salt value collisions among stored hashes (i.e., to prevent multiple subscriber accounts from having the same hashed password).","verified":true,"document":"nist-sp800-63b-4"},{"url":"https://pages.nist.gov/800-63-4/sp800-63b.html","claim":"Rev 4 recommends storing the scheme and cost factor for migration.","quote":"A reference to the password hashing scheme used, including the cost factor, SHOULD be stored for each password to allow migration to new algorithms and work factors.","verified":true,"document":"nist-sp800-63b-4"},{"url":"https://pages.nist.gov/800-63-4/sp800-63b.html","claim":"Rev 4 recommends an additional keyed hash or encryption with a verifier-only secret key.","quote":"In addition, verifiers SHOULD perform an additional iteration of a keyed hashing or encryption operation using a secret key known only to the verifier.","verified":true,"document":"nist-sp800-63b-4"},{"url":"https://pages.nist.gov/800-63-4/sp800-63b.html","claim":"Rev 4 requires the secret key to be stored separately from the hashes.","quote":"The secret key value SHALL be stored separately from the hashed passwords.","verified":true,"document":"nist-sp800-63b-4"},{"url":"https://pages.nist.gov/800-63-4/sp800-63b.html","claim":"Rev 4 recommends keeping the secret key in an HSM or TEE/TPM.","quote":"It SHOULD be stored and used within a hardware-protected area, such as a hardware security module or trusted execution environment (TEE), such as a trusted platform module (TPM).","verified":true,"document":"nist-sp800-63b-4"},{"url":"https://pages.nist.gov/800-63-4/sp800-63b.html","claim":"At AAL1 in general, approved algorithms are required but the implementation need not be FIPS 140 validated.","quote":"In other words, they must use approved algorithms, but the implementation need not be validated under [FIPS140].","verified":true,"document":"nist-sp800-63b-4"},{"url":"https://pages.nist.gov/800-63-4/sp800-63b.html","claim":"Verifiers operated by or for federal agencies must use FIPS 140 Level 1 validated cryptography.","quote":"Cryptography used by verifiers operated by or on behalf of federal agencies at AAL2 SHALL be validated to meet the requirements of [FIPS140] Level 1 unless otherwise specified.","verified":true,"document":"nist-sp800-63b-4"},{"url":"https://pages.nist.gov/800-63-3/sp800-63b.html","claim":"The superseded Rev 3 named PBKDF2 and Balloon as examples.","quote":"Examples of suitable key derivation functions include Password-based Key Derivation Function 2 (PBKDF2) [SP 800-132] and Balloon [BALLOON].","verified":true,"document":"nist-sp800-63b-3"},{"url":"https://pages.nist.gov/800-63-3/sp800-63b.html","claim":"The superseded Rev 3 suggested typically at least 10,000 iterations.","quote":"Therefore, the iteration count SHOULD be as large as verification server performance will allow, typically at least 10,000 iterations.","verified":true,"document":"nist-sp800-63b-3"},{"url":"https://www.rfc-editor.org/rfc/rfc9106.html","claim":"Argon2's RFC 9106 is informational, not a standards-track or NIST specification.","quote":"This document is not an Internet Standards Track specification; it is published for informational purposes.","verified":true,"document":"rfc9106"},{"url":"https://www.rfc-editor.org/rfc/rfc9106.html","claim":"Argon2 is built on BLAKE2b.","quote":"The collision and preimage resistance levels of Argon2 are equivalent to those of the underlying BLAKE2b hash function.","verified":true,"document":"rfc9106"}]
judge unverified quotes
0
judge verdicts
[{"owasp-argon2id":{"status":"met","support":["E1"]},"owasp-conditions":{"status":"met","support":["E2","E3","E4"]},"nist-current":{"status":"met","support":["E15","E17","E16"]},"nist-revision":{"status":"met","support":["E26"]},"reconciliation":{"status":"met","support":["E4","E5","E17"]},"common-ground":{"status":"met","support":["E9","E15","E19"]}},{"owasp-argon2id":{"status":"met","support":["E1"]},"owasp-conditions":{"status":"met","support":["E2","E3","E4"]},"nist-current":{"status":"met","support":["E15","E17","E16"]},"nist-revision":{"status":"met","support":["E26"]},"reconciliation":{"status":"met","support":["E4","E5","E17"]},"common-ground":{"status":"met","support":["E9","E15","E19"]}},{"owasp-argon2id":{"status":"met","support":["E1"]},"owasp-conditions":{"status":"met","support":["E2","E3","E4"]},"nist-current":{"status":"met","support":["E15","E17"]},"nist-revision":{"status":"met","support":["E26"]},"reconciliation":{"status":"met","support":["E4","E5","E17"]},"common-ground":{"status":"met","support":["E9","E15","E19"]}}]
judge failures
0
grounded weight share
1

Final answer

Password hashing for a FIPS-bound web service: OWASP vs. NIST SP 800-63B Rev. 4

Short answer: OWASP prefers Argon2id, but it explicitly says to use PBKDF2 when FIPS-140 compliance is required. NIST SP 800-63B Rev. 4 names no algorithm. It requires salted hashing with a cost factor and points to SP 800-132 for approved schemes. For a FIPS-bound service, both lead to PBKDF2-HMAC-SHA-256 inside a FIPS 140-validated module, configured with OWASP's parameters.

What OWASP recommends

The OWASP Password Storage Cheat Sheet (https://cheatsheetseries.owasp.org/cheatsheets/Password_Storage_Cheat_Sheet.html) gives this order of preference:

  1. Argon2id. Minimum 19 MiB of memory, 2 iterations and parallelism 1. The page lists other settings it treats as equally strong, trading CPU against RAM. They range from m=46 MiB with t=1 down to m=7 MiB with t=5.
  2. scrypt, if Argon2id isn't available. Minimum N=2^17 (128 MiB), r=8, p=1.
  3. bcrypt, for legacy systems only. Work factor of at least 10, and as high as the server allows. Enforce a maximum password length of 72 bytes, because most implementations ignore anything longer. If passwords must be pre-hashed for bcrypt, OWASP prescribes bcrypt(base64(hmac-sha384(data:$password, key:$pepper)), $salt, $cost).
  4. PBKDF2, when FIPS-140 compliance is required. Use at least 600,000 iterations with HMAC-SHA-256. The page also gives 220,000 iterations for HMAC-SHA-512. It lists 1,400,000 for HMAC-SHA-1 as "legacy only, do not select for new systems".

OWASP's stated reason for the PBKDF2 choice is that PBKDF2 "is permitted by NIST SP 800-63B-4 and has FIPS-140 validated implementations." It also says HMAC-SHA-256 "is recommended by NIST." These are OWASP's own descriptions of NIST.

Other OWASP guidance on the same page:

  • Every password needs a unique, random salt. Most libraries generate salts automatically.
  • A pepper is optional defence in depth and adds no security on its own. If used, it must be kept apart from the password database, in a secrets vault or HSM.
  • Computing one hash should take less than a second.

The page is slightly inconsistent with itself. Its introduction names only "Argon2id, bcrypt, or PBKDF2" and leaves out scrypt. The summary and the detailed sections give the full order above.

What NIST SP 800-63B requires

Current revision. Revision 4 is current. Its page (https://pages.nist.gov/800-63-4/sp800-63b.html) says it supersedes the earlier SP 800-63B. The Rev. 3 page (https://pages.nist.gov/800-63-3/sp800-63b.html) says it was superseded by SP 800-63-4 as of August 1, 2025. Our researchers found no newer revision, but this was checked only on pages.nist.gov because the CSRC pages returned 404.

Password storage rules in Rev. 4 (Sec. 3.1.1.2):

  • Hashing (SHALL): Passwords must be salted and hashed with a "suitable password hashing scheme." Such a scheme takes a password, a salt and a cost factor.
  • Cost factor (SHOULD): It should be as high as practical without hurting verifier performance, and it should be raised over time.
  • Algorithm (SHOULD): Rev. 4 names no algorithm. A full-page search found no "PBKDF2" and no "memory-hard". It says an approved scheme "published in the latest revision of [SP800-132] or updated NIST guidelines on password hashing schemes SHOULD be used." The reference list dates SP 800-132 to 2010 and titles it "Recommendation for Password-Based Key Derivation."
  • Salt (SHALL): At least 32 bits, chosen to minimise collisions between stored hashes.
  • Scheme record (SHOULD): Store a reference to the hashing scheme and its cost factor with each password, so you can migrate later.
  • Pepper (SHOULD, with SHALLs if used): Verifiers should perform an extra keyed hash or encryption step using a secret key known only to the verifier. That key must be stored separately from the hashes. It should be stored and used in protected hardware such as an HSM or a TEE/TPM.

FIPS validation in Rev. 4 (same URL):

  • "Approved" cryptography means FIPS-approved or NIST-recommended.
  • At AAL1, approved algorithms are enough in general and the implementation need not be validated.
  • Verifiers run by or for federal agencies must use cryptography validated to FIPS 140 Level 1, at AAL2 and also at AAL1.

How Rev. 3 differed (superseded, for comparison only):

  • It named PBKDF2 and Balloon as examples.
  • It said a memory-hard function SHOULD be used.
  • It suggested "typically at least 10,000" PBKDF2 iterations.

These points no longer apply under Rev. 4.

How the team should reconcile the two

The two sources don't really conflict. OWASP itself says to use PBKDF2 when FIPS-140 compliance is required. NIST Rev. 4 sends implementers to SP 800-132, which by its title covers password-based key derivation. A federal service also needs FIPS 140-validated cryptography.

The practical choice is therefore:

  • Algorithm: PBKDF2 with HMAC-SHA-256, running inside a FIPS 140-validated cryptographic module.
  • Iterations: At least 600,000, per OWASP. NIST Rev. 4 sets no number and only says "as high as practical," so OWASP's figure satisfies NIST and gives the concrete target.
  • Salt: A unique random salt per password, at least 32 bits to satisfy NIST.
  • Scheme record: Store the algorithm and cost with each hash. This meets NIST's SHOULD and matches OWASP's advice to plan for raising work factors.
  • Pepper: Use a secret key held in an HSM. NIST makes this a SHOULD; OWASP treats it as optional defence in depth.

Argon2id, scrypt and bcrypt are not a fit here. The only Argon2 specification our researchers found, RFC 9106 (https://www.rfc-editor.org/rfc/rfc9106.html), is an informational IRTF document built on BLAKE2b, not a NIST standard. However, no NIST page we retrieved explicitly says Argon2, scrypt or bcrypt are not approved. Their exclusion is an inference from Rev. 4 pointing only to SP 800-132.

Caveats and gaps

  1. OWASP's NIST claims are not directly verified.

    • OWASP says PBKDF2 "is permitted by NIST SP 800-63B-4." Rev. 4 never names PBKDF2; it reaches PBKDF2 only indirectly, through SP 800-132. Only Rev. 3 named PBKDF2 explicitly.
    • OWASP's statements that NIST recommends HMAC-SHA-256 and that SP 800-131A Rev. 2 disallows SHA-1 after 2030 were not checked against NIST.
  2. NIST primary sources could not be retrieved. SP 800-132, SP 800-140C and the CMVP/CAVP pages all returned 404. As a result:

    • We can't quote SP 800-132's own salt, iteration or PRF requirements.
    • We can't say whether SP 800-132 has been revised.
    • We can't confirm from a NIST list that PBKDF2 is an approved security function.

    The team should confirm these, and check that their specific crypto module's FIPS 140 certificate covers PBKDF2.

{"evidence": [
{"claim": "OWASP's primary recommendation is Argon2id with at least 19 MiB memory, 2 iterations, parallelism 1.", "quote": "Use Argon2id with a minimum configuration of 19 MiB of memory, an iteration count of 2, and 1 degree of parallelism.", "url": "https://cheatsheetseries.owasp.org/cheatsheets/Password_Storage_Cheat_Sheet.html"},
{"claim": "OWASP's second choice is scrypt with N=2^17, r=8, p=1.", "quote": "If Argon2id is not available, use scrypt with a minimum CPU/memory cost parameter of (2^17), a minimum block size of 8 (1024 bytes), and a parallelization parameter of 1.", "url": "https://cheatsheetseries.owasp.org/cheatsheets/Password_Storage_Cheat_Sheet.html"},
{"claim": "OWASP limits bcrypt to legacy systems, with work factor of at least 10 and a 72-byte password limit.", "quote": "For legacy systems using bcrypt, use a work factor of 10 or more and with a password limit of 72 bytes.", "url": "https://cheatsheetseries.owasp.org/cheatsheets/Password_Storage_Cheat_Sheet.html"},
{"claim": "OWASP recommends PBKDF2-HMAC-SHA-256 with at least 600,000 iterations when FIPS-140 compliance is required.", "quote": "If FIPS-140 compliance is required, use PBKDF2 with a work factor of 600,000 or more and set with an internal hash function of HMAC-SHA-256.", "url": "https://cheatsheetseries.owasp.org/cheatsheets/Password_Storage_Cheat_Sheet.html"},
{"claim": "OWASP justifies PBKDF2 by saying it is permitted by SP 800-63B-4 and has FIPS-140 validated implementations.", "quote": "Since PBKDF2 is permitted by NIST SP 800-63B-4 and has FIPS-140 validated implementations, it should be the preferred algorithm when these are required.", "url": "https://cheatsheetseries.owasp.org/cheatsheets/Password_Storage_Cheat_Sheet.html"},
{"claim": "OWASP gives 220,000 iterations for PBKDF2-HMAC-SHA512.", "quote": "PBKDF2-HMAC-SHA512: 220,000 iterations", "url": "https://cheatsheetseries.owasp.org/cheatsheets/Password_Storage_Cheat_Sheet.html"},
{"claim": "OWASP treats PBKDF2-HMAC-SHA1 as legacy only.", "quote": "PBKDF2-HMAC-SHA1: 1,400,000 iterations — legacy only, do not select for new systems. NIST SP 800-131A Rev. 2 disallows SHA-1 for new use after 2030.", "url": "https://cheatsheetseries.owasp.org/cheatsheets/Password_Storage_Cheat_Sheet.html"},
{"claim": "OWASP prescribes a peppered HMAC-SHA384 pre-hash if bcrypt must pre-hash passwords.", "quote": "To summarize if bcrypt has to be used and the password should to be pre-hashed you should do bcrypt(base64(hmac-sha384(data:$password, key:$pepper)), $salt, $cost) and store the pepper not in the database.", "url": "https://cheatsheetseries.owasp.org/cheatsheets/Password_Storage_Cheat_Sheet.html"},
{"claim": "OWASP requires a unique salt per password.", "quote": "A unique salt must be added to each password to prevent attackers from using precomputed lookup tables like rainbow tables.", "url": "https://cheatsheetseries.owasp.org/cheatsheets/Password_Storage_Cheat_Sheet.html"},
{"claim": "OWASP treats a pepper as optional defense in depth.", "quote": "Consider using a pepper to provide additional defense in depth (though alone, it provides no additional secure characteristics).", "url": "https://cheatsheetseries.owasp.org/cheatsheets/Password_Storage_Cheat_Sheet.html"},
{"claim": "OWASP says peppers belong in secrets vaults or HSMs.", "quote": "Peppers are secrets and should be stored in \"secrets vaults\" or HSMs (Hardware Security Modules).", "url": "https://cheatsheetseries.owasp.org/cheatsheets/Password_Storage_Cheat_Sheet.html"},
{"claim": "OWASP's introduction omits scrypt, an internal inconsistency with its detailed sections.", "quote": "Instead, they must be protected using strong, slow hashing algorithms such as Argon2id, bcrypt, or PBKDF2.", "url": "https://cheatsheetseries.owasp.org/cheatsheets/Password_Storage_Cheat_Sheet.html"},
{"claim": "SP 800-63B Rev 4 supersedes the earlier SP 800-63B.", "quote": "This publication supersedes NIST Special Publication (SP) 800-63B.", "url": "https://pages.nist.gov/800-63-4/sp800-63b.html"},
{"claim": "Rev 3 is marked superseded as of August 1, 2025.", "quote": "This revision of NIST SP 800-63 has been superseded by NIST SP 800-63-4 as of August 1, 2025.", "url": "https://pages.nist.gov/800-63-3/sp800-63b.html"},
{"claim": "Rev 4 requires salted hashing with a suitable password hashing scheme.", "quote": "Passwords SHALL be salted and hashed using a suitable password hashing scheme.", "url": "https://pages.nist.gov/800-63-4/sp800-63b.html"},
{"claim": "Rev 4 says the cost factor should be as high as practical.", "quote": "The chosen cost factor SHOULD be as high as practical without negatively impacting verifier performance.", "url": "https://pages.nist.gov/800-63-4/sp800-63b.html"},
{"claim": "Rev 4 points to SP 800-132 for an approved scheme, as a SHOULD, rather than naming an algorithm.", "quote": "An approved password hashing scheme published in the latest revision of [SP800-132] or updated NIST guidelines on password hashing schemes SHOULD be used.", "url": "https://pages.nist.gov/800-63-4/sp800-63b.html"},
{"claim": "Rev 4 cites SP 800-132 as the 2010 Recommendation for Password-Based Key Derivation.", "quote": "[SP800-132] Turan M, Barker E, Burr W, Chen L (2010) Recommendation for Password-Based Key Derivation.", "url": "https://pages.nist.gov/800-63-4/sp800-63b.html"},
{"claim": "Rev 4 requires a salt of at least 32 bits.", "quote": "The salt SHALL be at least 32 bits in length and chosen to minimize salt value collisions among stored hashes (i.e., to prevent multiple subscriber accounts from having the same hashed password).", "url": "https://pages.nist.gov/800-63-4/sp800-63b.html"},
{"claim": "Rev 4 recommends storing the scheme and cost factor for migration.", "quote": "A reference to the password hashing scheme used, including the cost factor, SHOULD be stored for each password to allow migration to new algorithms and work factors.", "url": "https://pages.nist.gov/800-63-4/sp800-63b.html"},
{"claim": "Rev 4 recommends an additional keyed hash or encryption with a verifier-only secret key.", "quote": "In addition, verifiers SHOULD perform an additional iteration of a keyed hashing or encryption operation using a secret key known only to the verifier.", "url": "https://pages.nist.gov/800-63-4/sp800-63b.html"},
{"claim": "Rev 4 requires the secret key to be stored separately from the hashes.", "quote": "The secret key value SHALL be stored separately from the hashed passwords.", "url": "https://pages.nist.gov/800-63-4/sp800-63b.html"},
{"claim": "Rev 4 recommends keeping the secret key in an HSM or TEE/TPM.", "quote": "It SHOULD be stored and used within a hardware-protected area, such as a hardware security module or trusted execution environment (TEE), such as a trusted platform module (TPM).", "url": "https://pages.nist.gov/800-63-4/sp800-63b.html"},
{"claim": "At AAL1 in general, approved algorithms are required but the implementation need not be FIPS 140 validated.", "quote": "In other words, they must use approved algorithms, but the implementation need not be validated under [FIPS140].", "url": "https://pages.nist.gov/800-63-4/sp800-63b.html"},
{"claim": "Verifiers operated by or for federal agencies must use FIPS 140 Level 1 validated cryptography.", "quote": "Cryptography used by verifiers operated by or on behalf of federal agencies at AAL2 SHALL be validated to meet the requirements of [FIPS140] Level 1 unless otherwise specified.", "url": "https://pages.nist.gov/800-63-4/sp800-63b.html"},
{"claim": "The superseded Rev 3 named PBKDF2 and Balloon as examples.", "quote": "Examples of suitable key derivation functions include Password-based Key Derivation Function 2 (PBKDF2) [SP 800-132] and Balloon [BALLOON].", "url": "https://pages.nist.gov/800-63-3/sp800-63b.html"},
{"claim": "The superseded Rev 3 suggested typically at least 10,000 iterations.", "quote": "Therefore, the iteration count SHOULD be as large as verification server performance will allow, typically at least 10,000 iterations.", "url": "https://pages.nist.gov/800-63-3/sp800-63b.html"},
{"claim": "Argon2's RFC 9106 is informational, not a standards-track or NIST specification.", "quote": "This document is not an Internet Standards Track specification; it is published for informational purposes.", "url": "https://www.rfc-editor.org/rfc/rfc9106.html"},
{"claim": "Argon2 is built on BLAKE2b.", "quote": "The collision and preimage resistance levels of Argon2 are equivalent to those of the underlying BLAKE2b hash function.", "url": "https://www.rfc-editor.org/rfc/rfc9106.html"}
]}

Provenance of the numbers on this page

run set
scaffold-or-scale-v1
models
Haiku 4.5, Sonnet 5.5, Opus 5.5
effort
high
repeats
2
fixtures
replay
runs
900 / 900
strategy cost
$354.44
judge cost
$9.19
wall clock
9h 48m
git
fce5807b2d

Cost excludes judge calls, which are tracked separately so a scoring model never flatters or penalises an architecture. Every figure on this site is read from results/ at build time.