1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
| # SPDX-License-Identifier: MIT
|
| from __future__ import annotations
|
| import argparse
| import sys
| import timeit
|
| from . import (
| DEFAULT_HASH_LENGTH,
| DEFAULT_MEMORY_COST,
| DEFAULT_PARALLELISM,
| DEFAULT_TIME_COST,
| PasswordHasher,
| profiles,
| )
|
|
| def main(argv: list[str]) -> None:
| parser = argparse.ArgumentParser(
| description="Benchmark Argon2.",
| formatter_class=argparse.ArgumentDefaultsHelpFormatter,
| )
| parser.add_argument(
| "-n", type=int, default=100, help="Number of iterations to measure."
| )
| parser.add_argument(
| "-t", type=int, help="`time_cost`", default=DEFAULT_TIME_COST
| )
| parser.add_argument(
| "-m", type=int, help="`memory_cost`", default=DEFAULT_MEMORY_COST
| )
| parser.add_argument(
| "-p", type=int, help="`parallelism`", default=DEFAULT_PARALLELISM
| )
| parser.add_argument(
| "-l", type=int, help="`hash_length`", default=DEFAULT_HASH_LENGTH
| )
| parser.add_argument(
| "--profile",
| type=str,
| help="A profile from `argon2.profiles. Takes precedence.",
| default=None,
| )
|
| args = parser.parse_args(argv[1:])
|
| password = b"secret"
| if args.profile:
| ph = PasswordHasher.from_parameters(
| getattr(profiles, args.profile.upper())
| )
| else:
| ph = PasswordHasher(
| time_cost=args.t,
| memory_cost=args.m,
| parallelism=args.p,
| hash_len=args.l,
| )
| hash = ph.hash(password)
|
| print(f"Running Argon2id {args.n} times with:")
|
| for name, value, units in [
| ("hash_len", ph.hash_len, "bytes"),
| ("memory_cost", ph.memory_cost, "KiB"),
| ("parallelism", ph.parallelism, "threads"),
| ("time_cost", ph.time_cost, "iterations"),
| ]:
| print(f"{name}: {value} {units}")
|
| print("\nMeasuring...")
| duration = timeit.timeit(
| f"ph.verify({hash!r}, {password!r})",
| setup=f"""\
| from argon2 import PasswordHasher
|
| ph = PasswordHasher(
| time_cost={args.t!r},
| memory_cost={args.m!r},
| parallelism={args.p!r},
| hash_len={args.l!r},
| )
| gc.enable()""",
| number=args.n,
| )
| print(f"\n{duration / args.n * 1000:.1f}ms per password verification")
|
|
| if __name__ == "__main__": # pragma: no cover
| main(sys.argv)
|
|