mirror of
https://github.com/hashcat/hashcat.git
synced 2025-07-22 06:28:16 +00:00
197 lines
8.9 KiB
Plaintext
197 lines
8.9 KiB
Plaintext
Optimal yescrypt configuration.
|
|
|
|
yescrypt is very flexible, but configuring it optimally is complicated.
|
|
Here are some guidelines to simplify near-optimal configuration. We
|
|
start by listing the parameters and their typical values, and then give
|
|
currently recommended parameter sets by use case.
|
|
|
|
|
|
Parameters and their typical values.
|
|
|
|
Set flags (yescrypt flavor) to YESCRYPT_DEFAULTS to use the currently
|
|
recommended flavor. (Other flags values exist for compatibility and for
|
|
specialized cases where you think you know what you're doing.)
|
|
|
|
Set N (block count) based on target memory usage and running time, as
|
|
well as on the value of r (block size in 128 byte units). N must be a
|
|
power of two.
|
|
|
|
Set r (block size) to 8 (so that N is in KiB, which is convenient) or to
|
|
another small value (if more optimal or for fine-tuning of the total
|
|
size and/or running time). Reasonable values for r are from 8 to 96.
|
|
|
|
Set p (parallelism) to 1 meaning no thread-level parallelism within one
|
|
computation of yescrypt. (Use of thread-level parallelism within
|
|
yescrypt makes sense for ROM initialization and for key derivation at
|
|
high memory usage, but usually not for password hashing where
|
|
parallelism is available through concurrent authentication attempts.
|
|
Don't use p > 1 unnecessarily.)
|
|
|
|
Set t (time) to 0 to use the optimal running time for a given memory
|
|
usage. This will allow you to maximize the memory usage (the value of
|
|
N*r) while staying within your running time constraints. (Non-zero t
|
|
makes sense in specialized cases where you can't afford higher memory
|
|
usage but can afford more time.)
|
|
|
|
Set g (upgrades) to 0 because there have been no hash upgrades yet.
|
|
|
|
Set NROM (block count of ROM) to 0 unless you use a ROM (see below).
|
|
NROM must be a power of two.
|
|
|
|
|
|
Password hashing for user authentication, no ROM.
|
|
|
|
Small and fast (memory usage 2 MiB, performance like bcrypt cost 2^5 -
|
|
latency 2-3 ms and throughput 10,000+ per second on a 16-core server):
|
|
|
|
flags = YESCRYPT_DEFAULTS, N = 2048, r = 8, p = 1, t = 0, g = 0, NROM = 0
|
|
|
|
Large and slow (memory usage 16 MiB, performance like bcrypt cost 2^8 -
|
|
latency 10-30 ms and throughput 1000+ per second on a 16-core server):
|
|
|
|
flags = YESCRYPT_DEFAULTS, N = 4096, r = 32, p = 1, t = 0, g = 0, NROM = 0
|
|
|
|
Of course, even heavier and slower settings are possible, if affordable.
|
|
Simply double the value of N as many times as needed. Since N must be a
|
|
power of two, you may use r (in the range of 8 to 32) or/and t (in the
|
|
range of 0 to 2) for fine-tuning the running time, but first bring N to
|
|
the maximum you can afford. If this feels too complicated, just use one
|
|
of the two parameter sets given above (preferably the second) as-is.
|
|
|
|
|
|
Password hashing for user authentication, with ROM.
|
|
|
|
It's similar to the above, except that you need to adjust r, set NROM,
|
|
and initialize the ROM.
|
|
|
|
First decide on a ROM size, such as making it a large portion of your
|
|
dedicated authentication servers' RAM sizes. Since NROM (block count)
|
|
must be a power of two, you might need to choose r (block size) based on
|
|
how your desired ROM size corresponds to a power of two. Also tuning
|
|
for performance on current hardware, you'll likely end up with r in the
|
|
range from slightly below 16 to 32. For example, to use 15/16 of a
|
|
server's 256 GiB RAM as ROM (thus, making it 240 GiB), you could use
|
|
r=15 or r=30. To use 23/24 of a server's 384 GiB RAM as ROM (thus,
|
|
making it 368 GiB), you'd use r=23. Then set NROM to your desired ROM
|
|
size in KiB divided by 128*r. Note that these examples might (or might
|
|
not) be too extreme, leaving little memory for the rest of the system.
|
|
You could as well opt for 7/8 with r=14 or 11/12 with r=11 or r=22.
|
|
|
|
Note that higher r may make placing of ROM in e.g. NVMe flash memory
|
|
instead of in RAM more reasonable (or less unreasonable) than it would
|
|
have been with a lower r. If this is a concern as it relates to
|
|
possible attacks and you do not intend to ever do it defensively, you
|
|
might want to keep r lower (e.g., prefer r=15 over r=30 in the example
|
|
above, even if 30 performs slightly faster).
|
|
|
|
Your adjustments to r, if you deviate from powers of two, will also
|
|
result in weirder memory usage per hash. Like 1.75 MiB at r=14 instead
|
|
of 2 MiB at r=8 that you would have used without a ROM. That's OK.
|
|
|
|
For ROM initialization, which you do with yescrypt_init_shared(), use
|
|
the same r and NROM that you'd later use for password hashing, choose p
|
|
based on your servers' physical and/or logical CPU count (maybe
|
|
considering eventual upgrades as you won't be able to change this later,
|
|
but without going unnecessarily high - e.g., p=28, p=56, or p=112 make
|
|
sense on servers that currently have 28 physical / 56 logical CPUs), and
|
|
set the rest of the parameters to:
|
|
|
|
flags = YESCRYPT_DEFAULTS, N = 0, t = 0, g = 0
|
|
|
|
N is set to 0 because it isn't relevant during ROM initialization (you
|
|
can use different values of N for hashing passwords with the same ROM).
|
|
|
|
To keep the ROM in e.g. SysV shared memory and reuse it across your
|
|
authentication service restarts, you'd need to allocate the memory and
|
|
set the flags to "YESCRYPT_DEFAULTS | YESCRYPT_SHARED_PREALLOCATED".
|
|
|
|
For actual password hashing, you'd use your chosen values for N, r,
|
|
NROM, and set the rest of the parameters to:
|
|
|
|
flags = YESCRYPT_DEFAULTS, p = 1, t = 0, g = 0
|
|
|
|
Note that although you'd use a large p for ROM initialization, you
|
|
should use p=1 for actual password hashing like you would without a ROM.
|
|
|
|
Do not forget to pass the ROM into the actual password hashing (and keep
|
|
r and NROM set accordingly).
|
|
|
|
Since N must be a power of two and r is dependent on ROM size, you may
|
|
use t (in the range of 0 to 2) for fine-tuning the running time, but
|
|
first bring N to the maximum you can afford.
|
|
|
|
If this feels too complicated, or even if it doesn't, please consider
|
|
engaging Openwall for your yescrypt deployment. We'd be happy to help.
|
|
|
|
|
|
Password-based key derivation.
|
|
|
|
(Or rather passphrase-based.)
|
|
|
|
Use settings similar to those for password hashing without a ROM, but
|
|
adjusted for higher memory usage and running time, and optionally with
|
|
thread-level parallelism.
|
|
|
|
Small and fast (memory usage 128 MiB, running time under 100 ms on a
|
|
fast desktop):
|
|
|
|
flags = YESCRYPT_DEFAULTS, N = 32768, r = 32, p = 1, t = 0, g = 0, NROM = 0
|
|
|
|
Large and fast (memory usage 1 GiB, running time under 200 ms on a fast
|
|
quad-core desktop not including memory allocation overhead, under 250 ms
|
|
with the overhead included), but requires build with OpenMP support (or
|
|
otherwise will run as slow as yet be weaker than its p=1 alternative):
|
|
|
|
flags = YESCRYPT_DEFAULTS, N = 262144, r = 32, p = 4, t = 0, g = 0, NROM = 0
|
|
|
|
Large and slower (memory usage 1 GiB, running time under 300 ms on a
|
|
fast quad-core desktop not including memory allocation overhead, under
|
|
350 ms with the overhead included), also requires build with OpenMP
|
|
support (or otherwise will run slower than the p=1 alternative below):
|
|
|
|
flags = YESCRYPT_DEFAULTS, N = 262144, r = 32, p = 4, t = 2, g = 0, NROM = 0
|
|
|
|
Large and slow (memory usage 1 GiB, running time under 600 ms on a fast
|
|
desktop not including memory allocation overhead, under 650 ms with the
|
|
overhead included):
|
|
|
|
flags = YESCRYPT_DEFAULTS, N = 262144, r = 32, p = 1, t = 0, g = 0, NROM = 0
|
|
|
|
Just like with password hashing, even heavier and slower settings are
|
|
possible, if affordable, and you achieve them by adjusting N, r, t in
|
|
the same way and in the same preferred ranges (please see the section on
|
|
password hashing without a ROM, above). Unlike with password hashing,
|
|
it makes some sense to go above t=2 if you expect that your users might
|
|
not be able to afford more memory but can afford more time. However,
|
|
increasing the memory usage provides better protection, and we don't
|
|
recommend forcing your users to wait for more than 1 second as they
|
|
could as well type more characters in that time. If this feels too
|
|
complicated, just use one of the above parameter sets as-is.
|
|
|
|
|
|
Amortization of memory allocation overhead.
|
|
|
|
It takes a significant fraction of yescrypt's total running time to
|
|
allocate memory from the operating system, especially considering that
|
|
the kernel zeroizes the memory before handing it over to your program.
|
|
|
|
Unless you naturally need to compute yescrypt just once per process, you
|
|
may achieve greater efficiency by fully using advanced yescrypt APIs
|
|
that let you preserve and reuse the memory allocation across yescrypt
|
|
invocations. This is done by reusing the structure pointed to by the
|
|
"yescrypt_local_t *local" argument of yescrypt_r() or yescrypt_kdf()
|
|
without calling yescrypt_free_local() inbetween the repeated invocations
|
|
of yescrypt.
|
|
|
|
|
|
YESCRYPT_DEFAULTS macro.
|
|
|
|
Please note that the value of the YESCRYPT_DEFAULTS macro might change
|
|
later, so if you use the macro like it's recommended here then for
|
|
results reproducible across versions you might need to store its value
|
|
somewhere along with the hashes or the encrypted data.
|
|
|
|
If you use yescrypt's standard hash string encoding, then yescrypt
|
|
already encodes and decodes this value for you, so you don't need to
|
|
worry about this.
|