Open chickahoona opened 1 year ago
See:
https://github.com/gmpassos/argon2/blob/master/lib/src/argon2_base.dart#L132
It's the memory used to store the "hashing blocks".
The Argon2 algorithm allows a custom amount of memory to compute the hash, what increases the computation cost (a feature needed in some use cases).
See: https://medium.com/analytics-vidhya/password-hashing-pbkdf2-scrypt-bcrypt-and-argon2-e25aaf41598e
And some description of the behavior:
The Argon2 password hashing algorithm is designed to be memory-hard, meaning that it requires a significant amount of memory to perform the hashing operation. This is intended to make the algorithm resistant to attacks that use specialized hardware, such as ASICs or FPGAs, to accelerate the hashing process.
The memory parameter in Argon2 specifies the amount of memory to be used for the hashing operation, measured in kibibytes (KiB). The higher the memory parameter, the more memory will be used by the algorithm, and the more difficult it will be for an attacker to perform brute-force attacks.
When the memory parameter is increased, the amount of time required to perform the hashing operation also increases, which can make the algorithm less suitable for use in some scenarios, such as low-power devices or high-traffic web applications. However, the memory parameter can be adjusted to strike a balance between security and performance, depending on the specific requirements of the application.
Overall, the memory parameter plays a crucial role in determining the security and performance characteristics of the Argon2 hashing algorithm. It is important to choose an appropriate value for this parameter to ensure that the algorithm provides adequate security against attacks while also meeting the performance requirements of the application.
So if I take measured in kibibytes (KiB).
, may I assume that the default example with memoryPowerOf2: 16
corresponds to 2^16KiB or 65536 KiB or 64 MiB?
@chickahoona
I have recently tried this package instead of dargon2
(uses argon2-cpp
libraries) and its memory parameter corresponds one-to-one to the argon2-cpp
(and argon2-cli
) memory parameter in terms of key generation but with a significant decrease in generation speed.
I have also compared speeds and memory use in a CLI application that is shipped together with my app using /usr/bin/time -v
, here are the results with parallelism
/lanes
= 4, memory
= 65536, iterations
= 2:
Implementation | User time (seconds) | Maximum resident set size (kbytes) |
---|---|---|
argon2 | 2.63 | 210168 |
dargon2 | 0.51 | 77340 |
pointycastle | 2.69 | 210816 |
I wouldn't expect memory use to co-align one-to-one, especially if using a high-level implementation such as the one provided by this package.
Did tou tried to run it compiled?
dart compile exe path/to/file.dart
If you are running it from the Dart VM (dart run file.dart
), it will take some time to analyze and compile the code, before really run it.
Note that the best way to perform a benchmark is not to compute the process
time, but run the operation internally for some seconds (10s), and get the operations per/sec that you get in each implementation.
@gmpassos indeed, my CLI executable is compiled via dart compile exe
for release builds. dart run
runs way slower. Regarding the tests, yes, they were not super serious but I did run them several times and time was within 0.05s range.
I also tried the library in my Flutter app and there was a noticeable delay in login times compared with argon2-cpp
. Kinda what I expected considering how this is a pure Dart implementation. I wanted to get rid of having to ship a .dll
with my CLI executable but I guess I'm out of luck for now.
Get rid of DLLs is a good thing.
Well, you could preload the Argon2BytesGenerator
before the user click the login button, reducing the login time for the user:
var argon2 = Argon2BytesGenerator();
argon2.init(parameters);
I will consider trying that sometime, thank you. To be honest, I am much more worried about memory use than time, as memory is often scarce on mobile devices. In either way, this is a pretty good implementation in case anyone needs it for low-memory web argon2 scenarios, keep up the good work. 👍
Have you tried the pointycastle
version? It was based on this version, but they improved the internal int
representation.
It loads a different implementation depending on the platform:
https://github.com/bcgit/pc-dart/blob/master/lib/key_derivators/argon2_native_int_impl.dart https://github.com/bcgit/pc-dart/blob/master/lib/key_derivators/argon2_register64_impl.dart
I have updated my original comment with test results. pointycastle
actually runs somewhat worse (although insignificantly) than argon2
. Great job!
Regarding pre-loading, mine is a special case where user can have more than one account and has the freedom to customize their argon2 parameters during runtime so I don't see how or when I can use the initialize function. I believe I'm better off keeping whatever I was using before.
Thank you!
So if I take
measured in kibibytes (KiB).
, may I assume that the default example withmemoryPowerOf2: 16
corresponds to 2^16KiB or 65536 KiB or 64 MiB?
I am also interested in this question. It would help if the memory
and memoryPowerOf2
were documented in the code. Making wrong assumptions of this parameter will cause security issues.
Thank you for your work 🙇
Could you please specify what Memory means? so are we talking about 2^X Bytes / Bits / Kilobits / ...
I am asking as OWASP recommends at least 19 MiB of RAM and I'd like to know which setting would reflect that?
https://cheatsheetseries.owasp.org/cheatsheets/Password_Storage_Cheat_Sheet.html