You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
The current findIterations method is too slow for my use-case. I intend to re-evaluate the number of iterations in a random interval to tailor the parameters to my hardware, and the current implementation is too inefficient and wasting a lot of resources when it is run multiple times during application runtime.
I have written a custom implementation that takes advantage of the fact that the hashing time grows roughly linear with the number of iterations.
Hashing time on my laptop for $$m = 8192$$ and $$p = 4$$ with incrementing number of iterations
My custom findIterations method
privateintmeasure(longstart) {
finallongend = System.nanoTime();
returnLong.valueOf((end - start) / 1_000_000).intValue();
}
protectedintfindIterations(Argon2Factory.Argon2Typestype, intmaxMillis, intm, intp) {
finalvarargon = Argon2Factory.create(type);
warmup(argon, "password".toCharArray());
// first do single iteration and see where we're atintiterations = 1;
longstart = System.nanoTime();
argon.hash(iterations, m, p, "password".toCharArray());
inttook = measure(start);
// if one iteration already takes more than maxMillis, use one iterationif (took > maxMillis) return1;
// if one iteration takes less than a third of maxMillis, bump iterations to 3 to get more accurate resultsif (took < (maxMillis / 3)) iterations = 3;
// do five rounds of hashing with those iterations and measure the execution timeint[] measurements = newint[5];
for (inti = 0; i < measurements.length; i++) {
start = System.nanoTime();
argon.hash(iterations, m, p, "password".toCharArray());
// divide measurement by amount of iterations, to get the approximate time one iteration would takemeasurements[i] = measure(start) / iterations;
}
// get the average time it took for one iterationvaravg = Arrays.stream(measurements).average().orElse(0.0);
// return the approximated amount of iterations to stay within maxMillis, with a lower bound of 1 iterationreturnMath.max(1, Math.floorDiv(maxMillis, Double.valueOf(avg).intValue()));
}
My custom implementation vastly outperforms the library method, and the results of $$t$$ are within a very similar range. Especially for large numbers of iterations, the method as provided in the library will take a long time. See comparison below.
variant
max millis
memory
parallelism
result
hash time (5/avg)
$$t$$ found in
library method
1000
8192 kiB
1
$$t = 129$$
848 ms
54997 ms
my method
1000
8192 kiB
1
$$t = 166$$
1005 ms
99 ms
variant
max millis
memory
parallelism
result
hash time (5/avg)
$$t$$ found in
library method
1000
65536 kiB
1
$$t = 18$$
967 ms
10751 ms
my method
1000
65536 kiB
1
$$t = 18$$
1028 ms
875 ms
variant
max millis
memory
parallelism
result
hash time (5/avg)
$$t$$ found in
library method
1000
1048576 kiB
1
$$t = 1$$
1135 ms
1131 ms
my method
1000
1048576 kiB
1
$$t = 1$$
1136 ms
1135 ms
variant
max millis
memory
parallelism
result
hash time (5/avg)
$$t$$ found in
library method
1000
8192 kiB
4
$$t = 303$$
939 ms
145418 ms
my method
1000
8192 kiB
4
$$t = 333$$
1002 ms
57 ms
variant
max millis
memory
parallelism
result
hash time (5/avg)
$$t$$ found in
library method
1000
65536 kiB
4
$$t = 42$$
920 ms
20730 ms
my method
1000
65536 kiB
4
$$t = 47$$
977 ms
351 ms
variant
max millis
memory
parallelism
result
hash time (5/avg)
$$t$$ found in
library method
1000
1048576 kiB
4
$$t = 2$$
872 ms
2623 ms
my method
1000
1048576 kiB
4
$$t = 2$$
791 ms
2411 ms
Note
The second to last column shows the time it takes to hash with the evaluated $$t$$ parameter, it was measured by measuring 5 times and taking the average. The last column shows the amount of time it took to find the number of iterations.
The current
findIterationsmethod is too slow for my use-case. I intend to re-evaluate the number of iterations in a random interval to tailor the parameters to my hardware, and the current implementation is too inefficient and wasting a lot of resources when it is run multiple times during application runtime.I have written a custom implementation that takes advantage of the fact that the hashing time grows roughly linear with the number of iterations.
Hashing time on my laptop for$$m = 8192$$ and $$p = 4$$ with incrementing number of iterations
My custom
findIterationsmethodMy custom implementation vastly outperforms the library method, and the results of$$t$$ are within a very similar range. Especially for large numbers of iterations, the method as provided in the library will take a long time. See comparison below.
848 ms54997 ms1005 ms99 ms967 ms10751 ms1028 ms875 ms1135 ms1131 ms1136 ms1135 ms939 ms145418 ms1002 ms57 ms920 ms20730 ms977 ms351 ms872 ms2623 ms791 ms2411 msNote
The second to last column shows the time it takes to hash with the evaluated$$t$$ parameter, it was measured by measuring 5 times and taking the average. The last column shows the amount of time it took to find the number of iterations.