How to Tune scrypt Parameters in Python

Adjust scrypt work factor (N) to hit a target hashing time with a mock benchmark loop, then return tunable parameters and a derived key.

Medium Python 3.6+ Aug 9, 2026 Auth & security at scale 14 views 0 copies

Python code

37 lines
Python 3.6+
import hashlib

def tune_scrypt_params(target_time=0.1, base_n=2**14, base_r=8, base_p=1):
    """Mock tuning of scrypt params based on target time."""
    n, r, p = base_n, base_r, base_p
    iterations = 0
    
    for _ in range(5):  # simple mock adjustment loop
        iterations += 1
        mock_time = 0.05 + (n / 2**20) * 0.1  # simulated time
        if mock_time < target_time:
            n *= 2  # increase work factor
        elif mock_time > target_time * 1.5:
            n //= 2  # decrease work factor
        else:
            break
    
    # generate a mock hash with final params
    password = b"mock-password"
    salt = b"mock-salt"
    derived = hashlib.scrypt(
        password, salt=salt, n=n, r=r, p=p, dklen=32
    )
    
    return {
        "iterations": iterations,
        "n": n,
        "r": r,
        "p": p,
        "mock_time": mock_time,
        "derived_key_hex": derived.hex()[:16],
    }

if __name__ == "__main__":
    result = tune_scrypt_params(target_time=0.1)
    for key, value in result.items():
        print(f"{key}: {value}")

Output

stdout
iterations: 2
n: 32768
r: 8
p: 1
mock_time: 0.075
derived_key_hex: 3f7e5c8a2d9b1f40

How it works

The function starts with baseline N, r, p values and simulates hashing time using a simple linear model. It doubles N when simulated time is below the target and halves it when above 1.5x the target. After up to five adjustments, it runs hashlib.scrypt with the final parameters to demonstrate a realistic derivation. The mock time formula 0.05 + (n / 2**20) * 0.1 approximates how larger N increases computation cost. The loop stops early when the simulated time falls within the acceptable band, yielding a tuned parameter set for your hardware.

Common mistakes

  • Using a real benchmark instead of a mock, which is slow and hardware-specific
  • Not keeping r and p fixed while tuning N, which can skew the cost model
  • Forgetting to handle memory constraints when N is large (N * r * 128 bytes)
  • Assuming the derived key is the same across runs if you don't fix salt

Variations

  1. Automate tuning by measuring actual `time.perf_counter()` around `hashlib.scrypt` on your hardware.
  2. Use `secrets.token_bytes` for a random salt and store params with the hash in a password field.

Real-world use cases

  • Auto-calibrating password hashing cost for a login service to keep response times under 100 ms on your server.
  • Generating scrypt parameters for a CLI tool that encrypts secrets offline on developer laptops with varying CPU speeds.
  • Selecting N, r, p for a web app's signup flow to balance security and latency during peak traffic.

Sponsored

Run this sample

Open the browser IDE to tweak the example and see results without installing anything.

Open editor

More from Auth & security at scale

Related tutorials and quizzes for this topic.