The library comprises an implementation of Argon2 (i, d, id) and Blake2B algorithms that features the following:
- C++14 interface
- constexpr and partial templates to get rid of useless branches
- SSE2, SSSE3, SSE4.1, AVX2 optimized implementations of Argon2 and Blake2B
- Runtime CPU dispatching (a partiular implementation is chosen runtime depending on SIMD extentions available in the CPU)
- OpenMP for multithreading in contrast to pthread in the Argon2 reference implementation
- In contrast to the Argon2 reference implementation the library uses SIMD-optimized Blake2B
#include <argonishche.h>
uint32_t tcost = 1; /* one pass */
uint32_t mcost = 32; /* in KB */
uint32_t threads = 1; /* one thread version */
bool runTest = false; /* by default factory runs a quick runtime test; pass 'false' to disable it */
argonishche::Argon2Factory afactory(runTest);
std::unique_ptr<argonishche::Argon2Base> argon2 = afactory.Create(argonishche::Argon2Type::Argon2_d, tcost, mcost, threads, key, keylen);
argon2->Hash(input, insize, salt, saltsize, out, outlen);
bool result = argon2->Verify(pwd, pwdlen, salt, saltlen, hash, hashlen, aad, addlen);
argonishche::Blake2BFactory bfactory(runTest);
uint32_t outlen = 32;
std::unique_ptr<argonishche::Blake2Base> blake2b = bfactory.Create(outlen, key, keylen);
blake2b->Update(in, inlen);
blake2b->Final(out, outlen);
There are also HashWithCustomMemory
and VerifyWithCustomMemory
methods to which you can pass a memory area to use it for computations and to save a little on memory allocation. GetMemorySize
method returns the size of memory area that required for a particular instance.
On my OS X 10.11, MacBook Pro (Early 2015, Core i5 2,7 GHz, 16 GB 1867 MHz DDR3) for (Argon2_d, 1, 2048, 1)
it gives:
Implementation | Speed per one core (H/s) |
---|---|
REF (x64 w/o optimizations) | 458.51 |
SSE2 | 665.17 |
SSSE3 | 743.86 |
SSE4.1 | 723.41 |
AVX2 | 1120.14 |
On Intel(R) Xeon(R) CPU E5-2686 v4 @ 2.30GHz for (Argon2_d, 1, 2048, 1)
it gives:
Implementation | Speed per one core (H/s) |
---|---|
REF (x64 w/o optimizations) | 423.9 |
SSE2 | 663.42 |
SSSE3 | 715.33 |
SSE4.1 | 720.12 |
AVX2 | 1130.36 |
The library uses constexpr to calculate some values at compile time. mcost value is a template variable, so the library doesn't support arbitrary mcost values except for predefined ones (in practise you usually don't need it).
To add a new mcost value just modify the file internal/proxy/proxy_macros.h
and add appropriate ARGON2_INSTANCE_DECL
declaration.
You can use the following cmake options:
Option | Default value | Description |
---|---|---|
BUILD_WITH_OPENMP | ON | Use OpenMP if it's available |
BUILD_TESTS | ON | Build library tests |
BUILD_BENCHMARK | ON | Build openssl speed like benchmarking tool |
One of the tests is intended to run under Intel SDE emulator. Make sure you have SDE in your PATH and run test_sde.sh <build_folder>/test/test_sde
.
argonishche.h
contains some Doxygen comments so Doxygen can be used to generate documentation.
Just "Argon" and Russian suffix "-ищ" (-ishch). In Russian suffix "-ищ" (-ishch) means something that is bigger than ordinary and that scares small children. In this case - something that is bigger than Argon :)
This project uses some ideas and pieces of code from the following projects licensed under CC0:
And it wouldn't be possible to make the library without work of the following people:
- Alex Biryukov, Daniel Dinu, Dmitry Khovratovich who designed Argon2 algorithm
- Jean-Philippe Aumasson, Samuel Neves, Zooko Wilcox-O'Hearn, Christian Winnerlein who designed Blake2 algorithm
I'm also thankful to Igor Klevanets for his fruitful feedback and code reviews.