defmodule Argon2.Benchmark do @moduledoc """ Benchmarking utilities for Argon2 password hashing. Helps you determine appropriate parameters for your use case by measuring execution time of different configurations. """ @doc """ Runs benchmarks for different Argon2 configurations. ## Examples iex> Argon2.Benchmark.run() Configuration Benchmarks (averaged over 5 runs): OWASP (default): Hash time: 285ms Verify time: 280ms Memory: 19MB Strong: Hash time: 890ms Verify time: 885ms Memory: 65MB Test (unsafe): Hash time: 25ms Verify time: 23ms Memory: 1MB """ def run(rounds \\ 5) do configs = [nil, "strong", "test_unsafe"] password = "benchmark_password123" IO.puts("Configuration Benchmarks (averaged over #{rounds} runs):\n") for config <- configs do {hash_times, verify_times} = measure_times(password, config, rounds) print_results(config || "owasp", hash_times, verify_times) end end defp measure_times(password, config, rounds) do hash_times = for _ <- 1..rounds do {time, hash} = :timer.tc(fn -> Argon2.hash_password(password, config) end) {verify_time, _} = :timer.tc(fn -> Argon2.verify_password(password, hash) end) # Convert to milliseconds {time / 1000, verify_time / 1000} end {hash_avg, verify_avg} = Enum.reduce(hash_times, {0, 0}, fn {h, v}, {ha, va} -> {ha + h / rounds, va + v / rounds} end) {hash_avg, verify_avg} end defp print_results(config, hash_avg, verify_avg) do memory = case config do "owasp" -> 19 "strong" -> 65 "test_unsafe" -> 1 end IO.puts(""" #{String.upcase(config)}: Hash time: #{round(hash_avg)}ms Verify time: #{round(verify_avg)}ms Memory: #{memory}MB """) end end