I'm trying to implement the Argon2 algorithm in an authentification library. I want to be able to provide some useful tips for the users to set the parameters.
While I understand how memory_cost
and threads
parameters affect the algorithm, I can't seem to wrap my head around the time_cost
parameter.
time_cost (integer) - Maximum amount of time it may take to compute the Argon2 hash. Defaults to PASSWORD_ARGON2_DEFAULT_TIME_COST.
Interrogation 1 - The default value is 2. It seems to represent a time, sadly, the unit seems missing. Is it in seconds? Milliseconds?
This SO answer says the default is 2 seconds.
In Chapter 3.1 Inputs, there is no mention of time here, only about a number of iterations.
Number of iterations
t
(used to tune the running time independently of the memory size) can be any integer number from 1 to 2^32−1;
A time-related value is defined in Chapter 9 Recommended Parameters, it says:
Figure out the maximum amount
x
of time (in seconds) that each call can afford[...]
Run the scheme of type
y
, memorym
andh
lanes and threads, using different number of passt
. Figure out the maximumt
such that the running time does not exceedx
. If it exceedsx
even fort = 1
, reducem
accordingly.Hash all the passwords with the just determined values
m
,h
, andt
.
Interrogation 2 - So does this mean PHP exposes the amount of time x
and determine the correct amount of iterations t
?
A time cost that defines the execution time of the algorithm and the number of iterations
[...]
The time cost represents the number of times the hash algorithm will be run.
Interrogation 3 - They talk about both a time and a number of iterations. Now I'm even more confused. Is it a time or a number of iterations? If I run a hash with time_cost = 2
, does this mean it will take 2 seconds?
To help me understand a bit, I've made this little benchmark script. I got the following result (1 thread):
m_cost (MB) | 1 | 2 | 4 | 8 | 16 | 32 | 64 | 128 | 256
=====================================================
t_cost=1 | 1 | 2 | 5 | 10 | 24 | 46 | 90 | 188 | 348
t_cost=2 | 2 | 4 | 8 | 18 | 39 | 75 | 145 | 295 | 636
t_cost=3 | 3 | 6 | 12 | 26 | 53 | 102 | 209 | 473 | 926
t_cost=4 | 5 | 9 | 30 | 56 | 78 | 147 | 309 | 567 |1233
t_cost=5 | 4 | 9 | 19 | 40 | 79 | 165 | 359 | 690 |1372
t_cost=6 | 5 | 12 | 23 | 49 | 93 | 198 | 399 | 781 |1777
t_cost=7 | 6 | 14 | 29 | 53 | 118 | 259 | 508 |1036 |2206
t_cost=8 | 8 | 16 | 33 | 82 | 179 | 294 | 528 |1185 |2344
I still don't get how the time_cost
could be a time in seconds.
If it is an upper bound (meaning the max time it could run), then it's not even helpful. For example, t_cost=8
and m_cost=16MB
could seem reasonable, as it takes around 200ms to run. But this means the algorithm could one day take up to 8 seconds to run? The usability would be disastrous!
I really tried to do my research, and I'm not really comfortable that I need to ask to understand this.
But this is really confusing. Since it is related to security, I really want to get to the bottom of this.
Thanks for your insights!
From what I can tell, it's the number of iterations in the ARGON2 algo.
If you track it back through the PHP source, you get
https://github.com/php/php-src/blob/master/ext/standard/password.c#L528
which calls
https://github.com/P-H-C/phc-winner-argon2/blob/master/src/argon2.c#L67
So here, t_cost maps to the number of passes ^
Also note:
See https://password-hashing.net/submissions/specs/Argon-v3.pdf - 2.1.1 - Inputs: Number of iterations t can be any integer number from 1 to 232 − 1
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With