Skip to content

Conversation

@gregharmon
Copy link

Fixes #9604.

Optimize hash_pbkdf2() in ext/hash by reusing precomputed HMAC contexts instead of rehashing key blocks each round.

Changes

  • Reuse precomputed HMAC inner/outer base contexts in PBKDF2 rounds.
  • Add a copy-based HMAC round helper for the PBKDF2 path.
  • Add SHA-256 PBKDF2 fast path + helper for fixed-size context-final rounds.
  • Add regression vectors in ext/hash/tests/gh9604.phpt.

Behavior

No API or semantic changes intended: validation, return formats, and output bytes are unchanged.

Tests

  • make test TESTS="ext/hash/tests/hash_pbkdf2_basic.phpt ext/hash/tests/hash_pbkdf2_error.phpt ext/hash/tests/gh9604.phpt"
  • make test TESTS="ext/hash/tests"

Benchmark

Setup:

  • hash_pbkdf2('sha256', 'password', 'salt', 200000, 64, false)
  • 9 timed runs/sample via hrtime(true), median reported

Observed on this machine:

  • Before: 135.47 ms median
  • After: 28.28 ms median-of-12 (sample medians 27.68–28.46 ms)
  • Speedup: ~4.79x

Copy link
Member

@TimWolla TimWolla left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Since this is security-sensitive code: Can you please split the individual optimizations into separate commits for ease of review?

  • Migration from float to integer operations to calculate the digest lengths.
  • HMAC context reuse
  • SHA-256 special case
  • CommonCrypto SHA-256 special case
  • Possibly other individually useful migration steps that I missed

@gregharmon
Copy link
Author

Follow-up with exact commit references for easier navigation:

  • 8061c738378 HMAC context reuse in PBKDF2
  • 2a21c6c3a89 SHA-256-specific PBKDF2 fast path
  • 757f645ed82 CommonCrypto SHA-256 path (Apple)
  • daa2d0fb837 float->integer length math

And 068c97e4af7 reverts the previous monolithic commit so the split commits above are cleanly reviewable in this same PR.

@TimWolla TimWolla self-requested a review February 9, 2026 22:07
@gregharmon gregharmon force-pushed the codex/pbkdf2-hmac-context-reuse branch from daa2d0f to 1e94d0b Compare February 9, 2026 22:10
Copy link
Member

@TimWolla TimWolla left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Thank you for splitting the commits. Some more superficial review. I'll need to take a deeper look at the logic when it isn't almost midnight.

@TimWolla TimWolla self-requested a review February 10, 2026 16:50
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Projects

None yet

Development

Successfully merging this pull request may close these issues.

hash_pbkdf2() wastes time by repeatedly hashing the HMAC key blocks

2 participants