Add Chukwa support
This commit is contained in:
parent
1d4bc030fb
commit
dcf9c68334
70 changed files with 7240 additions and 4 deletions
|
@ -10,6 +10,7 @@ option(WITH_HTTPD "HTTP REST API" ON)
|
|||
option(WITH_DEBUG_LOG "Enable debug log output" OFF)
|
||||
option(WITH_TLS "Enable OpenSSL support" ON)
|
||||
option(WITH_ASM "Enable ASM PoW implementations" ON)
|
||||
option(WITH_ARGON2 "Enable Argon2 Support" ON)
|
||||
option(BUILD_STATIC "Build static binary" OFF)
|
||||
option(ARM_TARGET "Force use specific ARM target 8 or 7" 0)
|
||||
option(WITH_EMBEDDED_CONFIG "Enable internal embedded JSON config" OFF)
|
||||
|
@ -86,6 +87,8 @@ set(HEADERS
|
|||
)
|
||||
|
||||
set(HEADERS_CRYPTO
|
||||
src/crypto/Argon2.h
|
||||
src/crypto/Argon2_constants.h
|
||||
src/crypto/c_blake256.h
|
||||
src/crypto/c_groestl.h
|
||||
src/crypto/c_jh.h
|
||||
|
@ -281,6 +284,15 @@ else()
|
|||
add_definitions(/DXMRIG_NO_API)
|
||||
endif()
|
||||
|
||||
if (WITH_ARGON2)
|
||||
add_subdirectory(src/3rdparty/argon2)
|
||||
include_directories(src/3rdparty/argon2/include)
|
||||
set(ARGON2_LIBRARY argon2)
|
||||
else()
|
||||
add_definitions(/DXMRIG_NO_ARGON2)
|
||||
set(ARGON2_LIBRARY "")
|
||||
endif()
|
||||
|
||||
include_directories(src)
|
||||
include_directories(src/3rdparty)
|
||||
include_directories(${UV_INCLUDE_DIR})
|
||||
|
@ -294,4 +306,4 @@ if (WITH_DEBUG_LOG)
|
|||
endif()
|
||||
|
||||
add_executable(${CMAKE_PROJECT_NAME} ${HEADERS} ${SOURCES} ${SOURCES_OS} ${SOURCES_CPUID} ${HEADERS_CRYPTO} ${SOURCES_CRYPTO} ${SOURCES_SYSLOG} ${HTTPD_SOURCES} ${TLS_SOURCES} ${XMRIG_ASM_SOURCES} ${CN_GPU_SOURCES})
|
||||
target_link_libraries(${CMAKE_PROJECT_NAME} ${XMRIG_ASM_LIBRARY} ${OPENSSL_LIBRARIES} ${UV_LIBRARIES} ${MHD_LIBRARY} ${EXTRA_LIBS} ${CPUID_LIB})
|
||||
target_link_libraries(${CMAKE_PROJECT_NAME} ${XMRIG_ASM_LIBRARY} ${OPENSSL_LIBRARIES} ${UV_LIBRARIES} ${MHD_LIBRARY} ${EXTRA_LIBS} ${CPUID_LIB} ${ARGON2_LIBRARY})
|
||||
|
|
2
src/3rdparty/argon2/.gitattributes
vendored
Normal file
2
src/3rdparty/argon2/.gitattributes
vendored
Normal file
|
@ -0,0 +1,2 @@
|
|||
*.h linguist-language=C
|
||||
*.pro linguist-language=QMake
|
70
src/3rdparty/argon2/.gitignore
vendored
Normal file
70
src/3rdparty/argon2/.gitignore
vendored
Normal file
|
@ -0,0 +1,70 @@
|
|||
# Compiled Object files
|
||||
*.slo
|
||||
*.lo
|
||||
*.o
|
||||
*.obj
|
||||
|
||||
# Precompiled Headers
|
||||
*.gch
|
||||
*.pch
|
||||
|
||||
# Compiled Dynamic libraries
|
||||
*.so
|
||||
*.dylib
|
||||
*.dll
|
||||
|
||||
# Fortran module files
|
||||
*.mod
|
||||
|
||||
# Compiled Static libraries
|
||||
*.lai
|
||||
*.la
|
||||
*.a
|
||||
*.lib
|
||||
|
||||
# Executables
|
||||
*.exe
|
||||
*.out
|
||||
*.app
|
||||
|
||||
# Autotools + Libtool
|
||||
/aclocal.m4
|
||||
/config.status
|
||||
/config
|
||||
/install-sh
|
||||
**/Makefile
|
||||
**/Makefile.in
|
||||
/autom4te.cache/
|
||||
/compile
|
||||
/config.guess
|
||||
/config.log
|
||||
/config.sub
|
||||
/configure
|
||||
/depcomp
|
||||
/libtool
|
||||
/ltmain.sh
|
||||
/m4/libtool.m4
|
||||
/m4/lt*.m4
|
||||
/missing
|
||||
/test-driver
|
||||
**/.deps/
|
||||
**/.dirstamp
|
||||
**/.libs/
|
||||
|
||||
# Qt Creator
|
||||
**/*.user
|
||||
**/*.user.*
|
||||
**/build-*/
|
||||
|
||||
# KDE
|
||||
**/.directory
|
||||
|
||||
# Vim
|
||||
*.swp
|
||||
|
||||
# CMake
|
||||
CMakeFiles/
|
||||
*.cmake
|
||||
CMakeCache.txt
|
||||
Makefile
|
||||
|
23
src/3rdparty/argon2/.travis.yml
vendored
Normal file
23
src/3rdparty/argon2/.travis.yml
vendored
Normal file
|
@ -0,0 +1,23 @@
|
|||
language: c
|
||||
|
||||
dist: trusty
|
||||
sudo: false
|
||||
|
||||
compiler:
|
||||
- clang
|
||||
- gcc
|
||||
|
||||
env:
|
||||
- BUILD=cmake BUILD_TYPE=Debug
|
||||
- BUILD=cmake BUILD_TYPE=Release
|
||||
- BUILD=autotools
|
||||
|
||||
script: |
|
||||
case $BUILD in
|
||||
cmake)
|
||||
cmake -DCMAKE_BUILD_TYPE=$BUILD_TYPE . && make && make test
|
||||
;;
|
||||
autotools)
|
||||
autoreconf -i && ./configure && make && make check
|
||||
;;
|
||||
esac
|
203
src/3rdparty/argon2/CMakeLists.txt
vendored
Normal file
203
src/3rdparty/argon2/CMakeLists.txt
vendored
Normal file
|
@ -0,0 +1,203 @@
|
|||
cmake_minimum_required(VERSION 2.6)
|
||||
|
||||
find_program(CCACHE_PROGRAM ccache)
|
||||
if(CCACHE_PROGRAM)
|
||||
message(STATUS "-- Argon2: Found ccache package... Activating...")
|
||||
set_property(GLOBAL PROPERTY RULE_LAUNCH_COMPILE "${CCACHE_PROGRAM}")
|
||||
endif()
|
||||
|
||||
project(Argon2 C)
|
||||
set(ARGON2_VERSION 1.0)
|
||||
set(CMAKE_C_STANDARD 90)
|
||||
set(CMAKE_C_STANDARD_REQUIRED ON)
|
||||
|
||||
include(CheckCSourceCompiles)
|
||||
find_package(Threads REQUIRED)
|
||||
|
||||
add_library(argon2-interface INTERFACE)
|
||||
target_include_directories(argon2-interface INTERFACE
|
||||
$<BUILD_INTERFACE:${CMAKE_CURRENT_SOURCE_DIR}/include>
|
||||
$<INSTALL_INTERFACE:include>
|
||||
)
|
||||
|
||||
add_library(argon2-internal INTERFACE)
|
||||
target_include_directories(argon2-internal INTERFACE lib lib/blake2)
|
||||
target_link_libraries(argon2-internal INTERFACE argon2-interface)
|
||||
|
||||
set(ARGON2_SRC
|
||||
lib/argon2.c
|
||||
lib/core.c
|
||||
lib/encoding.c
|
||||
lib/genkat.c
|
||||
lib/impl-select.c
|
||||
lib/thread.c
|
||||
lib/blake2/blake2.c
|
||||
)
|
||||
|
||||
message("-- Argon2: Processor: ${CMAKE_SYSTEM_PROCESSOR}")
|
||||
message("-- Argon2: Build Type: ${ARCH}")
|
||||
|
||||
if((CMAKE_SYSTEM_PROCESSOR STREQUAL "x86_64" OR CMAKE_SYSTEM_PROCESSOR STREQUAL "AMD64") AND NOT "${ARCH}" STREQUAL "default")
|
||||
include(CheckCXXSourceRuns)
|
||||
|
||||
# Check for AVX2
|
||||
check_cxx_source_runs("
|
||||
#include <immintrin.h>
|
||||
int main()
|
||||
{
|
||||
__m256i a, b, c;
|
||||
const int src[8] = { 1, 2, 3, 4, 5, 6, 7, 8 };
|
||||
int dst[8];
|
||||
a = _mm256_loadu_si256( (__m256i*)src );
|
||||
b = _mm256_loadu_si256( (__m256i*)src );
|
||||
c = _mm256_add_epi32( a, b );
|
||||
_mm256_storeu_si256( (__m256i*)dst, c );
|
||||
for( int i = 0; i < 8; i++ ){
|
||||
if( ( src[i] + src[i] ) != dst[i] ){
|
||||
return -1;
|
||||
}
|
||||
}
|
||||
return 0;
|
||||
}"
|
||||
HAVE_AVX2_EXTENSIONS)
|
||||
|
||||
if(HAVE_AVX2_EXTENSIONS)
|
||||
message("-- Argon2: AVX2 Extensions - Enabled")
|
||||
add_definitions(-DHAVE_AVX2)
|
||||
if(MSVC)
|
||||
add_definitions(/arch:AVX2)
|
||||
endif()
|
||||
else()
|
||||
message("-- Argon2: AVX2 Extensions - Disabled")
|
||||
endif()
|
||||
|
||||
# Check for AVX512
|
||||
check_cxx_source_runs("
|
||||
#include <immintrin.h>
|
||||
int main()
|
||||
{
|
||||
__m512i a, b, c;
|
||||
const int src[8] = { 1, 2, 3, 4, 5, 6, 7, 8 };
|
||||
int dst[8];
|
||||
a = _mm512_loadu_si512( (__m512i*)src );
|
||||
b = _mm512_loadu_si512( (__m512i*)src );
|
||||
c = _mm512_add_epi32( a, b );
|
||||
_mm512_storeu_si512( (__m512i*)dst, c );
|
||||
for( int i = 0; i < 8; i++ ){
|
||||
if( ( src[i] + src[i] ) != dst[i] ){
|
||||
return -1;
|
||||
}
|
||||
}
|
||||
return 0;
|
||||
}"
|
||||
HAVE_AVX512F_EXTENSIONS)
|
||||
|
||||
if(HAVE_AVX512F_EXTENSIONS)
|
||||
message("-- Argon2: AVX512 Extensions - Enabled")
|
||||
add_definitions(-DHAVE_AVX512F)
|
||||
else()
|
||||
message("-- Argon2: AVX512 Extensions - Disabled")
|
||||
endif()
|
||||
|
||||
# Check for SSE2
|
||||
check_cxx_source_runs("
|
||||
#include <immintrin.h>
|
||||
int main()
|
||||
{
|
||||
__m128d a, b;
|
||||
double vals[2] = {0};
|
||||
a = _mm_loadu_pd(vals);
|
||||
b = _mm_add_pd(a,a);
|
||||
_mm_storeu_pd(vals,b);
|
||||
return 0;
|
||||
}"
|
||||
HAVE_SSE2_EXTENSIONS)
|
||||
|
||||
if(HAVE_SSE2_EXTENSIONS)
|
||||
message("-- Argon2: SSE2 Extensions - Enabled")
|
||||
add_definitions(-DHAVE_SSE2)
|
||||
if(MSVC)
|
||||
add_definitions(/arch:SSE2)
|
||||
endif()
|
||||
else()
|
||||
message("-- Argon2: SSE2 Extensions - Disabled")
|
||||
endif()
|
||||
|
||||
# Check for SSE3
|
||||
check_cxx_source_runs("
|
||||
#include <immintrin.h>
|
||||
int main()
|
||||
{
|
||||
__m128d a, b;
|
||||
double vals[2] = {0};
|
||||
a = _mm_loadu_pd(vals);
|
||||
b = _mm_hadd_pd(a,a);
|
||||
_mm_storeu_pd(vals, b);
|
||||
return 0;
|
||||
}"
|
||||
HAVE_SSE3_EXTENSIONS)
|
||||
|
||||
if(HAVE_SSE3_EXTENSIONS)
|
||||
message("-- Argon2: SSE3 Extensions - Enabled")
|
||||
add_definitions(-DHAVE_SSE3)
|
||||
if(MSVC)
|
||||
add_definitions(/arch:SSE3)
|
||||
endif()
|
||||
else()
|
||||
message("-- Argon2: SSE3 Extensions - Disabled")
|
||||
endif()
|
||||
|
||||
# Check for XOP
|
||||
check_cxx_source_runs("
|
||||
#include <immintrin.h>
|
||||
int main()
|
||||
{
|
||||
__m128i a, b, c;
|
||||
const int src[8] = { 1, 2, 3, 4, 5, 6, 7, 8 };
|
||||
a = _mm_load_si128( (__m128i*)src );
|
||||
b = _mm_load_si128( (__m128i*)src );
|
||||
c = _mm_roti_epi64(*a, b);
|
||||
return 0;
|
||||
}"
|
||||
HAVE_XOP_EXTENSIONS)
|
||||
|
||||
if(HAVE_XOP_EXTENSIONS)
|
||||
message("-- Argon2: XOP Extensions - Enabled")
|
||||
add_definitions(-DHAVE_XOP)
|
||||
else()
|
||||
message("-- Argon2: XOP Extensions - Disabled")
|
||||
endif()
|
||||
|
||||
list(APPEND ARGON2_SRC
|
||||
arch/x86_64/lib/argon2-sse2.c
|
||||
arch/x86_64/lib/argon2-ssse3.c
|
||||
arch/x86_64/lib/argon2-xop.c
|
||||
arch/x86_64/lib/argon2-avx2.c
|
||||
arch/x86_64/lib/argon2-avx512f.c
|
||||
arch/x86_64/lib/argon2-arch.c
|
||||
)
|
||||
else()
|
||||
list(APPEND ARGON2_SRC
|
||||
arch/generic/lib/argon2-arch.c
|
||||
)
|
||||
endif()
|
||||
|
||||
add_library(argon2 STATIC ${ARGON2_SRC})
|
||||
|
||||
target_compile_definitions(argon2
|
||||
PUBLIC "A2_VISCTL"
|
||||
)
|
||||
|
||||
target_link_libraries(argon2
|
||||
PUBLIC argon2-interface ${CMAKE_THREAD_LIBS_INIT}
|
||||
PRIVATE argon2-internal
|
||||
)
|
||||
|
||||
set_property(TARGET argon2 PROPERTY C_STANDARD 90)
|
||||
set_property(TARGET argon2 PROPERTY VERSION ${Upstream_VERSION})
|
||||
set_property(TARGET argon2 PROPERTY SOVERSION 1)
|
||||
set_property(TARGET argon2 PROPERTY INTERFACE_ARGON2_MAJOR_VERSION 1)
|
||||
set_property(TARGET argon2 APPEND PROPERTY
|
||||
COMPATIBLE_INTERFACE_STRING ARGON2_MAJOR_VERSION
|
||||
)
|
||||
|
21
src/3rdparty/argon2/LICENSE
vendored
Normal file
21
src/3rdparty/argon2/LICENSE
vendored
Normal file
|
@ -0,0 +1,21 @@
|
|||
MIT License
|
||||
|
||||
Copyright (c) 2016 Ondrej Mosnáček
|
||||
|
||||
Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
of this software and associated documentation files (the "Software"), to deal
|
||||
in the Software without restriction, including without limitation the rights
|
||||
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
copies of the Software, and to permit persons to whom the Software is
|
||||
furnished to do so, subject to the following conditions:
|
||||
|
||||
The above copyright notice and this permission notice shall be included in all
|
||||
copies or substantial portions of the Software.
|
||||
|
||||
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
||||
SOFTWARE.
|
125
src/3rdparty/argon2/Makefile.am
vendored
Normal file
125
src/3rdparty/argon2/Makefile.am
vendored
Normal file
|
@ -0,0 +1,125 @@
|
|||
ACLOCAL_AMFLAGS = -I m4
|
||||
|
||||
include_HEADERS = include/argon2.h
|
||||
lib_LTLIBRARIES = libargon2.la
|
||||
noinst_LTLIBRARIES =
|
||||
|
||||
bin_PROGRAMS = argon2
|
||||
noinst_PROGRAMS = argon2-genkat argon2-bench2 argon2-test
|
||||
|
||||
TESTS = argon2-test
|
||||
|
||||
AM_CPPFLAGS = \
|
||||
-I$(srcdir)/include \
|
||||
-I$(srcdir)/lib \
|
||||
-I$(srcdir)/arch/@ARCH@/include \
|
||||
-I$(srcdir)/arch/@ARCH@/lib
|
||||
|
||||
libargon2_la_CFLAGS = @PTHREAD_CFLAGS@
|
||||
libargon2_la_LIBADD = @PTHREAD_LIBS@
|
||||
libargon2_la_SOURCES = \
|
||||
lib/argon2.c \
|
||||
lib/core.c \
|
||||
lib/encoding.c \
|
||||
lib/genkat.c \
|
||||
lib/impl-select.c \
|
||||
lib/thread.c \
|
||||
lib/blake2/blake2.c \
|
||||
lib/argon2-template-64.h \
|
||||
lib/core.h \
|
||||
lib/encoding.h \
|
||||
lib/genkat.h \
|
||||
lib/impl-select.h \
|
||||
lib/thread.h \
|
||||
lib/blake2/blake2.h \
|
||||
lib/blake2/blake2-impl.h
|
||||
|
||||
if ARCH_X86_64
|
||||
noinst_LTLIBRARIES += \
|
||||
libargon2-sse2.la \
|
||||
libargon2-ssse3.la \
|
||||
libargon2-xop.la \
|
||||
libargon2-avx2.la \
|
||||
libargon2-avx512f.la
|
||||
libargon2_la_LIBADD += \
|
||||
libargon2-sse2.la \
|
||||
libargon2-ssse3.la \
|
||||
libargon2-xop.la \
|
||||
libargon2-avx2.la \
|
||||
libargon2-avx512f.la
|
||||
|
||||
libargon2_sse2_la_SOURCES = \
|
||||
arch/@ARCH@/lib/argon2-sse2.c \
|
||||
arch/@ARCH@/lib/argon2-sse2.h \
|
||||
arch/@ARCH@/lib/argon2-template-128.h
|
||||
libargon2_sse2_la_CPPFLAGS = $(AM_CPPFLAGS)
|
||||
libargon2_sse2_la_CFLAGS = $(AM_CFLAGS)
|
||||
if HAVE_SSE2
|
||||
libargon2_sse2_la_CPPFLAGS += -DHAVE_SSE2
|
||||
libargon2_sse2_la_CFLAGS += -msse2
|
||||
endif # HAVE_SSE2
|
||||
|
||||
libargon2_ssse3_la_SOURCES = \
|
||||
arch/@ARCH@/lib/argon2-ssse3.c \
|
||||
arch/@ARCH@/lib/argon2-ssse3.h \
|
||||
arch/@ARCH@/lib/argon2-template-128.h
|
||||
libargon2_ssse3_la_CPPFLAGS = $(AM_CPPFLAGS)
|
||||
libargon2_ssse3_la_CFLAGS = $(AM_CFLAGS)
|
||||
if HAVE_SSSE3
|
||||
libargon2_ssse3_la_CPPFLAGS += -DHAVE_SSSE3
|
||||
libargon2_ssse3_la_CFLAGS += -mssse3
|
||||
endif # HAVE_SSSE3
|
||||
|
||||
libargon2_xop_la_SOURCES = \
|
||||
arch/@ARCH@/lib/argon2-xop.c \
|
||||
arch/@ARCH@/lib/argon2-xop.h \
|
||||
arch/@ARCH@/lib/argon2-template-128.h
|
||||
libargon2_xop_la_CPPFLAGS = $(AM_CPPFLAGS)
|
||||
libargon2_xop_la_CFLAGS = $(AM_CFLAGS)
|
||||
if HAVE_XOP
|
||||
libargon2_xop_la_CPPFLAGS += -DHAVE_XOP
|
||||
libargon2_xop_la_CFLAGS += -mxop
|
||||
endif # HAVE_XOP
|
||||
|
||||
libargon2_avx2_la_SOURCES = \
|
||||
arch/@ARCH@/lib/argon2-avx2.c \
|
||||
arch/@ARCH@/lib/argon2-avx2.h
|
||||
libargon2_avx2_la_CPPFLAGS = $(AM_CPPFLAGS)
|
||||
libargon2_avx2_la_CFLAGS = $(AM_CFLAGS)
|
||||
if HAVE_AVX2
|
||||
libargon2_avx2_la_CPPFLAGS += -DHAVE_AVX2
|
||||
libargon2_avx2_la_CFLAGS += -mavx2
|
||||
endif # HAVE_AVX2
|
||||
|
||||
libargon2_avx512f_la_SOURCES = \
|
||||
arch/@ARCH@/lib/argon2-avx512f.c \
|
||||
arch/@ARCH@/lib/argon2-avx512f.h
|
||||
libargon2_avx512f_la_CPPFLAGS = $(AM_CPPFLAGS)
|
||||
libargon2_avx512f_la_CFLAGS = $(AM_CFLAGS)
|
||||
if HAVE_AVX512F
|
||||
libargon2_avx512f_la_CPPFLAGS += -DHAVE_AVX512F
|
||||
libargon2_avx512f_la_CFLAGS += -mavx512f
|
||||
endif # HAVE_AVX512F
|
||||
|
||||
libargon2_la_SOURCES += \
|
||||
arch/@ARCH@/lib/argon2-arch.c \
|
||||
arch/@ARCH@/lib/cpu-flags.c \
|
||||
arch/@ARCH@/lib/cpu-flags.h
|
||||
endif # ARCH_X86_64
|
||||
|
||||
if ARCH_GENERIC
|
||||
libargon2_la_SOURCES += \
|
||||
arch/@ARCH@/lib/argon2-arch.c
|
||||
endif # ARCH_GENERIC
|
||||
|
||||
argon2_LDADD = libargon2.la
|
||||
argon2_SOURCES = src/run.c lib/core.h
|
||||
|
||||
argon2_genkat_LDADD = libargon2.la
|
||||
argon2_genkat_SOURCES = src/genkat.c
|
||||
|
||||
argon2_bench2_LDADD = libargon2.la -lrt
|
||||
argon2_bench2_SOURCES = src/bench2.c src/timing.h
|
||||
|
||||
argon2_test_LDADD = libargon2.la
|
||||
argon2_test_SOURCES = tests/test.c
|
58
src/3rdparty/argon2/README.md
vendored
Normal file
58
src/3rdparty/argon2/README.md
vendored
Normal file
|
@ -0,0 +1,58 @@
|
|||
# Argon2 [](https://travis-ci.org/WOnder93/argon2)
|
||||
A multi-arch library implementing the Argon2 password hashing algorithm.
|
||||
|
||||
This project is based on the [original source code](https://github.com/P-H-C/phc-winner-argon2) by the Argon2 authors. The goal of this project is to provide efficient Argon2 implementations for various HW architectures (x86, SSE, ARM, PowerPC, ...).
|
||||
|
||||
For the x86_64 architecture, the library implements a simple CPU dispatch which automatically selects the best implementation based on CPU flags and quick benchmarks.
|
||||
|
||||
# Building
|
||||
## Using GNU autotools
|
||||
|
||||
To prepare the build environment, run:
|
||||
```bash
|
||||
autoreconf -i
|
||||
./configure
|
||||
```
|
||||
|
||||
After that, just run `make` to build the library.
|
||||
|
||||
### Running tests
|
||||
After configuring the build environment, run `make check` to run the tests.
|
||||
|
||||
### Architecture options
|
||||
You can specify the target architecture by passing the `--host=...` flag to `./configure`.
|
||||
|
||||
Supported architectures:
|
||||
* `x86_64` – 64-bit x86 architecture
|
||||
* `generic` – use generic C impementation
|
||||
|
||||
## Using CMake
|
||||
|
||||
To prepare the build environment, run:
|
||||
```bash
|
||||
cmake -DCMAKE_BUILD_TYPE=Release .
|
||||
```
|
||||
|
||||
Then you can run `make` to build the library.
|
||||
|
||||
## Using QMake/Qt Creator
|
||||
A [QMake](http://doc.qt.io/qt-4.8/qmake-manual.html) project is also available in the `qmake` directory. You can open it in the [Qt Creator IDE](http://wiki.qt.io/Category:Tools::QtCreator) or build it from terminal:
|
||||
```bash
|
||||
cd qmake
|
||||
# see table below for the list of possible ARCH and CONFIG values
|
||||
qmake ARCH=... CONFIG+=...
|
||||
make
|
||||
```
|
||||
|
||||
### Architecture options
|
||||
For QMake builds you can configure support for different architectures. Use the `ARCH` variable to choose the architecture and the `CONFIG` variable to set additional options.
|
||||
|
||||
Supported architectures:
|
||||
* `x86_64` – 64-bit x86 architecture
|
||||
* QMake config flags:
|
||||
* `USE_SSE2` – use SSE2 instructions
|
||||
* `USE_SSSE3` – use SSSE3 instructions
|
||||
* `USE_XOP` – use XOP instructions
|
||||
* `USE_AVX2` – use AVX2 instructions
|
||||
* `USE_AVX512F` – use AVX-512F instructions
|
||||
* `generic` – use generic C impementation
|
20
src/3rdparty/argon2/arch/generic/lib/argon2-arch.c
vendored
Normal file
20
src/3rdparty/argon2/arch/generic/lib/argon2-arch.c
vendored
Normal file
|
@ -0,0 +1,20 @@
|
|||
#include <stdint.h>
|
||||
#include <string.h>
|
||||
#include <stdlib.h>
|
||||
|
||||
#include "impl-select.h"
|
||||
|
||||
#define rotr64(x, n) (((x) >> (n)) | ((x) << (64 - (n))))
|
||||
|
||||
#include "argon2-template-64.h"
|
||||
|
||||
void fill_segment_default(const argon2_instance_t *instance,
|
||||
argon2_position_t position)
|
||||
{
|
||||
fill_segment_64(instance, position);
|
||||
}
|
||||
|
||||
void argon2_get_impl_list(argon2_impl_list *list)
|
||||
{
|
||||
list->count = 0;
|
||||
}
|
38
src/3rdparty/argon2/arch/x86_64/lib/argon2-arch.c
vendored
Normal file
38
src/3rdparty/argon2/arch/x86_64/lib/argon2-arch.c
vendored
Normal file
|
@ -0,0 +1,38 @@
|
|||
#include <stdint.h>
|
||||
#include <string.h>
|
||||
#include <stdlib.h>
|
||||
|
||||
#include "impl-select.h"
|
||||
|
||||
#include "argon2-sse2.h"
|
||||
#include "argon2-ssse3.h"
|
||||
#include "argon2-xop.h"
|
||||
#include "argon2-avx2.h"
|
||||
#include "argon2-avx512f.h"
|
||||
|
||||
/* NOTE: there is no portable intrinsic for 64-bit rotate, but any
|
||||
* sane compiler should be able to compile this into a ROR instruction: */
|
||||
#define rotr64(x, n) ((x) >> (n)) | ((x) << (64 - (n)))
|
||||
|
||||
#include "argon2-template-64.h"
|
||||
|
||||
void fill_segment_default(const argon2_instance_t *instance,
|
||||
argon2_position_t position)
|
||||
{
|
||||
fill_segment_64(instance, position);
|
||||
}
|
||||
|
||||
void argon2_get_impl_list(argon2_impl_list *list)
|
||||
{
|
||||
static const argon2_impl IMPLS[] = {
|
||||
{ "x86_64", NULL, fill_segment_default },
|
||||
{ "SSE2", check_sse2, fill_segment_sse2 },
|
||||
{ "SSSE3", check_ssse3, fill_segment_ssse3 },
|
||||
{ "XOP", check_xop, fill_segment_xop },
|
||||
{ "AVX2", check_avx2, fill_segment_avx2 },
|
||||
{ "AVX-512F", check_avx512f, fill_segment_avx512f },
|
||||
};
|
||||
|
||||
list->count = sizeof(IMPLS) / sizeof(IMPLS[0]);
|
||||
list->entries = IMPLS;
|
||||
}
|
341
src/3rdparty/argon2/arch/x86_64/lib/argon2-avx2.c
vendored
Normal file
341
src/3rdparty/argon2/arch/x86_64/lib/argon2-avx2.c
vendored
Normal file
|
@ -0,0 +1,341 @@
|
|||
#include "argon2-avx2.h"
|
||||
|
||||
#ifdef HAVE_AVX2
|
||||
#include <string.h>
|
||||
|
||||
#include <immintrin.h>
|
||||
|
||||
#define r16 (_mm256_setr_epi8( \
|
||||
2, 3, 4, 5, 6, 7, 0, 1, \
|
||||
10, 11, 12, 13, 14, 15, 8, 9, \
|
||||
18, 19, 20, 21, 22, 23, 16, 17, \
|
||||
26, 27, 28, 29, 30, 31, 24, 25))
|
||||
|
||||
#define r24 (_mm256_setr_epi8( \
|
||||
3, 4, 5, 6, 7, 0, 1, 2, \
|
||||
11, 12, 13, 14, 15, 8, 9, 10, \
|
||||
19, 20, 21, 22, 23, 16, 17, 18, \
|
||||
27, 28, 29, 30, 31, 24, 25, 26))
|
||||
|
||||
#define ror64_16(x) _mm256_shuffle_epi8((x), r16)
|
||||
#define ror64_24(x) _mm256_shuffle_epi8((x), r24)
|
||||
#define ror64_32(x) _mm256_shuffle_epi32((x), _MM_SHUFFLE(2, 3, 0, 1))
|
||||
#define ror64_63(x) \
|
||||
_mm256_xor_si256(_mm256_srli_epi64((x), 63), _mm256_add_epi64((x), (x)))
|
||||
|
||||
static __m256i f(__m256i x, __m256i y)
|
||||
{
|
||||
__m256i z = _mm256_mul_epu32(x, y);
|
||||
return _mm256_add_epi64(_mm256_add_epi64(x, y), _mm256_add_epi64(z, z));
|
||||
}
|
||||
|
||||
#define G1(A0, B0, C0, D0, A1, B1, C1, D1) \
|
||||
do { \
|
||||
A0 = f(A0, B0); \
|
||||
A1 = f(A1, B1); \
|
||||
\
|
||||
D0 = _mm256_xor_si256(D0, A0); \
|
||||
D1 = _mm256_xor_si256(D1, A1); \
|
||||
\
|
||||
D0 = ror64_32(D0); \
|
||||
D1 = ror64_32(D1); \
|
||||
\
|
||||
C0 = f(C0, D0); \
|
||||
C1 = f(C1, D1); \
|
||||
\
|
||||
B0 = _mm256_xor_si256(B0, C0); \
|
||||
B1 = _mm256_xor_si256(B1, C1); \
|
||||
\
|
||||
B0 = ror64_24(B0); \
|
||||
B1 = ror64_24(B1); \
|
||||
} while ((void)0, 0)
|
||||
|
||||
#define G2(A0, B0, C0, D0, A1, B1, C1, D1) \
|
||||
do { \
|
||||
A0 = f(A0, B0); \
|
||||
A1 = f(A1, B1); \
|
||||
\
|
||||
D0 = _mm256_xor_si256(D0, A0); \
|
||||
D1 = _mm256_xor_si256(D1, A1); \
|
||||
\
|
||||
D0 = ror64_16(D0); \
|
||||
D1 = ror64_16(D1); \
|
||||
\
|
||||
C0 = f(C0, D0); \
|
||||
C1 = f(C1, D1); \
|
||||
\
|
||||
B0 = _mm256_xor_si256(B0, C0); \
|
||||
B1 = _mm256_xor_si256(B1, C1); \
|
||||
\
|
||||
B0 = ror64_63(B0); \
|
||||
B1 = ror64_63(B1); \
|
||||
} while ((void)0, 0)
|
||||
|
||||
#define DIAGONALIZE1(A0, B0, C0, D0, A1, B1, C1, D1) \
|
||||
do { \
|
||||
B0 = _mm256_permute4x64_epi64(B0, _MM_SHUFFLE(0, 3, 2, 1)); \
|
||||
B1 = _mm256_permute4x64_epi64(B1, _MM_SHUFFLE(0, 3, 2, 1)); \
|
||||
\
|
||||
C0 = _mm256_permute4x64_epi64(C0, _MM_SHUFFLE(1, 0, 3, 2)); \
|
||||
C1 = _mm256_permute4x64_epi64(C1, _MM_SHUFFLE(1, 0, 3, 2)); \
|
||||
\
|
||||
D0 = _mm256_permute4x64_epi64(D0, _MM_SHUFFLE(2, 1, 0, 3)); \
|
||||
D1 = _mm256_permute4x64_epi64(D1, _MM_SHUFFLE(2, 1, 0, 3)); \
|
||||
} while ((void)0, 0)
|
||||
|
||||
#define UNDIAGONALIZE1(A0, B0, C0, D0, A1, B1, C1, D1) \
|
||||
do { \
|
||||
B0 = _mm256_permute4x64_epi64(B0, _MM_SHUFFLE(2, 1, 0, 3)); \
|
||||
B1 = _mm256_permute4x64_epi64(B1, _MM_SHUFFLE(2, 1, 0, 3)); \
|
||||
\
|
||||
C0 = _mm256_permute4x64_epi64(C0, _MM_SHUFFLE(1, 0, 3, 2)); \
|
||||
C1 = _mm256_permute4x64_epi64(C1, _MM_SHUFFLE(1, 0, 3, 2)); \
|
||||
\
|
||||
D0 = _mm256_permute4x64_epi64(D0, _MM_SHUFFLE(0, 3, 2, 1)); \
|
||||
D1 = _mm256_permute4x64_epi64(D1, _MM_SHUFFLE(0, 3, 2, 1)); \
|
||||
} while ((void)0, 0)
|
||||
|
||||
#define DIAGONALIZE2(A0, B0, C0, D0, A1, B1, C1, D1) \
|
||||
do { \
|
||||
__m256i tmp1, tmp2; \
|
||||
tmp1 = _mm256_blend_epi32(B0, B1, 0xCC); \
|
||||
tmp2 = _mm256_blend_epi32(B0, B1, 0x33); \
|
||||
B1 = _mm256_permute4x64_epi64(tmp1, _MM_SHUFFLE(2,3,0,1)); \
|
||||
B0 = _mm256_permute4x64_epi64(tmp2, _MM_SHUFFLE(2,3,0,1)); \
|
||||
\
|
||||
tmp1 = C0; \
|
||||
C0 = C1; \
|
||||
C1 = tmp1; \
|
||||
\
|
||||
tmp1 = _mm256_blend_epi32(D0, D1, 0xCC); \
|
||||
tmp2 = _mm256_blend_epi32(D0, D1, 0x33); \
|
||||
D0 = _mm256_permute4x64_epi64(tmp1, _MM_SHUFFLE(2,3,0,1)); \
|
||||
D1 = _mm256_permute4x64_epi64(tmp2, _MM_SHUFFLE(2,3,0,1)); \
|
||||
} while ((void)0, 0)
|
||||
|
||||
#define UNDIAGONALIZE2(A0, B0, C0, D0, A1, B1, C1, D1) \
|
||||
do { \
|
||||
__m256i tmp1, tmp2; \
|
||||
tmp1 = _mm256_blend_epi32(B0, B1, 0xCC); \
|
||||
tmp2 = _mm256_blend_epi32(B0, B1, 0x33); \
|
||||
B0 = _mm256_permute4x64_epi64(tmp1, _MM_SHUFFLE(2,3,0,1)); \
|
||||
B1 = _mm256_permute4x64_epi64(tmp2, _MM_SHUFFLE(2,3,0,1)); \
|
||||
\
|
||||
tmp1 = C0; \
|
||||
C0 = C1; \
|
||||
C1 = tmp1; \
|
||||
\
|
||||
tmp1 = _mm256_blend_epi32(D0, D1, 0xCC); \
|
||||
tmp2 = _mm256_blend_epi32(D0, D1, 0x33); \
|
||||
D1 = _mm256_permute4x64_epi64(tmp1, _MM_SHUFFLE(2,3,0,1)); \
|
||||
D0 = _mm256_permute4x64_epi64(tmp2, _MM_SHUFFLE(2,3,0,1)); \
|
||||
} while ((void)0, 0)
|
||||
|
||||
#define BLAKE2_ROUND1(A0, B0, C0, D0, A1, B1, C1, D1) \
|
||||
do { \
|
||||
G1(A0, B0, C0, D0, A1, B1, C1, D1); \
|
||||
G2(A0, B0, C0, D0, A1, B1, C1, D1); \
|
||||
\
|
||||
DIAGONALIZE1(A0, B0, C0, D0, A1, B1, C1, D1); \
|
||||
\
|
||||
G1(A0, B0, C0, D0, A1, B1, C1, D1); \
|
||||
G2(A0, B0, C0, D0, A1, B1, C1, D1); \
|
||||
\
|
||||
UNDIAGONALIZE1(A0, B0, C0, D0, A1, B1, C1, D1); \
|
||||
} while ((void)0, 0)
|
||||
|
||||
#define BLAKE2_ROUND2(A0, A1, B0, B1, C0, C1, D0, D1) \
|
||||
do { \
|
||||
G1(A0, B0, C0, D0, A1, B1, C1, D1); \
|
||||
G2(A0, B0, C0, D0, A1, B1, C1, D1); \
|
||||
\
|
||||
DIAGONALIZE2(A0, B0, C0, D0, A1, B1, C1, D1); \
|
||||
\
|
||||
G1(A0, B0, C0, D0, A1, B1, C1, D1); \
|
||||
G2(A0, B0, C0, D0, A1, B1, C1, D1); \
|
||||
\
|
||||
UNDIAGONALIZE2(A0, B0, C0, D0, A1, B1, C1, D1); \
|
||||
} while ((void)0, 0)
|
||||
|
||||
enum {
|
||||
ARGON2_HWORDS_IN_BLOCK = ARGON2_OWORDS_IN_BLOCK / 2,
|
||||
};
|
||||
|
||||
static void fill_block(__m256i *s, const block *ref_block, block *next_block,
|
||||
int with_xor)
|
||||
{
|
||||
__m256i block_XY[ARGON2_HWORDS_IN_BLOCK];
|
||||
unsigned int i;
|
||||
|
||||
if (with_xor) {
|
||||
for (i = 0; i < ARGON2_HWORDS_IN_BLOCK; i++) {
|
||||
s[i] =_mm256_xor_si256(
|
||||
s[i], _mm256_loadu_si256((const __m256i *)ref_block->v + i));
|
||||
block_XY[i] = _mm256_xor_si256(
|
||||
s[i], _mm256_loadu_si256((const __m256i *)next_block->v + i));
|
||||
}
|
||||
|
||||
} else {
|
||||
for (i = 0; i < ARGON2_HWORDS_IN_BLOCK; i++) {
|
||||
block_XY[i] = s[i] =_mm256_xor_si256(
|
||||
s[i], _mm256_loadu_si256((const __m256i *)ref_block->v + i));
|
||||
}
|
||||
}
|
||||
|
||||
for (i = 0; i < 4; ++i) {
|
||||
BLAKE2_ROUND1(
|
||||
s[8 * i + 0], s[8 * i + 1], s[8 * i + 2], s[8 * i + 3],
|
||||
s[8 * i + 4], s[8 * i + 5], s[8 * i + 6], s[8 * i + 7]);
|
||||
}
|
||||
|
||||
for (i = 0; i < 4; ++i) {
|
||||
BLAKE2_ROUND2(
|
||||
s[4 * 0 + i], s[4 * 1 + i], s[4 * 2 + i], s[4 * 3 + i],
|
||||
s[4 * 4 + i], s[4 * 5 + i], s[4 * 6 + i], s[4 * 7 + i]);
|
||||
}
|
||||
|
||||
for (i = 0; i < ARGON2_HWORDS_IN_BLOCK; i++) {
|
||||
s[i] = _mm256_xor_si256(s[i], block_XY[i]);
|
||||
_mm256_storeu_si256((__m256i *)next_block->v + i, s[i]);
|
||||
}
|
||||
}
|
||||
|
||||
static void next_addresses(block *address_block, block *input_block)
|
||||
{
|
||||
/*Temporary zero-initialized blocks*/
|
||||
__m256i zero_block[ARGON2_HWORDS_IN_BLOCK];
|
||||
__m256i zero2_block[ARGON2_HWORDS_IN_BLOCK];
|
||||
|
||||
memset(zero_block, 0, sizeof(zero_block));
|
||||
memset(zero2_block, 0, sizeof(zero2_block));
|
||||
|
||||
/*Increasing index counter*/
|
||||
input_block->v[6]++;
|
||||
|
||||
/*First iteration of G*/
|
||||
fill_block(zero_block, input_block, address_block, 0);
|
||||
|
||||
/*Second iteration of G*/
|
||||
fill_block(zero2_block, address_block, address_block, 0);
|
||||
}
|
||||
|
||||
void fill_segment_avx2(const argon2_instance_t *instance,
|
||||
argon2_position_t position)
|
||||
{
|
||||
block *ref_block = NULL, *curr_block = NULL;
|
||||
block address_block, input_block;
|
||||
uint64_t pseudo_rand, ref_index, ref_lane;
|
||||
uint32_t prev_offset, curr_offset;
|
||||
uint32_t starting_index, i;
|
||||
__m256i state[ARGON2_HWORDS_IN_BLOCK];
|
||||
int data_independent_addressing;
|
||||
|
||||
if (instance == NULL) {
|
||||
return;
|
||||
}
|
||||
|
||||
data_independent_addressing = (instance->type == Argon2_i) ||
|
||||
(instance->type == Argon2_id && (position.pass == 0) &&
|
||||
(position.slice < ARGON2_SYNC_POINTS / 2));
|
||||
|
||||
if (data_independent_addressing) {
|
||||
init_block_value(&input_block, 0);
|
||||
|
||||
input_block.v[0] = position.pass;
|
||||
input_block.v[1] = position.lane;
|
||||
input_block.v[2] = position.slice;
|
||||
input_block.v[3] = instance->memory_blocks;
|
||||
input_block.v[4] = instance->passes;
|
||||
input_block.v[5] = instance->type;
|
||||
}
|
||||
|
||||
starting_index = 0;
|
||||
|
||||
if ((0 == position.pass) && (0 == position.slice)) {
|
||||
starting_index = 2; /* we have already generated the first two blocks */
|
||||
|
||||
/* Don't forget to generate the first block of addresses: */
|
||||
if (data_independent_addressing) {
|
||||
next_addresses(&address_block, &input_block);
|
||||
}
|
||||
}
|
||||
|
||||
/* Offset of the current block */
|
||||
curr_offset = position.lane * instance->lane_length +
|
||||
position.slice * instance->segment_length + starting_index;
|
||||
|
||||
if (0 == curr_offset % instance->lane_length) {
|
||||
/* Last block in this lane */
|
||||
prev_offset = curr_offset + instance->lane_length - 1;
|
||||
} else {
|
||||
/* Previous block */
|
||||
prev_offset = curr_offset - 1;
|
||||
}
|
||||
|
||||
memcpy(state, ((instance->memory + prev_offset)->v), ARGON2_BLOCK_SIZE);
|
||||
|
||||
for (i = starting_index; i < instance->segment_length;
|
||||
++i, ++curr_offset, ++prev_offset) {
|
||||
/*1.1 Rotating prev_offset if needed */
|
||||
if (curr_offset % instance->lane_length == 1) {
|
||||
prev_offset = curr_offset - 1;
|
||||
}
|
||||
|
||||
/* 1.2 Computing the index of the reference block */
|
||||
/* 1.2.1 Taking pseudo-random value from the previous block */
|
||||
if (data_independent_addressing) {
|
||||
if (i % ARGON2_ADDRESSES_IN_BLOCK == 0) {
|
||||
next_addresses(&address_block, &input_block);
|
||||
}
|
||||
pseudo_rand = address_block.v[i % ARGON2_ADDRESSES_IN_BLOCK];
|
||||
} else {
|
||||
pseudo_rand = instance->memory[prev_offset].v[0];
|
||||
}
|
||||
|
||||
/* 1.2.2 Computing the lane of the reference block */
|
||||
ref_lane = ((pseudo_rand >> 32)) % instance->lanes;
|
||||
|
||||
if ((position.pass == 0) && (position.slice == 0)) {
|
||||
/* Can not reference other lanes yet */
|
||||
ref_lane = position.lane;
|
||||
}
|
||||
|
||||
/* 1.2.3 Computing the number of possible reference block within the
|
||||
* lane.
|
||||
*/
|
||||
position.index = i;
|
||||
ref_index = index_alpha(instance, &position, pseudo_rand & 0xFFFFFFFF,
|
||||
ref_lane == position.lane);
|
||||
|
||||
/* 2 Creating a new block */
|
||||
ref_block =
|
||||
instance->memory + instance->lane_length * ref_lane + ref_index;
|
||||
curr_block = instance->memory + curr_offset;
|
||||
|
||||
/* version 1.2.1 and earlier: overwrite, not XOR */
|
||||
if (0 == position.pass || ARGON2_VERSION_10 == instance->version) {
|
||||
fill_block(state, ref_block, curr_block, 0);
|
||||
} else {
|
||||
fill_block(state, ref_block, curr_block, 1);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
int check_avx2(void)
|
||||
{
|
||||
return 1;
|
||||
}
|
||||
|
||||
#else
|
||||
|
||||
void fill_segment_avx2(const argon2_instance_t *instance,
|
||||
argon2_position_t position)
|
||||
{
|
||||
}
|
||||
|
||||
int check_avx2(void)
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
|
||||
#endif
|
11
src/3rdparty/argon2/arch/x86_64/lib/argon2-avx2.h
vendored
Normal file
11
src/3rdparty/argon2/arch/x86_64/lib/argon2-avx2.h
vendored
Normal file
|
@ -0,0 +1,11 @@
|
|||
#ifndef ARGON2_AVX2_H
|
||||
#define ARGON2_AVX2_H
|
||||
|
||||
#include "core.h"
|
||||
|
||||
void fill_segment_avx2(const argon2_instance_t *instance,
|
||||
argon2_position_t position);
|
||||
|
||||
int check_avx2(void);
|
||||
|
||||
#endif // ARGON2_AVX2_H
|
326
src/3rdparty/argon2/arch/x86_64/lib/argon2-avx512f.c
vendored
Normal file
326
src/3rdparty/argon2/arch/x86_64/lib/argon2-avx512f.c
vendored
Normal file
|
@ -0,0 +1,326 @@
|
|||
#include "argon2-avx512f.h"
|
||||
|
||||
#ifdef HAVE_AVX512F
|
||||
#include <stdint.h>
|
||||
#include <string.h>
|
||||
|
||||
#include <immintrin.h>
|
||||
|
||||
#define ror64(x, n) _mm512_ror_epi64((x), (n))
|
||||
|
||||
static __m512i f(__m512i x, __m512i y)
|
||||
{
|
||||
__m512i z = _mm512_mul_epu32(x, y);
|
||||
return _mm512_add_epi64(_mm512_add_epi64(x, y), _mm512_add_epi64(z, z));
|
||||
}
|
||||
|
||||
#define G1(A0, B0, C0, D0, A1, B1, C1, D1) \
|
||||
do { \
|
||||
A0 = f(A0, B0); \
|
||||
A1 = f(A1, B1); \
|
||||
\
|
||||
D0 = _mm512_xor_si512(D0, A0); \
|
||||
D1 = _mm512_xor_si512(D1, A1); \
|
||||
\
|
||||
D0 = ror64(D0, 32); \
|
||||
D1 = ror64(D1, 32); \
|
||||
\
|
||||
C0 = f(C0, D0); \
|
||||
C1 = f(C1, D1); \
|
||||
\
|
||||
B0 = _mm512_xor_si512(B0, C0); \
|
||||
B1 = _mm512_xor_si512(B1, C1); \
|
||||
\
|
||||
B0 = ror64(B0, 24); \
|
||||
B1 = ror64(B1, 24); \
|
||||
} while ((void)0, 0)
|
||||
|
||||
#define G2(A0, B0, C0, D0, A1, B1, C1, D1) \
|
||||
do { \
|
||||
A0 = f(A0, B0); \
|
||||
A1 = f(A1, B1); \
|
||||
\
|
||||
D0 = _mm512_xor_si512(D0, A0); \
|
||||
D1 = _mm512_xor_si512(D1, A1); \
|
||||
\
|
||||
D0 = ror64(D0, 16); \
|
||||
D1 = ror64(D1, 16); \
|
||||
\
|
||||
C0 = f(C0, D0); \
|
||||
C1 = f(C1, D1); \
|
||||
\
|
||||
B0 = _mm512_xor_si512(B0, C0); \
|
||||
B1 = _mm512_xor_si512(B1, C1); \
|
||||
\
|
||||
B0 = ror64(B0, 63); \
|
||||
B1 = ror64(B1, 63); \
|
||||
} while ((void)0, 0)
|
||||
|
||||
#define DIAGONALIZE(A0, B0, C0, D0, A1, B1, C1, D1) \
|
||||
do { \
|
||||
B0 = _mm512_permutex_epi64(B0, _MM_SHUFFLE(0, 3, 2, 1)); \
|
||||
B1 = _mm512_permutex_epi64(B1, _MM_SHUFFLE(0, 3, 2, 1)); \
|
||||
\
|
||||
C0 = _mm512_permutex_epi64(C0, _MM_SHUFFLE(1, 0, 3, 2)); \
|
||||
C1 = _mm512_permutex_epi64(C1, _MM_SHUFFLE(1, 0, 3, 2)); \
|
||||
\
|
||||
D0 = _mm512_permutex_epi64(D0, _MM_SHUFFLE(2, 1, 0, 3)); \
|
||||
D1 = _mm512_permutex_epi64(D1, _MM_SHUFFLE(2, 1, 0, 3)); \
|
||||
} while ((void)0, 0)
|
||||
|
||||
#define UNDIAGONALIZE(A0, B0, C0, D0, A1, B1, C1, D1) \
|
||||
do { \
|
||||
B0 = _mm512_permutex_epi64(B0, _MM_SHUFFLE(2, 1, 0, 3)); \
|
||||
B1 = _mm512_permutex_epi64(B1, _MM_SHUFFLE(2, 1, 0, 3)); \
|
||||
\
|
||||
C0 = _mm512_permutex_epi64(C0, _MM_SHUFFLE(1, 0, 3, 2)); \
|
||||
C1 = _mm512_permutex_epi64(C1, _MM_SHUFFLE(1, 0, 3, 2)); \
|
||||
\
|
||||
D0 = _mm512_permutex_epi64(D0, _MM_SHUFFLE(0, 3, 2, 1)); \
|
||||
D1 = _mm512_permutex_epi64(D1, _MM_SHUFFLE(0, 3, 2, 1)); \
|
||||
} while ((void)0, 0)
|
||||
|
||||
#define BLAKE2_ROUND(A0, B0, C0, D0, A1, B1, C1, D1) \
|
||||
do { \
|
||||
G1(A0, B0, C0, D0, A1, B1, C1, D1); \
|
||||
G2(A0, B0, C0, D0, A1, B1, C1, D1); \
|
||||
\
|
||||
DIAGONALIZE(A0, B0, C0, D0, A1, B1, C1, D1); \
|
||||
\
|
||||
G1(A0, B0, C0, D0, A1, B1, C1, D1); \
|
||||
G2(A0, B0, C0, D0, A1, B1, C1, D1); \
|
||||
\
|
||||
UNDIAGONALIZE(A0, B0, C0, D0, A1, B1, C1, D1); \
|
||||
} while ((void)0, 0)
|
||||
|
||||
#define SWAP_HALVES(A0, A1) \
|
||||
do { \
|
||||
__m512i t0, t1; \
|
||||
t0 = _mm512_shuffle_i64x2(A0, A1, _MM_SHUFFLE(1, 0, 1, 0)); \
|
||||
t1 = _mm512_shuffle_i64x2(A0, A1, _MM_SHUFFLE(3, 2, 3, 2)); \
|
||||
A0 = t0; \
|
||||
A1 = t1; \
|
||||
} while((void)0, 0)
|
||||
|
||||
#define SWAP_QUARTERS(A0, A1) \
|
||||
do { \
|
||||
SWAP_HALVES(A0, A1); \
|
||||
A0 = _mm512_permutexvar_epi64(_mm512_setr_epi64(0, 1, 4, 5, 2, 3, 6, 7), A0); \
|
||||
A1 = _mm512_permutexvar_epi64(_mm512_setr_epi64(0, 1, 4, 5, 2, 3, 6, 7), A1); \
|
||||
} while((void)0, 0)
|
||||
|
||||
#define UNSWAP_QUARTERS(A0, A1) \
|
||||
do { \
|
||||
A0 = _mm512_permutexvar_epi64(_mm512_setr_epi64(0, 1, 4, 5, 2, 3, 6, 7), A0); \
|
||||
A1 = _mm512_permutexvar_epi64(_mm512_setr_epi64(0, 1, 4, 5, 2, 3, 6, 7), A1); \
|
||||
SWAP_HALVES(A0, A1); \
|
||||
} while((void)0, 0)
|
||||
|
||||
#define BLAKE2_ROUND1(A0, C0, B0, D0, A1, C1, B1, D1) \
|
||||
do { \
|
||||
SWAP_HALVES(A0, B0); \
|
||||
SWAP_HALVES(C0, D0); \
|
||||
SWAP_HALVES(A1, B1); \
|
||||
SWAP_HALVES(C1, D1); \
|
||||
BLAKE2_ROUND(A0, B0, C0, D0, A1, B1, C1, D1); \
|
||||
SWAP_HALVES(A0, B0); \
|
||||
SWAP_HALVES(C0, D0); \
|
||||
SWAP_HALVES(A1, B1); \
|
||||
SWAP_HALVES(C1, D1); \
|
||||
} while ((void)0, 0)
|
||||
|
||||
#define BLAKE2_ROUND2(A0, A1, B0, B1, C0, C1, D0, D1) \
|
||||
do { \
|
||||
SWAP_QUARTERS(A0, A1); \
|
||||
SWAP_QUARTERS(B0, B1); \
|
||||
SWAP_QUARTERS(C0, C1); \
|
||||
SWAP_QUARTERS(D0, D1); \
|
||||
BLAKE2_ROUND(A0, B0, C0, D0, A1, B1, C1, D1); \
|
||||
UNSWAP_QUARTERS(A0, A1); \
|
||||
UNSWAP_QUARTERS(B0, B1); \
|
||||
UNSWAP_QUARTERS(C0, C1); \
|
||||
UNSWAP_QUARTERS(D0, D1); \
|
||||
} while ((void)0, 0)
|
||||
|
||||
enum {
|
||||
ARGON2_VECS_IN_BLOCK = ARGON2_OWORDS_IN_BLOCK / 4,
|
||||
};
|
||||
|
||||
static void fill_block(__m512i *s, const block *ref_block, block *next_block,
|
||||
int with_xor)
|
||||
{
|
||||
__m512i block_XY[ARGON2_VECS_IN_BLOCK];
|
||||
unsigned int i;
|
||||
|
||||
if (with_xor) {
|
||||
for (i = 0; i < ARGON2_VECS_IN_BLOCK; i++) {
|
||||
s[i] =_mm512_xor_si512(
|
||||
s[i], _mm512_loadu_si512((const __m512i *)ref_block->v + i));
|
||||
block_XY[i] = _mm512_xor_si512(
|
||||
s[i], _mm512_loadu_si512((const __m512i *)next_block->v + i));
|
||||
}
|
||||
|
||||
} else {
|
||||
for (i = 0; i < ARGON2_VECS_IN_BLOCK; i++) {
|
||||
block_XY[i] = s[i] =_mm512_xor_si512(
|
||||
s[i], _mm512_loadu_si512((const __m512i *)ref_block->v + i));
|
||||
}
|
||||
}
|
||||
|
||||
for (i = 0; i < 2; ++i) {
|
||||
BLAKE2_ROUND1(
|
||||
s[8 * i + 0], s[8 * i + 1], s[8 * i + 2], s[8 * i + 3],
|
||||
s[8 * i + 4], s[8 * i + 5], s[8 * i + 6], s[8 * i + 7]);
|
||||
}
|
||||
|
||||
for (i = 0; i < 2; ++i) {
|
||||
BLAKE2_ROUND2(
|
||||
s[2 * 0 + i], s[2 * 1 + i], s[2 * 2 + i], s[2 * 3 + i],
|
||||
s[2 * 4 + i], s[2 * 5 + i], s[2 * 6 + i], s[2 * 7 + i]);
|
||||
}
|
||||
|
||||
for (i = 0; i < ARGON2_VECS_IN_BLOCK; i++) {
|
||||
s[i] = _mm512_xor_si512(s[i], block_XY[i]);
|
||||
_mm512_storeu_si512((__m512i *)next_block->v + i, s[i]);
|
||||
}
|
||||
}
|
||||
|
||||
static void next_addresses(block *address_block, block *input_block)
|
||||
{
|
||||
/*Temporary zero-initialized blocks*/
|
||||
__m512i zero_block[ARGON2_VECS_IN_BLOCK];
|
||||
__m512i zero2_block[ARGON2_VECS_IN_BLOCK];
|
||||
|
||||
memset(zero_block, 0, sizeof(zero_block));
|
||||
memset(zero2_block, 0, sizeof(zero2_block));
|
||||
|
||||
/*Increasing index counter*/
|
||||
input_block->v[6]++;
|
||||
|
||||
/*First iteration of G*/
|
||||
fill_block(zero_block, input_block, address_block, 0);
|
||||
|
||||
/*Second iteration of G*/
|
||||
fill_block(zero2_block, address_block, address_block, 0);
|
||||
}
|
||||
|
||||
void fill_segment_avx512f(const argon2_instance_t *instance,
|
||||
argon2_position_t position)
|
||||
{
|
||||
block *ref_block = NULL, *curr_block = NULL;
|
||||
block address_block, input_block;
|
||||
uint64_t pseudo_rand, ref_index, ref_lane;
|
||||
uint32_t prev_offset, curr_offset;
|
||||
uint32_t starting_index, i;
|
||||
__m512i state[ARGON2_VECS_IN_BLOCK];
|
||||
int data_independent_addressing;
|
||||
|
||||
if (instance == NULL) {
|
||||
return;
|
||||
}
|
||||
|
||||
data_independent_addressing = (instance->type == Argon2_i) ||
|
||||
(instance->type == Argon2_id && (position.pass == 0) &&
|
||||
(position.slice < ARGON2_SYNC_POINTS / 2));
|
||||
|
||||
if (data_independent_addressing) {
|
||||
init_block_value(&input_block, 0);
|
||||
|
||||
input_block.v[0] = position.pass;
|
||||
input_block.v[1] = position.lane;
|
||||
input_block.v[2] = position.slice;
|
||||
input_block.v[3] = instance->memory_blocks;
|
||||
input_block.v[4] = instance->passes;
|
||||
input_block.v[5] = instance->type;
|
||||
}
|
||||
|
||||
starting_index = 0;
|
||||
|
||||
if ((0 == position.pass) && (0 == position.slice)) {
|
||||
starting_index = 2; /* we have already generated the first two blocks */
|
||||
|
||||
/* Don't forget to generate the first block of addresses: */
|
||||
if (data_independent_addressing) {
|
||||
next_addresses(&address_block, &input_block);
|
||||
}
|
||||
}
|
||||
|
||||
/* Offset of the current block */
|
||||
curr_offset = position.lane * instance->lane_length +
|
||||
position.slice * instance->segment_length + starting_index;
|
||||
|
||||
if (0 == curr_offset % instance->lane_length) {
|
||||
/* Last block in this lane */
|
||||
prev_offset = curr_offset + instance->lane_length - 1;
|
||||
} else {
|
||||
/* Previous block */
|
||||
prev_offset = curr_offset - 1;
|
||||
}
|
||||
|
||||
memcpy(state, ((instance->memory + prev_offset)->v), ARGON2_BLOCK_SIZE);
|
||||
|
||||
for (i = starting_index; i < instance->segment_length;
|
||||
++i, ++curr_offset, ++prev_offset) {
|
||||
/*1.1 Rotating prev_offset if needed */
|
||||
if (curr_offset % instance->lane_length == 1) {
|
||||
prev_offset = curr_offset - 1;
|
||||
}
|
||||
|
||||
/* 1.2 Computing the index of the reference block */
|
||||
/* 1.2.1 Taking pseudo-random value from the previous block */
|
||||
if (data_independent_addressing) {
|
||||
if (i % ARGON2_ADDRESSES_IN_BLOCK == 0) {
|
||||
next_addresses(&address_block, &input_block);
|
||||
}
|
||||
pseudo_rand = address_block.v[i % ARGON2_ADDRESSES_IN_BLOCK];
|
||||
} else {
|
||||
pseudo_rand = instance->memory[prev_offset].v[0];
|
||||
}
|
||||
|
||||
/* 1.2.2 Computing the lane of the reference block */
|
||||
ref_lane = ((pseudo_rand >> 32)) % instance->lanes;
|
||||
|
||||
if ((position.pass == 0) && (position.slice == 0)) {
|
||||
/* Can not reference other lanes yet */
|
||||
ref_lane = position.lane;
|
||||
}
|
||||
|
||||
/* 1.2.3 Computing the number of possible reference block within the
|
||||
* lane.
|
||||
*/
|
||||
position.index = i;
|
||||
ref_index = index_alpha(instance, &position, pseudo_rand & 0xFFFFFFFF,
|
||||
ref_lane == position.lane);
|
||||
|
||||
/* 2 Creating a new block */
|
||||
ref_block =
|
||||
instance->memory + instance->lane_length * ref_lane + ref_index;
|
||||
curr_block = instance->memory + curr_offset;
|
||||
|
||||
/* version 1.2.1 and earlier: overwrite, not XOR */
|
||||
if (0 == position.pass || ARGON2_VERSION_10 == instance->version) {
|
||||
fill_block(state, ref_block, curr_block, 0);
|
||||
} else {
|
||||
fill_block(state, ref_block, curr_block, 1);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
int check_avx512f(void)
|
||||
{
|
||||
return 1;
|
||||
}
|
||||
|
||||
#else
|
||||
|
||||
void fill_segment_avx512f(const argon2_instance_t *instance,
|
||||
argon2_position_t position)
|
||||
{
|
||||
}
|
||||
|
||||
int check_avx512f(void)
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
|
||||
#endif
|
11
src/3rdparty/argon2/arch/x86_64/lib/argon2-avx512f.h
vendored
Normal file
11
src/3rdparty/argon2/arch/x86_64/lib/argon2-avx512f.h
vendored
Normal file
|
@ -0,0 +1,11 @@
|
|||
#ifndef ARGON2_AVX512F_H
|
||||
#define ARGON2_AVX512F_H
|
||||
|
||||
#include "core.h"
|
||||
|
||||
void fill_segment_avx512f(const argon2_instance_t *instance,
|
||||
argon2_position_t position);
|
||||
|
||||
int check_avx512f(void);
|
||||
|
||||
#endif // ARGON2_AVX512F_H
|
122
src/3rdparty/argon2/arch/x86_64/lib/argon2-sse2.c
vendored
Normal file
122
src/3rdparty/argon2/arch/x86_64/lib/argon2-sse2.c
vendored
Normal file
|
@ -0,0 +1,122 @@
|
|||
#include "argon2-sse2.h"
|
||||
|
||||
#ifdef HAVE_SSE2
|
||||
#include <immintrin.h>
|
||||
|
||||
#define ror64_16(x) \
|
||||
_mm_shufflehi_epi16( \
|
||||
_mm_shufflelo_epi16((x), _MM_SHUFFLE(0, 3, 2, 1)), \
|
||||
_MM_SHUFFLE(0, 3, 2, 1))
|
||||
#define ror64_24(x) \
|
||||
_mm_xor_si128(_mm_srli_epi64((x), 24), _mm_slli_epi64((x), 40))
|
||||
#define ror64_32(x) _mm_shuffle_epi32((x), _MM_SHUFFLE(2, 3, 0, 1))
|
||||
#define ror64_63(x) \
|
||||
_mm_xor_si128(_mm_srli_epi64((x), 63), _mm_add_epi64((x), (x)))
|
||||
|
||||
static __m128i f(__m128i x, __m128i y)
|
||||
{
|
||||
__m128i z = _mm_mul_epu32(x, y);
|
||||
return _mm_add_epi64(_mm_add_epi64(x, y), _mm_add_epi64(z, z));
|
||||
}
|
||||
|
||||
#define G1(A0, B0, C0, D0, A1, B1, C1, D1) \
|
||||
do { \
|
||||
A0 = f(A0, B0); \
|
||||
A1 = f(A1, B1); \
|
||||
\
|
||||
D0 = _mm_xor_si128(D0, A0); \
|
||||
D1 = _mm_xor_si128(D1, A1); \
|
||||
\
|
||||
D0 = ror64_32(D0); \
|
||||
D1 = ror64_32(D1); \
|
||||
\
|
||||
C0 = f(C0, D0); \
|
||||
C1 = f(C1, D1); \
|
||||
\
|
||||
B0 = _mm_xor_si128(B0, C0); \
|
||||
B1 = _mm_xor_si128(B1, C1); \
|
||||
\
|
||||
B0 = ror64_24(B0); \
|
||||
B1 = ror64_24(B1); \
|
||||
} while ((void)0, 0)
|
||||
|
||||
#define G2(A0, B0, C0, D0, A1, B1, C1, D1) \
|
||||
do { \
|
||||
A0 = f(A0, B0); \
|
||||
A1 = f(A1, B1); \
|
||||
\
|
||||
D0 = _mm_xor_si128(D0, A0); \
|
||||
D1 = _mm_xor_si128(D1, A1); \
|
||||
\
|
||||
D0 = ror64_16(D0); \
|
||||
D1 = ror64_16(D1); \
|
||||
\
|
||||
C0 = f(C0, D0); \
|
||||
C1 = f(C1, D1); \
|
||||
\
|
||||
B0 = _mm_xor_si128(B0, C0); \
|
||||
B1 = _mm_xor_si128(B1, C1); \
|
||||
\
|
||||
B0 = ror64_63(B0); \
|
||||
B1 = ror64_63(B1); \
|
||||
} while ((void)0, 0)
|
||||
|
||||
#define DIAGONALIZE(A0, B0, C0, D0, A1, B1, C1, D1) \
|
||||
do { \
|
||||
__m128i t0 = D0; \
|
||||
__m128i t1 = B0; \
|
||||
D0 = _mm_unpackhi_epi64(D1, _mm_unpacklo_epi64(t0, t0)); \
|
||||
D1 = _mm_unpackhi_epi64(t0, _mm_unpacklo_epi64(D1, D1)); \
|
||||
B0 = _mm_unpackhi_epi64(B0, _mm_unpacklo_epi64(B1, B1)); \
|
||||
B1 = _mm_unpackhi_epi64(B1, _mm_unpacklo_epi64(t1, t1)); \
|
||||
} while ((void)0, 0)
|
||||
|
||||
#define UNDIAGONALIZE(A0, B0, C0, D0, A1, B1, C1, D1) \
|
||||
do { \
|
||||
__m128i t0 = B0; \
|
||||
__m128i t1 = D0; \
|
||||
B0 = _mm_unpackhi_epi64(B1, _mm_unpacklo_epi64(B0, B0)); \
|
||||
B1 = _mm_unpackhi_epi64(t0, _mm_unpacklo_epi64(B1, B1)); \
|
||||
D0 = _mm_unpackhi_epi64(D0, _mm_unpacklo_epi64(D1, D1)); \
|
||||
D1 = _mm_unpackhi_epi64(D1, _mm_unpacklo_epi64(t1, t1)); \
|
||||
} while ((void)0, 0)
|
||||
|
||||
#define BLAKE2_ROUND(A0, A1, B0, B1, C0, C1, D0, D1) \
|
||||
do { \
|
||||
G1(A0, B0, C0, D0, A1, B1, C1, D1); \
|
||||
G2(A0, B0, C0, D0, A1, B1, C1, D1); \
|
||||
\
|
||||
DIAGONALIZE(A0, B0, C0, D0, A1, B1, C1, D1); \
|
||||
\
|
||||
G1(A0, B0, C1, D0, A1, B1, C0, D1); \
|
||||
G2(A0, B0, C1, D0, A1, B1, C0, D1); \
|
||||
\
|
||||
UNDIAGONALIZE(A0, B0, C0, D0, A1, B1, C1, D1); \
|
||||
} while ((void)0, 0)
|
||||
|
||||
#include "argon2-template-128.h"
|
||||
|
||||
void fill_segment_sse2(const argon2_instance_t *instance,
|
||||
argon2_position_t position)
|
||||
{
|
||||
fill_segment_128(instance, position);
|
||||
}
|
||||
|
||||
int check_sse2(void)
|
||||
{
|
||||
return 1;
|
||||
}
|
||||
|
||||
#else
|
||||
|
||||
void fill_segment_sse2(const argon2_instance_t *instance,
|
||||
argon2_position_t position)
|
||||
{
|
||||
}
|
||||
|
||||
int check_sse2(void)
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
|
||||
#endif
|
11
src/3rdparty/argon2/arch/x86_64/lib/argon2-sse2.h
vendored
Normal file
11
src/3rdparty/argon2/arch/x86_64/lib/argon2-sse2.h
vendored
Normal file
|
@ -0,0 +1,11 @@
|
|||
#ifndef ARGON2_SSE2_H
|
||||
#define ARGON2_SSE2_H
|
||||
|
||||
#include "core.h"
|
||||
|
||||
void fill_segment_sse2(const argon2_instance_t *instance,
|
||||
argon2_position_t position);
|
||||
|
||||
int check_sse2(void);
|
||||
|
||||
#endif // ARGON2_SSE2_H
|
134
src/3rdparty/argon2/arch/x86_64/lib/argon2-ssse3.c
vendored
Normal file
134
src/3rdparty/argon2/arch/x86_64/lib/argon2-ssse3.c
vendored
Normal file
|
@ -0,0 +1,134 @@
|
|||
#include "argon2-ssse3.h"
|
||||
|
||||
#ifdef HAVE_SSSE3
|
||||
#include <string.h>
|
||||
|
||||
#include <immintrin.h>
|
||||
|
||||
#define r16 (_mm_setr_epi8( \
|
||||
2, 3, 4, 5, 6, 7, 0, 1, \
|
||||
10, 11, 12, 13, 14, 15, 8, 9))
|
||||
|
||||
#define r24 (_mm_setr_epi8( \
|
||||
3, 4, 5, 6, 7, 0, 1, 2, \
|
||||
11, 12, 13, 14, 15, 8, 9, 10))
|
||||
|
||||
#define ror64_16(x) _mm_shuffle_epi8((x), r16)
|
||||
#define ror64_24(x) _mm_shuffle_epi8((x), r24)
|
||||
#define ror64_32(x) _mm_shuffle_epi32((x), _MM_SHUFFLE(2, 3, 0, 1))
|
||||
#define ror64_63(x) \
|
||||
_mm_xor_si128(_mm_srli_epi64((x), 63), _mm_add_epi64((x), (x)))
|
||||
|
||||
static __m128i f(__m128i x, __m128i y)
|
||||
{
|
||||
__m128i z = _mm_mul_epu32(x, y);
|
||||
return _mm_add_epi64(_mm_add_epi64(x, y), _mm_add_epi64(z, z));
|
||||
}
|
||||
|
||||
#define G1(A0, B0, C0, D0, A1, B1, C1, D1) \
|
||||
do { \
|
||||
A0 = f(A0, B0); \
|
||||
A1 = f(A1, B1); \
|
||||
\
|
||||
D0 = _mm_xor_si128(D0, A0); \
|
||||
D1 = _mm_xor_si128(D1, A1); \
|
||||
\
|
||||
D0 = ror64_32(D0); \
|
||||
D1 = ror64_32(D1); \
|
||||
\
|
||||
C0 = f(C0, D0); \
|
||||
C1 = f(C1, D1); \
|
||||
\
|
||||
B0 = _mm_xor_si128(B0, C0); \
|
||||
B1 = _mm_xor_si128(B1, C1); \
|
||||
\
|
||||
B0 = ror64_24(B0); \
|
||||
B1 = ror64_24(B1); \
|
||||
} while ((void)0, 0)
|
||||
|
||||
#define G2(A0, B0, C0, D0, A1, B1, C1, D1) \
|
||||
do { \
|
||||
A0 = f(A0, B0); \
|
||||
A1 = f(A1, B1); \
|
||||
\
|
||||
D0 = _mm_xor_si128(D0, A0); \
|
||||
D1 = _mm_xor_si128(D1, A1); \
|
||||
\
|
||||
D0 = ror64_16(D0); \
|
||||
D1 = ror64_16(D1); \
|
||||
\
|
||||
C0 = f(C0, D0); \
|
||||
C1 = f(C1, D1); \
|
||||
\
|
||||
B0 = _mm_xor_si128(B0, C0); \
|
||||
B1 = _mm_xor_si128(B1, C1); \
|
||||
\
|
||||
B0 = ror64_63(B0); \
|
||||
B1 = ror64_63(B1); \
|
||||
} while ((void)0, 0)
|
||||
|
||||
#define DIAGONALIZE(A0, B0, C0, D0, A1, B1, C1, D1) \
|
||||
do { \
|
||||
__m128i t0 = _mm_alignr_epi8(B1, B0, 8); \
|
||||
__m128i t1 = _mm_alignr_epi8(B0, B1, 8); \
|
||||
B0 = t0; \
|
||||
B1 = t1; \
|
||||
\
|
||||
t0 = _mm_alignr_epi8(D1, D0, 8); \
|
||||
t1 = _mm_alignr_epi8(D0, D1, 8); \
|
||||
D0 = t1; \
|
||||
D1 = t0; \
|
||||
} while ((void)0, 0)
|
||||
|
||||
#define UNDIAGONALIZE(A0, B0, C0, D0, A1, B1, C1, D1) \
|
||||
do { \
|
||||
__m128i t0 = _mm_alignr_epi8(B0, B1, 8); \
|
||||
__m128i t1 = _mm_alignr_epi8(B1, B0, 8); \
|
||||
B0 = t0; \
|
||||
B1 = t1; \
|
||||
\
|
||||
t0 = _mm_alignr_epi8(D0, D1, 8); \
|
||||
t1 = _mm_alignr_epi8(D1, D0, 8); \
|
||||
D0 = t1; \
|
||||
D1 = t0; \
|
||||
} while ((void)0, 0)
|
||||
|
||||
#define BLAKE2_ROUND(A0, A1, B0, B1, C0, C1, D0, D1) \
|
||||
do { \
|
||||
G1(A0, B0, C0, D0, A1, B1, C1, D1); \
|
||||
G2(A0, B0, C0, D0, A1, B1, C1, D1); \
|
||||
\
|
||||
DIAGONALIZE(A0, B0, C0, D0, A1, B1, C1, D1); \
|
||||
\
|
||||
G1(A0, B0, C1, D0, A1, B1, C0, D1); \
|
||||
G2(A0, B0, C1, D0, A1, B1, C0, D1); \
|
||||
\
|
||||
UNDIAGONALIZE(A0, B0, C0, D0, A1, B1, C1, D1); \
|
||||
} while ((void)0, 0)
|
||||
|
||||
#include "argon2-template-128.h"
|
||||
|
||||
void fill_segment_ssse3(const argon2_instance_t *instance,
|
||||
argon2_position_t position)
|
||||
{
|
||||
fill_segment_128(instance, position);
|
||||
}
|
||||
|
||||
int check_ssse3(void)
|
||||
{
|
||||
return 1;
|
||||
}
|
||||
|
||||
#else
|
||||
|
||||
void fill_segment_ssse3(const argon2_instance_t *instance,
|
||||
argon2_position_t position)
|
||||
{
|
||||
}
|
||||
|
||||
int check_ssse3(void)
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
|
||||
#endif
|
11
src/3rdparty/argon2/arch/x86_64/lib/argon2-ssse3.h
vendored
Normal file
11
src/3rdparty/argon2/arch/x86_64/lib/argon2-ssse3.h
vendored
Normal file
|
@ -0,0 +1,11 @@
|
|||
#ifndef ARGON2_SSSE3_H
|
||||
#define ARGON2_SSSE3_H
|
||||
|
||||
#include "core.h"
|
||||
|
||||
void fill_segment_ssse3(const argon2_instance_t *instance,
|
||||
argon2_position_t position);
|
||||
|
||||
int check_ssse3(void);
|
||||
|
||||
#endif // ARGON2_SSSE3_H
|
164
src/3rdparty/argon2/arch/x86_64/lib/argon2-template-128.h
vendored
Normal file
164
src/3rdparty/argon2/arch/x86_64/lib/argon2-template-128.h
vendored
Normal file
|
@ -0,0 +1,164 @@
|
|||
#include <string.h>
|
||||
|
||||
#include <immintrin.h>
|
||||
|
||||
#include "core.h"
|
||||
|
||||
static void fill_block(__m128i *s, const block *ref_block, block *next_block,
|
||||
int with_xor)
|
||||
{
|
||||
__m128i block_XY[ARGON2_OWORDS_IN_BLOCK];
|
||||
unsigned int i;
|
||||
|
||||
if (with_xor) {
|
||||
for (i = 0; i < ARGON2_OWORDS_IN_BLOCK; i++) {
|
||||
s[i] = _mm_xor_si128(
|
||||
s[i], _mm_loadu_si128((const __m128i *)ref_block->v + i));
|
||||
block_XY[i] = _mm_xor_si128(
|
||||
s[i], _mm_loadu_si128((const __m128i *)next_block->v + i));
|
||||
}
|
||||
} else {
|
||||
for (i = 0; i < ARGON2_OWORDS_IN_BLOCK; i++) {
|
||||
block_XY[i] = s[i] = _mm_xor_si128(
|
||||
s[i], _mm_loadu_si128((const __m128i *)ref_block->v + i));
|
||||
}
|
||||
}
|
||||
|
||||
for (i = 0; i < 8; ++i) {
|
||||
BLAKE2_ROUND(
|
||||
s[8 * i + 0], s[8 * i + 1], s[8 * i + 2], s[8 * i + 3],
|
||||
s[8 * i + 4], s[8 * i + 5], s[8 * i + 6], s[8 * i + 7]);
|
||||
}
|
||||
|
||||
for (i = 0; i < 8; ++i) {
|
||||
BLAKE2_ROUND(
|
||||
s[8 * 0 + i], s[8 * 1 + i], s[8 * 2 + i], s[8 * 3 + i],
|
||||
s[8 * 4 + i], s[8 * 5 + i], s[8 * 6 + i], s[8 * 7 + i]);
|
||||
}
|
||||
|
||||
for (i = 0; i < ARGON2_OWORDS_IN_BLOCK; i++) {
|
||||
s[i] = _mm_xor_si128(s[i], block_XY[i]);
|
||||
_mm_storeu_si128((__m128i *)next_block->v + i, s[i]);
|
||||
}
|
||||
}
|
||||
|
||||
static void next_addresses(block *address_block, block *input_block)
|
||||
{
|
||||
/*Temporary zero-initialized blocks*/
|
||||
__m128i zero_block[ARGON2_OWORDS_IN_BLOCK];
|
||||
__m128i zero2_block[ARGON2_OWORDS_IN_BLOCK];
|
||||
|
||||
memset(zero_block, 0, sizeof(zero_block));
|
||||
memset(zero2_block, 0, sizeof(zero2_block));
|
||||
|
||||
/*Increasing index counter*/
|
||||
input_block->v[6]++;
|
||||
|
||||
/*First iteration of G*/
|
||||
fill_block(zero_block, input_block, address_block, 0);
|
||||
|
||||
/*Second iteration of G*/
|
||||
fill_block(zero2_block, address_block, address_block, 0);
|
||||
}
|
||||
|
||||
static void fill_segment_128(const argon2_instance_t *instance,
|
||||
argon2_position_t position)
|
||||
{
|
||||
block *ref_block = NULL, *curr_block = NULL;
|
||||
block address_block, input_block;
|
||||
uint64_t pseudo_rand, ref_index, ref_lane;
|
||||
uint32_t prev_offset, curr_offset;
|
||||
uint32_t starting_index, i;
|
||||
__m128i state[ARGON2_OWORDS_IN_BLOCK];
|
||||
int data_independent_addressing;
|
||||
|
||||
if (instance == NULL) {
|
||||
return;
|
||||
}
|
||||
|
||||
data_independent_addressing = (instance->type == Argon2_i) ||
|
||||
(instance->type == Argon2_id && (position.pass == 0) &&
|
||||
(position.slice < ARGON2_SYNC_POINTS / 2));
|
||||
|
||||
if (data_independent_addressing) {
|
||||
init_block_value(&input_block, 0);
|
||||
|
||||
input_block.v[0] = position.pass;
|
||||
input_block.v[1] = position.lane;
|
||||
input_block.v[2] = position.slice;
|
||||
input_block.v[3] = instance->memory_blocks;
|
||||
input_block.v[4] = instance->passes;
|
||||
input_block.v[5] = instance->type;
|
||||
}
|
||||
|
||||
starting_index = 0;
|
||||
|
||||
if ((0 == position.pass) && (0 == position.slice)) {
|
||||
starting_index = 2; /* we have already generated the first two blocks */
|
||||
|
||||
/* Don't forget to generate the first block of addresses: */
|
||||
if (data_independent_addressing) {
|
||||
next_addresses(&address_block, &input_block);
|
||||
}
|
||||
}
|
||||
|
||||
/* Offset of the current block */
|
||||
curr_offset = position.lane * instance->lane_length +
|
||||
position.slice * instance->segment_length + starting_index;
|
||||
|
||||
if (0 == curr_offset % instance->lane_length) {
|
||||
/* Last block in this lane */
|
||||
prev_offset = curr_offset + instance->lane_length - 1;
|
||||
} else {
|
||||
/* Previous block */
|
||||
prev_offset = curr_offset - 1;
|
||||
}
|
||||
|
||||
memcpy(state, ((instance->memory + prev_offset)->v), ARGON2_BLOCK_SIZE);
|
||||
|
||||
for (i = starting_index; i < instance->segment_length;
|
||||
++i, ++curr_offset, ++prev_offset) {
|
||||
/*1.1 Rotating prev_offset if needed */
|
||||
if (curr_offset % instance->lane_length == 1) {
|
||||
prev_offset = curr_offset - 1;
|
||||
}
|
||||
|
||||
/* 1.2 Computing the index of the reference block */
|
||||
/* 1.2.1 Taking pseudo-random value from the previous block */
|
||||
if (data_independent_addressing) {
|
||||
if (i % ARGON2_ADDRESSES_IN_BLOCK == 0) {
|
||||
next_addresses(&address_block, &input_block);
|
||||
}
|
||||
pseudo_rand = address_block.v[i % ARGON2_ADDRESSES_IN_BLOCK];
|
||||
} else {
|
||||
pseudo_rand = instance->memory[prev_offset].v[0];
|
||||
}
|
||||
|
||||
/* 1.2.2 Computing the lane of the reference block */
|
||||
ref_lane = ((pseudo_rand >> 32)) % instance->lanes;
|
||||
|
||||
if ((position.pass == 0) && (position.slice == 0)) {
|
||||
/* Can not reference other lanes yet */
|
||||
ref_lane = position.lane;
|
||||
}
|
||||
|
||||
/* 1.2.3 Computing the number of possible reference block within the
|
||||
* lane.
|
||||
*/
|
||||
position.index = i;
|
||||
ref_index = index_alpha(instance, &position, pseudo_rand & 0xFFFFFFFF,
|
||||
ref_lane == position.lane);
|
||||
|
||||
/* 2 Creating a new block */
|
||||
ref_block =
|
||||
instance->memory + instance->lane_length * ref_lane + ref_index;
|
||||
curr_block = instance->memory + curr_offset;
|
||||
|
||||
/* version 1.2.1 and earlier: overwrite, not XOR */
|
||||
if (0 == position.pass || ARGON2_VERSION_10 == instance->version) {
|
||||
fill_block(state, ref_block, curr_block, 0);
|
||||
} else {
|
||||
fill_block(state, ref_block, curr_block, 1);
|
||||
}
|
||||
}
|
||||
}
|
122
src/3rdparty/argon2/arch/x86_64/lib/argon2-xop.c
vendored
Normal file
122
src/3rdparty/argon2/arch/x86_64/lib/argon2-xop.c
vendored
Normal file
|
@ -0,0 +1,122 @@
|
|||
#include "argon2-xop.h"
|
||||
|
||||
#ifdef HAVE_XOP
|
||||
#include <string.h>
|
||||
|
||||
#include <immintrin.h>
|
||||
|
||||
#define ror64(x, c) _mm_roti_epi64((x), -(c))
|
||||
|
||||
static __m128i f(__m128i x, __m128i y)
|
||||
{
|
||||
__m128i z = _mm_mul_epu32(x, y);
|
||||
return _mm_add_epi64(_mm_add_epi64(x, y), _mm_add_epi64(z, z));
|
||||
}
|
||||
|
||||
#define G1(A0, B0, C0, D0, A1, B1, C1, D1) \
|
||||
do { \
|
||||
A0 = f(A0, B0); \
|
||||
A1 = f(A1, B1); \
|
||||
\
|
||||
D0 = _mm_xor_si128(D0, A0); \
|
||||
D1 = _mm_xor_si128(D1, A1); \
|
||||
\
|
||||
D0 = ror64(D0, 32); \
|
||||
D1 = ror64(D1, 32); \
|
||||
\
|
||||
C0 = f(C0, D0); \
|
||||
C1 = f(C1, D1); \
|
||||
\
|
||||
B0 = _mm_xor_si128(B0, C0); \
|
||||
B1 = _mm_xor_si128(B1, C1); \
|
||||
\
|
||||
B0 = ror64(B0, 24); \
|
||||
B1 = ror64(B1, 24); \
|
||||
} while ((void)0, 0)
|
||||
|
||||
#define G2(A0, B0, C0, D0, A1, B1, C1, D1) \
|
||||
do { \
|
||||
A0 = f(A0, B0); \
|
||||
A1 = f(A1, B1); \
|
||||
\
|
||||
D0 = _mm_xor_si128(D0, A0); \
|
||||
D1 = _mm_xor_si128(D1, A1); \
|
||||
\
|
||||
D0 = ror64(D0, 16); \
|
||||
D1 = ror64(D1, 16); \
|
||||
\
|
||||
C0 = f(C0, D0); \
|
||||
C1 = f(C1, D1); \
|
||||
\
|
||||
B0 = _mm_xor_si128(B0, C0); \
|
||||
B1 = _mm_xor_si128(B1, C1); \
|
||||
\
|
||||
B0 = ror64(B0, 63); \
|
||||
B1 = ror64(B1, 63); \
|
||||
} while ((void)0, 0)
|
||||
|
||||
#define DIAGONALIZE(A0, B0, C0, D0, A1, B1, C1, D1) \
|
||||
do { \
|
||||
__m128i t0 = _mm_alignr_epi8(B1, B0, 8); \
|
||||
__m128i t1 = _mm_alignr_epi8(B0, B1, 8); \
|
||||
B0 = t0; \
|
||||
B1 = t1; \
|
||||
\
|
||||
t0 = _mm_alignr_epi8(D1, D0, 8); \
|
||||
t1 = _mm_alignr_epi8(D0, D1, 8); \
|
||||
D0 = t1; \
|
||||
D1 = t0; \
|
||||
} while ((void)0, 0)
|
||||
|
||||
#define UNDIAGONALIZE(A0, B0, C0, D0, A1, B1, C1, D1) \
|
||||
do { \
|
||||
__m128i t0 = _mm_alignr_epi8(B0, B1, 8); \
|
||||
__m128i t1 = _mm_alignr_epi8(B1, B0, 8); \
|
||||
B0 = t0; \
|
||||
B1 = t1; \
|
||||
\
|
||||
t0 = _mm_alignr_epi8(D0, D1, 8); \
|
||||
t1 = _mm_alignr_epi8(D1, D0, 8); \
|
||||
D0 = t1; \
|
||||
D1 = t0; \
|
||||
} while ((void)0, 0)
|
||||
|
||||
#define BLAKE2_ROUND(A0, A1, B0, B1, C0, C1, D0, D1) \
|
||||
do { \
|
||||
G1(A0, B0, C0, D0, A1, B1, C1, D1); \
|
||||
G2(A0, B0, C0, D0, A1, B1, C1, D1); \
|
||||
\
|
||||
DIAGONALIZE(A0, B0, C0, D0, A1, B1, C1, D1); \
|
||||
\
|
||||
G1(A0, B0, C1, D0, A1, B1, C0, D1); \
|
||||
G2(A0, B0, C1, D0, A1, B1, C0, D1); \
|
||||
\
|
||||
UNDIAGONALIZE(A0, B0, C0, D0, A1, B1, C1, D1); \
|
||||
} while ((void)0, 0)
|
||||
|
||||
#include "argon2-template-128.h"
|
||||
|
||||
void fill_segment_xop(const argon2_instance_t *instance,
|
||||
argon2_position_t position)
|
||||
{
|
||||
fill_segment_128(instance, position);
|
||||
}
|
||||
|
||||
int check_xop(void)
|
||||
{
|
||||
return 1;
|
||||
}
|
||||
|
||||
#else
|
||||
|
||||
void fill_segment_xop(const argon2_instance_t *instance,
|
||||
argon2_position_t position)
|
||||
{
|
||||
}
|
||||
|
||||
int check_xop(void)
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
|
||||
#endif
|
11
src/3rdparty/argon2/arch/x86_64/lib/argon2-xop.h
vendored
Normal file
11
src/3rdparty/argon2/arch/x86_64/lib/argon2-xop.h
vendored
Normal file
|
@ -0,0 +1,11 @@
|
|||
#ifndef ARGON2_XOP_H
|
||||
#define ARGON2_XOP_H
|
||||
|
||||
#include "core.h"
|
||||
|
||||
void fill_segment_xop(const argon2_instance_t *instance,
|
||||
argon2_position_t position);
|
||||
|
||||
int check_xop(void);
|
||||
|
||||
#endif // ARGON2_XOP_H
|
108
src/3rdparty/argon2/configure.ac
vendored
Normal file
108
src/3rdparty/argon2/configure.ac
vendored
Normal file
|
@ -0,0 +1,108 @@
|
|||
dnl ---------------------------------------------------------------------
|
||||
dnl Copyright (C) 2015, Ondrej Mosnacek <omosnacek@gmail.com>
|
||||
dnl
|
||||
dnl This program is free software: you can redistribute it and/or
|
||||
dnl modify it under the terms of the GNU General Public License
|
||||
dnl as published by the Free Software Foundation: either version 2
|
||||
dnl of the License, or (at your option) any later version.
|
||||
dnl
|
||||
dnl This program is distributed in the hope that it will be useful,
|
||||
dnl but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
dnl MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
dnl GNU General Public License for more details.
|
||||
dnl
|
||||
dnl You should have received a copy of the GNU General Public License
|
||||
dnl along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
dnl ---------------------------------------------------------------------
|
||||
|
||||
AC_CONFIG_MACRO_DIR([m4])
|
||||
|
||||
AC_INIT([argon2], [0.1], [])
|
||||
LT_INIT
|
||||
AM_INIT_AUTOMAKE([foreign subdir-objects])
|
||||
AM_SILENT_RULES([yes])
|
||||
|
||||
AC_PROG_CC
|
||||
AC_PROG_CC_C89
|
||||
AM_PROG_AS
|
||||
AX_PTHREAD
|
||||
|
||||
AC_CANONICAL_HOST
|
||||
|
||||
AS_CASE([$host_cpu],
|
||||
dnl [i?86], [ARCH=i386],
|
||||
[x86_64], [ARCH=x86_64],
|
||||
[ARCH=generic
|
||||
AC_MSG_WARN("No code for architecture $host_cpu; using generic implementation")]
|
||||
)
|
||||
AC_SUBST([ARCH])
|
||||
|
||||
AM_CONDITIONAL([ARCH_X86_64], [test "$ARCH" = 'x86_64'])
|
||||
AM_CONDITIONAL([ARCH_GENERIC], [test "$ARCH" = 'generic'])
|
||||
|
||||
# AX_CHECK_COMPILER_FEATURE(NAME, FLAG, TEST_SOURCE)
|
||||
# --------------------------
|
||||
AC_DEFUN([AX_CHECK_COMPILER_FEATURE], [{
|
||||
AX_CHECK_COMPILE_FLAG([-m$2], [HAVE_FLAG=1], [HAVE_FLAG=0])
|
||||
HAVE_FEATURE=0
|
||||
AS_IF([test "$HAVE_FLAG" = '1'], [{
|
||||
AC_MSG_CHECKING("whether C compiler supports $1 with -m$2...")
|
||||
|
||||
CFLAGS_BACKUP="$CFLAGS"
|
||||
CFLAGS="-m$2"
|
||||
|
||||
AC_COMPILE_IFELSE([AC_LANG_SOURCE([$3])], [HAVE_FEATURE=1])
|
||||
|
||||
CFLAGS="$CFLAGS_BACKUP"
|
||||
AS_IF([test "$HAVE_FEATURE" = '1'], [RESULT='yes'], [RESULT='no'])
|
||||
AC_MSG_RESULT([$RESULT])
|
||||
|
||||
}])
|
||||
HAVE_$1=HAVE_FEATURE
|
||||
AM_CONDITIONAL([HAVE_$1], [test "$HAVE_FEATURE" = '1'])
|
||||
}])
|
||||
|
||||
AX_CHECK_COMPILER_FEATURE([SSE2], [sse2], [[
|
||||
#include <x86intrin.h>
|
||||
|
||||
void function_sse2(__m128i *dst, const __m128i *a, const __m128i *b)
|
||||
{
|
||||
*dst = _mm_xor_si128(*a, *b);
|
||||
}
|
||||
]])
|
||||
AX_CHECK_COMPILER_FEATURE([SSSE3], [ssse3], [[
|
||||
#include <x86intrin.h>
|
||||
|
||||
void function_ssse3(__m128i *dst, const __m128i *a, const __m128i *b)
|
||||
{
|
||||
*dst = _mm_shuffle_epi8(*a, *b);
|
||||
}
|
||||
]])
|
||||
AX_CHECK_COMPILER_FEATURE([XOP], [xop], [[
|
||||
#include <x86intrin.h>
|
||||
|
||||
void function_xop(__m128i *dst, const __m128i *a, int b)
|
||||
{
|
||||
*dst = _mm_roti_epi64(*a, b);
|
||||
}
|
||||
]])
|
||||
AX_CHECK_COMPILER_FEATURE([AVX2], [avx2], [[
|
||||
#include <x86intrin.h>
|
||||
|
||||
void function_avx2(__m256i *dst, const __m256i *a, const __m256i *b)
|
||||
{
|
||||
*dst = _mm256_xor_si256(*a, *b);
|
||||
}
|
||||
]])
|
||||
AX_CHECK_COMPILER_FEATURE([AVX512F], [avx512f], [[
|
||||
#include <x86intrin.h>
|
||||
|
||||
void function_avx512f(__m512i *dst, const __m512i *a)
|
||||
{
|
||||
*dst = _mm512_ror_epi64(*a, 57);
|
||||
}
|
||||
]])
|
||||
|
||||
AC_CONFIG_FILES([Makefile])
|
||||
|
||||
AC_OUTPUT
|
478
src/3rdparty/argon2/include/argon2.h
vendored
Normal file
478
src/3rdparty/argon2/include/argon2.h
vendored
Normal file
|
@ -0,0 +1,478 @@
|
|||
/*
|
||||
* Argon2 source code package
|
||||
*
|
||||
* Written by Daniel Dinu and Dmitry Khovratovich, 2015
|
||||
*
|
||||
* This work is licensed under a Creative Commons CC0 1.0 License/Waiver.
|
||||
*
|
||||
* You should have received a copy of the CC0 Public Domain Dedication
|
||||
* along with this software. If not, see
|
||||
* <http://creativecommons.org/publicdomain/zero/1.0/>.
|
||||
*/
|
||||
|
||||
#ifndef ARGON2_H
|
||||
#define ARGON2_H
|
||||
|
||||
#include <stdint.h>
|
||||
#include <stddef.h>
|
||||
#include <stdio.h>
|
||||
#include <limits.h>
|
||||
|
||||
/* Symbols visibility control */
|
||||
#if defined(_WIN32) || defined(__CYGWIN__)
|
||||
#if defined(A2_VISCTL)
|
||||
#if defined(_MSC_VER)
|
||||
#define ARGON2_PUBLIC __declspec(dllexport)
|
||||
#else
|
||||
#define ARGON2_PUBLIC __attribute__ ((dllexport))
|
||||
#endif
|
||||
#else
|
||||
#if defined(_MSC_VER)
|
||||
#define ARGON2_PUBLIC __declspec(dllimport)
|
||||
#else
|
||||
#define ARGON2_PUBLIC /*__attribute__ ((dllimport))*/
|
||||
#endif
|
||||
#endif
|
||||
#define ARGON2_LOCAL
|
||||
#else
|
||||
#if defined(A2_VISCTL)
|
||||
#define ARGON2_PUBLIC __attribute__ ((visibility ("default")))
|
||||
#define ARGON2_LOCAL __attribute__ ((visibility ("hidden")))
|
||||
#else
|
||||
#define ARGON2_PUBLIC
|
||||
#define ARGON2_LOCAL
|
||||
#endif
|
||||
#endif
|
||||
|
||||
#if defined(__cplusplus)
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
/*
|
||||
* Argon2 input parameter restrictions
|
||||
*/
|
||||
|
||||
/* Minimum and maximum number of lanes (degree of parallelism) */
|
||||
#define ARGON2_MIN_LANES UINT32_C(1)
|
||||
#define ARGON2_MAX_LANES UINT32_C(0xFFFFFF)
|
||||
|
||||
/* Minimum and maximum number of threads */
|
||||
#define ARGON2_MIN_THREADS UINT32_C(1)
|
||||
#define ARGON2_MAX_THREADS UINT32_C(0xFFFFFF)
|
||||
|
||||
/* Number of synchronization points between lanes per pass */
|
||||
#define ARGON2_SYNC_POINTS UINT32_C(4)
|
||||
|
||||
/* Minimum and maximum digest size in bytes */
|
||||
#define ARGON2_MIN_OUTLEN UINT32_C(4)
|
||||
#define ARGON2_MAX_OUTLEN UINT32_C(0xFFFFFFFF)
|
||||
|
||||
/* Minimum and maximum number of memory blocks (each of BLOCK_SIZE bytes) */
|
||||
#define ARGON2_MIN_MEMORY (2 * ARGON2_SYNC_POINTS) /* 2 blocks per slice */
|
||||
|
||||
#define ARGON2_MIN(a, b) ((a) < (b) ? (a) : (b))
|
||||
/* Max memory size is addressing-space/2, topping at 2^32 blocks (4 TB) */
|
||||
#define ARGON2_MAX_MEMORY_BITS \
|
||||
ARGON2_MIN(UINT32_C(32), (sizeof(void *) * CHAR_BIT - 10 - 1))
|
||||
#define ARGON2_MAX_MEMORY \
|
||||
ARGON2_MIN(UINT32_C(0xFFFFFFFF), UINT64_C(1) << ARGON2_MAX_MEMORY_BITS)
|
||||
|
||||
/* Minimum and maximum number of passes */
|
||||
#define ARGON2_MIN_TIME UINT32_C(1)
|
||||
#define ARGON2_MAX_TIME UINT32_C(0xFFFFFFFF)
|
||||
|
||||
/* Minimum and maximum password length in bytes */
|
||||
#define ARGON2_MIN_PWD_LENGTH UINT32_C(0)
|
||||
#define ARGON2_MAX_PWD_LENGTH UINT32_C(0xFFFFFFFF)
|
||||
|
||||
/* Minimum and maximum associated data length in bytes */
|
||||
#define ARGON2_MIN_AD_LENGTH UINT32_C(0)
|
||||
#define ARGON2_MAX_AD_LENGTH UINT32_C(0xFFFFFFFF)
|
||||
|
||||
/* Minimum and maximum salt length in bytes */
|
||||
#define ARGON2_MIN_SALT_LENGTH UINT32_C(8)
|
||||
#define ARGON2_MAX_SALT_LENGTH UINT32_C(0xFFFFFFFF)
|
||||
|
||||
/* Minimum and maximum key length in bytes */
|
||||
#define ARGON2_MIN_SECRET UINT32_C(0)
|
||||
#define ARGON2_MAX_SECRET UINT32_C(0xFFFFFFFF)
|
||||
|
||||
/* Flags to determine which fields are securely wiped (default = no wipe). */
|
||||
#define ARGON2_DEFAULT_FLAGS UINT32_C(0)
|
||||
#define ARGON2_FLAG_CLEAR_PASSWORD (UINT32_C(1) << 0)
|
||||
#define ARGON2_FLAG_CLEAR_SECRET (UINT32_C(1) << 1)
|
||||
#define ARGON2_FLAG_GENKAT (UINT32_C(1) << 3)
|
||||
|
||||
/* Global flag to determine if we are wiping internal memory buffers. This flag
|
||||
* is defined in core.c and deafults to 1 (wipe internal memory). */
|
||||
extern int FLAG_clear_internal_memory;
|
||||
|
||||
/* Error codes */
|
||||
typedef enum Argon2_ErrorCodes {
|
||||
ARGON2_OK = 0,
|
||||
|
||||
ARGON2_OUTPUT_PTR_NULL = -1,
|
||||
|
||||
ARGON2_OUTPUT_TOO_SHORT = -2,
|
||||
ARGON2_OUTPUT_TOO_LONG = -3,
|
||||
|
||||
ARGON2_PWD_TOO_SHORT = -4,
|
||||
ARGON2_PWD_TOO_LONG = -5,
|
||||
|
||||
ARGON2_SALT_TOO_SHORT = -6,
|
||||
ARGON2_SALT_TOO_LONG = -7,
|
||||
|
||||
ARGON2_AD_TOO_SHORT = -8,
|
||||
ARGON2_AD_TOO_LONG = -9,
|
||||
|
||||
ARGON2_SECRET_TOO_SHORT = -10,
|
||||
ARGON2_SECRET_TOO_LONG = -11,
|
||||
|
||||
ARGON2_TIME_TOO_SMALL = -12,
|
||||
ARGON2_TIME_TOO_LARGE = -13,
|
||||
|
||||
ARGON2_MEMORY_TOO_LITTLE = -14,
|
||||
ARGON2_MEMORY_TOO_MUCH = -15,
|
||||
|
||||
ARGON2_LANES_TOO_FEW = -16,
|
||||
ARGON2_LANES_TOO_MANY = -17,
|
||||
|
||||
ARGON2_PWD_PTR_MISMATCH = -18, /* NULL ptr with non-zero length */
|
||||
ARGON2_SALT_PTR_MISMATCH = -19, /* NULL ptr with non-zero length */
|
||||
ARGON2_SECRET_PTR_MISMATCH = -20, /* NULL ptr with non-zero length */
|
||||
ARGON2_AD_PTR_MISMATCH = -21, /* NULL ptr with non-zero length */
|
||||
|
||||
ARGON2_MEMORY_ALLOCATION_ERROR = -22,
|
||||
|
||||
ARGON2_FREE_MEMORY_CBK_NULL = -23,
|
||||
ARGON2_ALLOCATE_MEMORY_CBK_NULL = -24,
|
||||
|
||||
ARGON2_INCORRECT_PARAMETER = -25,
|
||||
ARGON2_INCORRECT_TYPE = -26,
|
||||
|
||||
ARGON2_OUT_PTR_MISMATCH = -27,
|
||||
|
||||
ARGON2_THREADS_TOO_FEW = -28,
|
||||
ARGON2_THREADS_TOO_MANY = -29,
|
||||
|
||||
ARGON2_MISSING_ARGS = -30,
|
||||
|
||||
ARGON2_ENCODING_FAIL = -31,
|
||||
|
||||
ARGON2_DECODING_FAIL = -32,
|
||||
|
||||
ARGON2_THREAD_FAIL = -33,
|
||||
|
||||
ARGON2_DECODING_LENGTH_FAIL = -34,
|
||||
|
||||
ARGON2_VERIFY_MISMATCH = -35
|
||||
} argon2_error_codes;
|
||||
|
||||
/* Memory allocator types --- for external allocation */
|
||||
typedef int (*allocate_fptr)(uint8_t **memory, size_t bytes_to_allocate);
|
||||
typedef void (*deallocate_fptr)(uint8_t *memory, size_t bytes_to_allocate);
|
||||
|
||||
/* Argon2 external data structures */
|
||||
|
||||
/*
|
||||
*****
|
||||
* Context: structure to hold Argon2 inputs:
|
||||
* output array and its length,
|
||||
* password and its length,
|
||||
* salt and its length,
|
||||
* secret and its length,
|
||||
* associated data and its length,
|
||||
* number of passes, amount of used memory (in KBytes, can be rounded up a bit)
|
||||
* number of parallel threads that will be run.
|
||||
* All the parameters above affect the output hash value.
|
||||
* Additionally, two function pointers can be provided to allocate and
|
||||
* deallocate the memory (if NULL, memory will be allocated internally).
|
||||
* Also, three flags indicate whether to erase password, secret as soon as they
|
||||
* are pre-hashed (and thus not needed anymore), and the entire memory
|
||||
*****
|
||||
* Simplest situation: you have output array out[8], password is stored in
|
||||
* pwd[32], salt is stored in salt[16], you do not have keys nor associated
|
||||
* data. You need to spend 1 GB of RAM and you run 5 passes of Argon2d with
|
||||
* 4 parallel lanes.
|
||||
* You want to erase the password, but you're OK with last pass not being
|
||||
* erased. You want to use the default memory allocator.
|
||||
* Then you initialize:
|
||||
Argon2_Context(out,8,pwd,32,salt,16,NULL,0,NULL,0,5,1<<20,4,4,NULL,NULL,true,false,false,false)
|
||||
*/
|
||||
typedef struct Argon2_Context {
|
||||
uint8_t *out; /* output array */
|
||||
uint32_t outlen; /* digest length */
|
||||
|
||||
uint8_t *pwd; /* password array */
|
||||
uint32_t pwdlen; /* password length */
|
||||
|
||||
uint8_t *salt; /* salt array */
|
||||
uint32_t saltlen; /* salt length */
|
||||
|
||||
uint8_t *secret; /* key array */
|
||||
uint32_t secretlen; /* key length */
|
||||
|
||||
uint8_t *ad; /* associated data array */
|
||||
uint32_t adlen; /* associated data length */
|
||||
|
||||
uint32_t t_cost; /* number of passes */
|
||||
uint32_t m_cost; /* amount of memory requested (KB) */
|
||||
uint32_t lanes; /* number of lanes */
|
||||
uint32_t threads; /* maximum number of threads */
|
||||
|
||||
uint32_t version; /* version number */
|
||||
|
||||
allocate_fptr allocate_cbk; /* pointer to memory allocator */
|
||||
deallocate_fptr free_cbk; /* pointer to memory deallocator */
|
||||
|
||||
uint32_t flags; /* array of bool options */
|
||||
} argon2_context;
|
||||
|
||||
/* Argon2 primitive type */
|
||||
typedef enum Argon2_type {
|
||||
Argon2_d = 0,
|
||||
Argon2_i = 1,
|
||||
Argon2_id = 2
|
||||
} argon2_type;
|
||||
|
||||
/* Version of the algorithm */
|
||||
typedef enum Argon2_version {
|
||||
ARGON2_VERSION_10 = 0x10,
|
||||
ARGON2_VERSION_13 = 0x13,
|
||||
ARGON2_VERSION_NUMBER = ARGON2_VERSION_13
|
||||
} argon2_version;
|
||||
|
||||
/*
|
||||
* Function that gives the string representation of an argon2_type.
|
||||
* @param type The argon2_type that we want the string for
|
||||
* @param uppercase Whether the string should have the first letter uppercase
|
||||
* @return NULL if invalid type, otherwise the string representation.
|
||||
*/
|
||||
ARGON2_PUBLIC const char *argon2_type2string(argon2_type type, int uppercase);
|
||||
|
||||
/*
|
||||
* Function that performs memory-hard hashing with certain degree of parallelism
|
||||
* @param context Pointer to the Argon2 internal structure
|
||||
* @return Error code if smth is wrong, ARGON2_OK otherwise
|
||||
*/
|
||||
ARGON2_PUBLIC int argon2_ctx(argon2_context *context, argon2_type type);
|
||||
|
||||
/**
|
||||
* Hashes a password with Argon2i, producing an encoded hash
|
||||
* @param t_cost Number of iterations
|
||||
* @param m_cost Sets memory usage to m_cost kibibytes
|
||||
* @param parallelism Number of threads and compute lanes
|
||||
* @param pwd Pointer to password
|
||||
* @param pwdlen Password size in bytes
|
||||
* @param salt Pointer to salt
|
||||
* @param saltlen Salt size in bytes
|
||||
* @param hashlen Desired length of the hash in bytes
|
||||
* @param encoded Buffer where to write the encoded hash
|
||||
* @param encodedlen Size of the buffer (thus max size of the encoded hash)
|
||||
* @pre Different parallelism levels will give different results
|
||||
* @pre Returns ARGON2_OK if successful
|
||||
*/
|
||||
ARGON2_PUBLIC int argon2i_hash_encoded(const uint32_t t_cost,
|
||||
const uint32_t m_cost,
|
||||
const uint32_t parallelism,
|
||||
const void *pwd, const size_t pwdlen,
|
||||
const void *salt, const size_t saltlen,
|
||||
const size_t hashlen, char *encoded,
|
||||
const size_t encodedlen);
|
||||
|
||||
/**
|
||||
* Hashes a password with Argon2i, producing a raw hash by allocating memory at
|
||||
* @hash
|
||||
* @param t_cost Number of iterations
|
||||
* @param m_cost Sets memory usage to m_cost kibibytes
|
||||
* @param parallelism Number of threads and compute lanes
|
||||
* @param pwd Pointer to password
|
||||
* @param pwdlen Password size in bytes
|
||||
* @param salt Pointer to salt
|
||||
* @param saltlen Salt size in bytes
|
||||
* @param hash Buffer where to write the raw hash - updated by the function
|
||||
* @param hashlen Desired length of the hash in bytes
|
||||
* @pre Different parallelism levels will give different results
|
||||
* @pre Returns ARGON2_OK if successful
|
||||
*/
|
||||
ARGON2_PUBLIC int argon2i_hash_raw(const uint32_t t_cost, const uint32_t m_cost,
|
||||
const uint32_t parallelism, const void *pwd,
|
||||
const size_t pwdlen, const void *salt,
|
||||
const size_t saltlen, void *hash,
|
||||
const size_t hashlen);
|
||||
|
||||
ARGON2_PUBLIC int argon2d_hash_encoded(const uint32_t t_cost,
|
||||
const uint32_t m_cost,
|
||||
const uint32_t parallelism,
|
||||
const void *pwd, const size_t pwdlen,
|
||||
const void *salt, const size_t saltlen,
|
||||
const size_t hashlen, char *encoded,
|
||||
const size_t encodedlen);
|
||||
|
||||
ARGON2_PUBLIC int argon2d_hash_raw(const uint32_t t_cost,
|
||||
const uint32_t m_cost,
|
||||
const uint32_t parallelism, const void *pwd,
|
||||
const size_t pwdlen, const void *salt,
|
||||
const size_t saltlen, void *hash,
|
||||
const size_t hashlen);
|
||||
|
||||
ARGON2_PUBLIC int argon2id_hash_encoded(const uint32_t t_cost,
|
||||
const uint32_t m_cost,
|
||||
const uint32_t parallelism,
|
||||
const void *pwd, const size_t pwdlen,
|
||||
const void *salt, const size_t saltlen,
|
||||
const size_t hashlen, char *encoded,
|
||||
const size_t encodedlen);
|
||||
|
||||
ARGON2_PUBLIC int argon2id_hash_raw(const uint32_t t_cost,
|
||||
const uint32_t m_cost,
|
||||
const uint32_t parallelism, const void *pwd,
|
||||
const size_t pwdlen, const void *salt,
|
||||
const size_t saltlen, void *hash,
|
||||
const size_t hashlen);
|
||||
|
||||
/* generic function underlying the above ones */
|
||||
ARGON2_PUBLIC int argon2_hash(const uint32_t t_cost, const uint32_t m_cost,
|
||||
const uint32_t parallelism, const void *pwd,
|
||||
const size_t pwdlen, const void *salt,
|
||||
const size_t saltlen, void *hash,
|
||||
const size_t hashlen, char *encoded,
|
||||
const size_t encodedlen, argon2_type type,
|
||||
const uint32_t version);
|
||||
|
||||
/**
|
||||
* Verifies a password against an encoded string
|
||||
* Encoded string is restricted as in validate_inputs()
|
||||
* @param encoded String encoding parameters, salt, hash
|
||||
* @param pwd Pointer to password
|
||||
* @pre Returns ARGON2_OK if successful
|
||||
*/
|
||||
ARGON2_PUBLIC int argon2i_verify(const char *encoded, const void *pwd,
|
||||
const size_t pwdlen);
|
||||
|
||||
ARGON2_PUBLIC int argon2d_verify(const char *encoded, const void *pwd,
|
||||
const size_t pwdlen);
|
||||
|
||||
ARGON2_PUBLIC int argon2id_verify(const char *encoded, const void *pwd,
|
||||
const size_t pwdlen);
|
||||
|
||||
/* generic function underlying the above ones */
|
||||
ARGON2_PUBLIC int argon2_verify(const char *encoded, const void *pwd,
|
||||
const size_t pwdlen, argon2_type type);
|
||||
|
||||
/**
|
||||
* Argon2d: Version of Argon2 that picks memory blocks depending
|
||||
* on the password and salt. Only for side-channel-free
|
||||
* environment!!
|
||||
*****
|
||||
* @param context Pointer to current Argon2 context
|
||||
* @return Zero if successful, a non zero error code otherwise
|
||||
*/
|
||||
ARGON2_PUBLIC int argon2d_ctx(argon2_context *context);
|
||||
|
||||
/**
|
||||
* Argon2i: Version of Argon2 that picks memory blocks
|
||||
* independent on the password and salt. Good for side-channels,
|
||||
* but worse w.r.t. tradeoff attacks if only one pass is used.
|
||||
*****
|
||||
* @param context Pointer to current Argon2 context
|
||||
* @return Zero if successful, a non zero error code otherwise
|
||||
*/
|
||||
ARGON2_PUBLIC int argon2i_ctx(argon2_context *context);
|
||||
|
||||
/**
|
||||
* Argon2id: Version of Argon2 where the first half-pass over memory is
|
||||
* password-independent, the rest are password-dependent (on the password and
|
||||
* salt). OK against side channels (they reduce to 1/2-pass Argon2i), and
|
||||
* better with w.r.t. tradeoff attacks (similar to Argon2d).
|
||||
*****
|
||||
* @param context Pointer to current Argon2 context
|
||||
* @return Zero if successful, a non zero error code otherwise
|
||||
*/
|
||||
ARGON2_PUBLIC int argon2id_ctx(argon2_context *context);
|
||||
|
||||
/**
|
||||
* Verify if a given password is correct for Argon2d hashing
|
||||
* @param context Pointer to current Argon2 context
|
||||
* @param hash The password hash to verify. The length of the hash is
|
||||
* specified by the context outlen member
|
||||
* @return Zero if successful, a non zero error code otherwise
|
||||
*/
|
||||
ARGON2_PUBLIC int argon2d_verify_ctx(argon2_context *context, const char *hash);
|
||||
|
||||
/**
|
||||
* Verify if a given password is correct for Argon2i hashing
|
||||
* @param context Pointer to current Argon2 context
|
||||
* @param hash The password hash to verify. The length of the hash is
|
||||
* specified by the context outlen member
|
||||
* @return Zero if successful, a non zero error code otherwise
|
||||
*/
|
||||
ARGON2_PUBLIC int argon2i_verify_ctx(argon2_context *context, const char *hash);
|
||||
|
||||
/**
|
||||
* Verify if a given password is correct for Argon2id hashing
|
||||
* @param context Pointer to current Argon2 context
|
||||
* @param hash The password hash to verify. The length of the hash is
|
||||
* specified by the context outlen member
|
||||
* @return Zero if successful, a non zero error code otherwise
|
||||
*/
|
||||
ARGON2_PUBLIC int argon2id_verify_ctx(argon2_context *context,
|
||||
const char *hash);
|
||||
|
||||
/* generic function underlying the above ones */
|
||||
ARGON2_PUBLIC int argon2_verify_ctx(argon2_context *context, const char *hash,
|
||||
argon2_type type);
|
||||
|
||||
/**
|
||||
* Get the associated error message for given error code
|
||||
* @return The error message associated with the given error code
|
||||
*/
|
||||
ARGON2_PUBLIC const char *argon2_error_message(int error_code);
|
||||
|
||||
/**
|
||||
* Returns the encoded hash length for the given input parameters
|
||||
* @param t_cost Number of iterations
|
||||
* @param m_cost Memory usage in kibibytes
|
||||
* @param parallelism Number of threads; used to compute lanes
|
||||
* @param saltlen Salt size in bytes
|
||||
* @param hashlen Hash size in bytes
|
||||
* @param type The argon2_type that we want the encoded length for
|
||||
* @return The encoded hash length in bytes
|
||||
*/
|
||||
ARGON2_PUBLIC size_t argon2_encodedlen(uint32_t t_cost, uint32_t m_cost,
|
||||
uint32_t parallelism, uint32_t saltlen,
|
||||
uint32_t hashlen, argon2_type type);
|
||||
|
||||
/* signals availability of argon2_select_impl: */
|
||||
#define ARGON2_SELECTABLE_IMPL
|
||||
|
||||
/**
|
||||
* Selects the fastest available optimized implementation.
|
||||
* @param out The file for debug output (e. g. stderr; pass NULL for no
|
||||
* debug output)
|
||||
* @param prefix What to print before each line; NULL is equivalent to empty
|
||||
* string
|
||||
*/
|
||||
ARGON2_PUBLIC void argon2_select_impl(FILE *out, const char *prefix);
|
||||
|
||||
/* signals support for passing preallocated memory: */
|
||||
#define ARGON2_PREALLOCATED_MEMORY
|
||||
|
||||
ARGON2_PUBLIC size_t argon2_memory_size(uint32_t m_cost, uint32_t parallelism);
|
||||
|
||||
/**
|
||||
* Function that performs memory-hard hashing with certain degree of parallelism
|
||||
* @param context Pointer to the Argon2 internal structure
|
||||
* @param type The Argon2 type
|
||||
* @param memory Preallocated memory for blocks (or NULL)
|
||||
* @param memory_size The size of preallocated memory
|
||||
* @return Error code if smth is wrong, ARGON2_OK otherwise
|
||||
*/
|
||||
ARGON2_PUBLIC int argon2_ctx_mem(argon2_context *context, argon2_type type,
|
||||
void *memory, size_t memory_size);
|
||||
|
||||
#if defined(__cplusplus)
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif
|
193
src/3rdparty/argon2/lib/argon2-template-64.h
vendored
Normal file
193
src/3rdparty/argon2/lib/argon2-template-64.h
vendored
Normal file
|
@ -0,0 +1,193 @@
|
|||
#include <string.h>
|
||||
|
||||
#include "core.h"
|
||||
|
||||
#define MASK_32 UINT64_C(0xFFFFFFFF)
|
||||
|
||||
#define F(x, y) ((x) + (y) + 2 * ((x) & MASK_32) * ((y) & MASK_32))
|
||||
|
||||
#define G(a, b, c, d) \
|
||||
do { \
|
||||
a = F(a, b); \
|
||||
d = rotr64(d ^ a, 32); \
|
||||
c = F(c, d); \
|
||||
b = rotr64(b ^ c, 24); \
|
||||
a = F(a, b); \
|
||||
d = rotr64(d ^ a, 16); \
|
||||
c = F(c, d); \
|
||||
b = rotr64(b ^ c, 63); \
|
||||
} while ((void)0, 0)
|
||||
|
||||
#define BLAKE2_ROUND_NOMSG(v0, v1, v2, v3, v4, v5, v6, v7, \
|
||||
v8, v9, v10, v11, v12, v13, v14, v15) \
|
||||
do { \
|
||||
G(v0, v4, v8, v12); \
|
||||
G(v1, v5, v9, v13); \
|
||||
G(v2, v6, v10, v14); \
|
||||
G(v3, v7, v11, v15); \
|
||||
G(v0, v5, v10, v15); \
|
||||
G(v1, v6, v11, v12); \
|
||||
G(v2, v7, v8, v13); \
|
||||
G(v3, v4, v9, v14); \
|
||||
} while ((void)0, 0)
|
||||
|
||||
#define BLAKE2_ROUND_NOMSG1(v) \
|
||||
BLAKE2_ROUND_NOMSG( \
|
||||
(v)[ 0], (v)[ 1], (v)[ 2], (v)[ 3], \
|
||||
(v)[ 4], (v)[ 5], (v)[ 6], (v)[ 7], \
|
||||
(v)[ 8], (v)[ 9], (v)[10], (v)[11], \
|
||||
(v)[12], (v)[13], (v)[14], (v)[15])
|
||||
|
||||
#define BLAKE2_ROUND_NOMSG2(v) \
|
||||
BLAKE2_ROUND_NOMSG( \
|
||||
(v)[ 0], (v)[ 1], (v)[ 16], (v)[ 17], \
|
||||
(v)[ 32], (v)[ 33], (v)[ 48], (v)[ 49], \
|
||||
(v)[ 64], (v)[ 65], (v)[ 80], (v)[ 81], \
|
||||
(v)[ 96], (v)[ 97], (v)[112], (v)[113])
|
||||
|
||||
static void fill_block(const block *prev_block, const block *ref_block,
|
||||
block *next_block, int with_xor)
|
||||
{
|
||||
block blockR, block_tmp;
|
||||
|
||||
copy_block(&blockR, ref_block);
|
||||
xor_block(&blockR, prev_block);
|
||||
copy_block(&block_tmp, &blockR);
|
||||
if (with_xor) {
|
||||
xor_block(&block_tmp, next_block);
|
||||
}
|
||||
|
||||
/* Apply Blake2 on columns of 64-bit words: (0,1,...,15) , then
|
||||
(16,17,..31)... finally (112,113,...127) */
|
||||
BLAKE2_ROUND_NOMSG1(blockR.v + 0 * 16);
|
||||
BLAKE2_ROUND_NOMSG1(blockR.v + 1 * 16);
|
||||
BLAKE2_ROUND_NOMSG1(blockR.v + 2 * 16);
|
||||
BLAKE2_ROUND_NOMSG1(blockR.v + 3 * 16);
|
||||
BLAKE2_ROUND_NOMSG1(blockR.v + 4 * 16);
|
||||
BLAKE2_ROUND_NOMSG1(blockR.v + 5 * 16);
|
||||
BLAKE2_ROUND_NOMSG1(blockR.v + 6 * 16);
|
||||
BLAKE2_ROUND_NOMSG1(blockR.v + 7 * 16);
|
||||
|
||||
/* Apply Blake2 on rows of 64-bit words: (0,1,16,17,...112,113), then
|
||||
(2,3,18,19,...,114,115).. finally (14,15,30,31,...,126,127) */
|
||||
BLAKE2_ROUND_NOMSG2(blockR.v + 0 * 2);
|
||||
BLAKE2_ROUND_NOMSG2(blockR.v + 1 * 2);
|
||||
BLAKE2_ROUND_NOMSG2(blockR.v + 2 * 2);
|
||||
BLAKE2_ROUND_NOMSG2(blockR.v + 3 * 2);
|
||||
BLAKE2_ROUND_NOMSG2(blockR.v + 4 * 2);
|
||||
BLAKE2_ROUND_NOMSG2(blockR.v + 5 * 2);
|
||||
BLAKE2_ROUND_NOMSG2(blockR.v + 6 * 2);
|
||||
BLAKE2_ROUND_NOMSG2(blockR.v + 7 * 2);
|
||||
|
||||
copy_block(next_block, &block_tmp);
|
||||
xor_block(next_block, &blockR);
|
||||
}
|
||||
|
||||
static void next_addresses(block *address_block, block *input_block,
|
||||
const block *zero_block)
|
||||
{
|
||||
input_block->v[6]++;
|
||||
fill_block(zero_block, input_block, address_block, 0);
|
||||
fill_block(zero_block, address_block, address_block, 0);
|
||||
}
|
||||
|
||||
static void fill_segment_64(const argon2_instance_t *instance,
|
||||
argon2_position_t position)
|
||||
{
|
||||
block *ref_block, *curr_block, *prev_block;
|
||||
block address_block, input_block, zero_block;
|
||||
uint64_t pseudo_rand, ref_index, ref_lane;
|
||||
uint32_t prev_offset, curr_offset;
|
||||
uint32_t starting_index, i;
|
||||
int data_independent_addressing;
|
||||
|
||||
if (instance == NULL) {
|
||||
return;
|
||||
}
|
||||
|
||||
data_independent_addressing = (instance->type == Argon2_i) ||
|
||||
(instance->type == Argon2_id && (position.pass == 0) &&
|
||||
(position.slice < ARGON2_SYNC_POINTS / 2));
|
||||
|
||||
if (data_independent_addressing) {
|
||||
init_block_value(&zero_block, 0);
|
||||
init_block_value(&input_block, 0);
|
||||
|
||||
input_block.v[0] = position.pass;
|
||||
input_block.v[1] = position.lane;
|
||||
input_block.v[2] = position.slice;
|
||||
input_block.v[3] = instance->memory_blocks;
|
||||
input_block.v[4] = instance->passes;
|
||||
input_block.v[5] = instance->type;
|
||||
}
|
||||
|
||||
starting_index = 0;
|
||||
|
||||
if ((0 == position.pass) && (0 == position.slice)) {
|
||||
starting_index = 2; /* we have already generated the first two blocks */
|
||||
|
||||
/* Don't forget to generate the first block of addresses: */
|
||||
if (data_independent_addressing) {
|
||||
next_addresses(&address_block, &input_block, &zero_block);
|
||||
}
|
||||
}
|
||||
|
||||
/* Offset of the current block */
|
||||
curr_offset = position.lane * instance->lane_length +
|
||||
position.slice * instance->segment_length + starting_index;
|
||||
|
||||
if (0 == curr_offset % instance->lane_length) {
|
||||
/* Last block in this lane */
|
||||
prev_offset = curr_offset + instance->lane_length - 1;
|
||||
} else {
|
||||
/* Previous block */
|
||||
prev_offset = curr_offset - 1;
|
||||
}
|
||||
|
||||
for (i = starting_index; i < instance->segment_length;
|
||||
++i, ++curr_offset, ++prev_offset) {
|
||||
/*1.1 Rotating prev_offset if needed */
|
||||
if (curr_offset % instance->lane_length == 1) {
|
||||
prev_offset = curr_offset - 1;
|
||||
}
|
||||
|
||||
/* 1.2 Computing the index of the reference block */
|
||||
/* 1.2.1 Taking pseudo-random value from the previous block */
|
||||
if (data_independent_addressing) {
|
||||
if (i % ARGON2_ADDRESSES_IN_BLOCK == 0) {
|
||||
next_addresses(&address_block, &input_block, &zero_block);
|
||||
}
|
||||
pseudo_rand = address_block.v[i % ARGON2_ADDRESSES_IN_BLOCK];
|
||||
} else {
|
||||
pseudo_rand = instance->memory[prev_offset].v[0];
|
||||
}
|
||||
|
||||
/* 1.2.2 Computing the lane of the reference block */
|
||||
ref_lane = ((pseudo_rand >> 32)) % instance->lanes;
|
||||
|
||||
if ((position.pass == 0) && (position.slice == 0)) {
|
||||
/* Can not reference other lanes yet */
|
||||
ref_lane = position.lane;
|
||||
}
|
||||
|
||||
/* 1.2.3 Computing the number of possible reference block within the
|
||||
* lane.
|
||||
*/
|
||||
position.index = i;
|
||||
ref_index = index_alpha(instance, &position, pseudo_rand & 0xFFFFFFFF,
|
||||
ref_lane == position.lane);
|
||||
|
||||
/* 2 Creating a new block */
|
||||
ref_block =
|
||||
instance->memory + instance->lane_length * ref_lane + ref_index;
|
||||
curr_block = instance->memory + curr_offset;
|
||||
prev_block = instance->memory + prev_offset;
|
||||
|
||||
/* version 1.2.1 and earlier: overwrite, not XOR */
|
||||
if (0 == position.pass || ARGON2_VERSION_10 == instance->version) {
|
||||
fill_block(prev_block, ref_block, curr_block, 0);
|
||||
} else {
|
||||
fill_block(prev_block, ref_block, curr_block, 1);
|
||||
}
|
||||
}
|
||||
}
|
476
src/3rdparty/argon2/lib/argon2.c
vendored
Normal file
476
src/3rdparty/argon2/lib/argon2.c
vendored
Normal file
|
@ -0,0 +1,476 @@
|
|||
/*
|
||||
* Argon2 source code package
|
||||
*
|
||||
* Written by Daniel Dinu and Dmitry Khovratovich, 2015
|
||||
*
|
||||
* This work is licensed under a Creative Commons CC0 1.0 License/Waiver.
|
||||
*
|
||||
* You should have received a copy of the CC0 Public Domain Dedication along
|
||||
* with
|
||||
* this software. If not, see
|
||||
* <http://creativecommons.org/publicdomain/zero/1.0/>.
|
||||
*/
|
||||
|
||||
#include <string.h>
|
||||
#include <stdlib.h>
|
||||
#include <stdio.h>
|
||||
|
||||
#include "argon2.h"
|
||||
#include "encoding.h"
|
||||
#include "core.h"
|
||||
|
||||
const char *argon2_type2string(argon2_type type, int uppercase) {
|
||||
switch (type) {
|
||||
case Argon2_d:
|
||||
return uppercase ? "Argon2d" : "argon2d";
|
||||
case Argon2_i:
|
||||
return uppercase ? "Argon2i" : "argon2i";
|
||||
case Argon2_id:
|
||||
return uppercase ? "Argon2id" : "argon2id";
|
||||
}
|
||||
|
||||
return NULL;
|
||||
}
|
||||
|
||||
static void argon2_compute_memory_blocks(uint32_t *memory_blocks,
|
||||
uint32_t *segment_length,
|
||||
uint32_t m_cost, uint32_t lanes)
|
||||
{
|
||||
/* Minimum memory_blocks = 8L blocks, where L is the number of lanes */
|
||||
*memory_blocks = m_cost;
|
||||
if (*memory_blocks < 2 * ARGON2_SYNC_POINTS * lanes) {
|
||||
*memory_blocks = 2 * ARGON2_SYNC_POINTS * lanes;
|
||||
}
|
||||
|
||||
*segment_length = *memory_blocks / (lanes * ARGON2_SYNC_POINTS);
|
||||
/* Ensure that all segments have equal length */
|
||||
*memory_blocks = *segment_length * (lanes * ARGON2_SYNC_POINTS);
|
||||
}
|
||||
|
||||
size_t argon2_memory_size(uint32_t m_cost, uint32_t parallelism) {
|
||||
uint32_t memory_blocks, segment_length;
|
||||
argon2_compute_memory_blocks(&memory_blocks, &segment_length, m_cost,
|
||||
parallelism);
|
||||
return memory_blocks * ARGON2_BLOCK_SIZE;
|
||||
}
|
||||
|
||||
int argon2_ctx_mem(argon2_context *context, argon2_type type, void *memory,
|
||||
size_t memory_size) {
|
||||
/* 1. Validate all inputs */
|
||||
int result = validate_inputs(context);
|
||||
uint32_t memory_blocks, segment_length;
|
||||
argon2_instance_t instance;
|
||||
|
||||
if (ARGON2_OK != result) {
|
||||
return result;
|
||||
}
|
||||
|
||||
if (Argon2_d != type && Argon2_i != type && Argon2_id != type) {
|
||||
return ARGON2_INCORRECT_TYPE;
|
||||
}
|
||||
|
||||
/* 2. Align memory size */
|
||||
argon2_compute_memory_blocks(&memory_blocks, &segment_length,
|
||||
context->m_cost, context->lanes);
|
||||
|
||||
/* check for sufficient memory size: */
|
||||
if (memory != NULL && (memory_size % ARGON2_BLOCK_SIZE != 0 ||
|
||||
memory_size / ARGON2_BLOCK_SIZE < memory_blocks)) {
|
||||
return ARGON2_MEMORY_ALLOCATION_ERROR;
|
||||
}
|
||||
|
||||
instance.version = context->version;
|
||||
instance.memory = (block *)memory;
|
||||
instance.passes = context->t_cost;
|
||||
instance.memory_blocks = memory_blocks;
|
||||
instance.segment_length = segment_length;
|
||||
instance.lane_length = segment_length * ARGON2_SYNC_POINTS;
|
||||
instance.lanes = context->lanes;
|
||||
instance.threads = context->threads;
|
||||
instance.type = type;
|
||||
instance.print_internals = !!(context->flags & ARGON2_FLAG_GENKAT);
|
||||
instance.keep_memory = memory != NULL;
|
||||
|
||||
if (instance.threads > instance.lanes) {
|
||||
instance.threads = instance.lanes;
|
||||
}
|
||||
|
||||
/* 3. Initialization: Hashing inputs, allocating memory, filling first
|
||||
* blocks
|
||||
*/
|
||||
result = initialize(&instance, context);
|
||||
|
||||
if (ARGON2_OK != result) {
|
||||
return result;
|
||||
}
|
||||
|
||||
/* 4. Filling memory */
|
||||
result = fill_memory_blocks(&instance);
|
||||
|
||||
if (ARGON2_OK != result) {
|
||||
return result;
|
||||
}
|
||||
/* 5. Finalization */
|
||||
finalize(context, &instance);
|
||||
|
||||
return ARGON2_OK;
|
||||
}
|
||||
|
||||
int argon2_ctx(argon2_context *context, argon2_type type) {
|
||||
return argon2_ctx_mem(context, type, NULL, 0);
|
||||
}
|
||||
|
||||
int argon2_hash(const uint32_t t_cost, const uint32_t m_cost,
|
||||
const uint32_t parallelism, const void *pwd,
|
||||
const size_t pwdlen, const void *salt, const size_t saltlen,
|
||||
void *hash, const size_t hashlen, char *encoded,
|
||||
const size_t encodedlen, argon2_type type,
|
||||
const uint32_t version){
|
||||
|
||||
argon2_context context;
|
||||
int result;
|
||||
uint8_t *out;
|
||||
|
||||
if (pwdlen > ARGON2_MAX_PWD_LENGTH) {
|
||||
return ARGON2_PWD_TOO_LONG;
|
||||
}
|
||||
|
||||
if (saltlen > ARGON2_MAX_SALT_LENGTH) {
|
||||
return ARGON2_SALT_TOO_LONG;
|
||||
}
|
||||
|
||||
if (hashlen > ARGON2_MAX_OUTLEN) {
|
||||
return ARGON2_OUTPUT_TOO_LONG;
|
||||
}
|
||||
|
||||
if (hashlen < ARGON2_MIN_OUTLEN) {
|
||||
return ARGON2_OUTPUT_TOO_SHORT;
|
||||
}
|
||||
|
||||
out = malloc(hashlen);
|
||||
if (!out) {
|
||||
return ARGON2_MEMORY_ALLOCATION_ERROR;
|
||||
}
|
||||
|
||||
context.out = (uint8_t *)out;
|
||||
context.outlen = (uint32_t)hashlen;
|
||||
context.pwd = CONST_CAST(uint8_t *)pwd;
|
||||
context.pwdlen = (uint32_t)pwdlen;
|
||||
context.salt = CONST_CAST(uint8_t *)salt;
|
||||
context.saltlen = (uint32_t)saltlen;
|
||||
context.secret = NULL;
|
||||
context.secretlen = 0;
|
||||
context.ad = NULL;
|
||||
context.adlen = 0;
|
||||
context.t_cost = t_cost;
|
||||
context.m_cost = m_cost;
|
||||
context.lanes = parallelism;
|
||||
context.threads = parallelism;
|
||||
context.allocate_cbk = NULL;
|
||||
context.free_cbk = NULL;
|
||||
context.flags = ARGON2_DEFAULT_FLAGS;
|
||||
context.version = version;
|
||||
|
||||
result = argon2_ctx(&context, type);
|
||||
|
||||
if (result != ARGON2_OK) {
|
||||
clear_internal_memory(out, hashlen);
|
||||
free(out);
|
||||
return result;
|
||||
}
|
||||
|
||||
/* if raw hash requested, write it */
|
||||
if (hash) {
|
||||
memcpy(hash, out, hashlen);
|
||||
}
|
||||
|
||||
/* if encoding requested, write it */
|
||||
if (encoded && encodedlen) {
|
||||
if (encode_string(encoded, encodedlen, &context, type) != ARGON2_OK) {
|
||||
clear_internal_memory(out, hashlen); /* wipe buffers if error */
|
||||
clear_internal_memory(encoded, encodedlen);
|
||||
free(out);
|
||||
return ARGON2_ENCODING_FAIL;
|
||||
}
|
||||
}
|
||||
clear_internal_memory(out, hashlen);
|
||||
free(out);
|
||||
|
||||
return ARGON2_OK;
|
||||
}
|
||||
|
||||
int argon2i_hash_encoded(const uint32_t t_cost, const uint32_t m_cost,
|
||||
const uint32_t parallelism, const void *pwd,
|
||||
const size_t pwdlen, const void *salt,
|
||||
const size_t saltlen, const size_t hashlen,
|
||||
char *encoded, const size_t encodedlen) {
|
||||
|
||||
return argon2_hash(t_cost, m_cost, parallelism, pwd, pwdlen, salt, saltlen,
|
||||
NULL, hashlen, encoded, encodedlen, Argon2_i,
|
||||
ARGON2_VERSION_NUMBER);
|
||||
}
|
||||
|
||||
int argon2i_hash_raw(const uint32_t t_cost, const uint32_t m_cost,
|
||||
const uint32_t parallelism, const void *pwd,
|
||||
const size_t pwdlen, const void *salt,
|
||||
const size_t saltlen, void *hash, const size_t hashlen) {
|
||||
|
||||
return argon2_hash(t_cost, m_cost, parallelism, pwd, pwdlen, salt, saltlen,
|
||||
hash, hashlen, NULL, 0, Argon2_i, ARGON2_VERSION_NUMBER);
|
||||
}
|
||||
|
||||
int argon2d_hash_encoded(const uint32_t t_cost, const uint32_t m_cost,
|
||||
const uint32_t parallelism, const void *pwd,
|
||||
const size_t pwdlen, const void *salt,
|
||||
const size_t saltlen, const size_t hashlen,
|
||||
char *encoded, const size_t encodedlen) {
|
||||
|
||||
return argon2_hash(t_cost, m_cost, parallelism, pwd, pwdlen, salt, saltlen,
|
||||
NULL, hashlen, encoded, encodedlen, Argon2_d,
|
||||
ARGON2_VERSION_NUMBER);
|
||||
}
|
||||
|
||||
int argon2d_hash_raw(const uint32_t t_cost, const uint32_t m_cost,
|
||||
const uint32_t parallelism, const void *pwd,
|
||||
const size_t pwdlen, const void *salt,
|
||||
const size_t saltlen, void *hash, const size_t hashlen) {
|
||||
|
||||
return argon2_hash(t_cost, m_cost, parallelism, pwd, pwdlen, salt, saltlen,
|
||||
hash, hashlen, NULL, 0, Argon2_d, ARGON2_VERSION_NUMBER);
|
||||
}
|
||||
|
||||
int argon2id_hash_encoded(const uint32_t t_cost, const uint32_t m_cost,
|
||||
const uint32_t parallelism, const void *pwd,
|
||||
const size_t pwdlen, const void *salt,
|
||||
const size_t saltlen, const size_t hashlen,
|
||||
char *encoded, const size_t encodedlen) {
|
||||
|
||||
return argon2_hash(t_cost, m_cost, parallelism, pwd, pwdlen, salt, saltlen,
|
||||
NULL, hashlen, encoded, encodedlen, Argon2_id,
|
||||
ARGON2_VERSION_NUMBER);
|
||||
}
|
||||
|
||||
int argon2id_hash_raw(const uint32_t t_cost, const uint32_t m_cost,
|
||||
const uint32_t parallelism, const void *pwd,
|
||||
const size_t pwdlen, const void *salt,
|
||||
const size_t saltlen, void *hash, const size_t hashlen) {
|
||||
return argon2_hash(t_cost, m_cost, parallelism, pwd, pwdlen, salt, saltlen,
|
||||
hash, hashlen, NULL, 0, Argon2_id,
|
||||
ARGON2_VERSION_NUMBER);
|
||||
}
|
||||
|
||||
static int argon2_compare(const uint8_t *b1, const uint8_t *b2, size_t len) {
|
||||
size_t i;
|
||||
uint8_t d = 0U;
|
||||
|
||||
for (i = 0U; i < len; i++) {
|
||||
d |= b1[i] ^ b2[i];
|
||||
}
|
||||
return (int)((1 & ((d - 1) >> 8)) - 1);
|
||||
}
|
||||
|
||||
int argon2_verify(const char *encoded, const void *pwd, const size_t pwdlen,
|
||||
argon2_type type) {
|
||||
|
||||
argon2_context ctx;
|
||||
uint8_t *desired_result = NULL;
|
||||
|
||||
int ret = ARGON2_OK;
|
||||
|
||||
size_t encoded_len;
|
||||
uint32_t max_field_len;
|
||||
|
||||
if (pwdlen > ARGON2_MAX_PWD_LENGTH) {
|
||||
return ARGON2_PWD_TOO_LONG;
|
||||
}
|
||||
|
||||
if (encoded == NULL) {
|
||||
return ARGON2_DECODING_FAIL;
|
||||
}
|
||||
|
||||
encoded_len = strlen(encoded);
|
||||
if (encoded_len > UINT32_MAX) {
|
||||
return ARGON2_DECODING_FAIL;
|
||||
}
|
||||
|
||||
/* No field can be longer than the encoded length */
|
||||
max_field_len = (uint32_t)encoded_len;
|
||||
|
||||
ctx.saltlen = max_field_len;
|
||||
ctx.outlen = max_field_len;
|
||||
|
||||
ctx.salt = malloc(ctx.saltlen);
|
||||
ctx.out = malloc(ctx.outlen);
|
||||
if (!ctx.salt || !ctx.out) {
|
||||
ret = ARGON2_MEMORY_ALLOCATION_ERROR;
|
||||
goto fail;
|
||||
}
|
||||
|
||||
ctx.pwd = (uint8_t *)pwd;
|
||||
ctx.pwdlen = (uint32_t)pwdlen;
|
||||
|
||||
ret = decode_string(&ctx, encoded, type);
|
||||
if (ret != ARGON2_OK) {
|
||||
goto fail;
|
||||
}
|
||||
|
||||
/* Set aside the desired result, and get a new buffer. */
|
||||
desired_result = ctx.out;
|
||||
ctx.out = malloc(ctx.outlen);
|
||||
if (!ctx.out) {
|
||||
ret = ARGON2_MEMORY_ALLOCATION_ERROR;
|
||||
goto fail;
|
||||
}
|
||||
|
||||
ret = argon2_verify_ctx(&ctx, (char *)desired_result, type);
|
||||
if (ret != ARGON2_OK) {
|
||||
goto fail;
|
||||
}
|
||||
|
||||
fail:
|
||||
free(ctx.salt);
|
||||
free(ctx.out);
|
||||
free(desired_result);
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
int argon2i_verify(const char *encoded, const void *pwd, const size_t pwdlen) {
|
||||
|
||||
return argon2_verify(encoded, pwd, pwdlen, Argon2_i);
|
||||
}
|
||||
|
||||
int argon2d_verify(const char *encoded, const void *pwd, const size_t pwdlen) {
|
||||
|
||||
return argon2_verify(encoded, pwd, pwdlen, Argon2_d);
|
||||
}
|
||||
|
||||
int argon2id_verify(const char *encoded, const void *pwd, const size_t pwdlen) {
|
||||
|
||||
return argon2_verify(encoded, pwd, pwdlen, Argon2_id);
|
||||
}
|
||||
|
||||
int argon2d_ctx(argon2_context *context) {
|
||||
return argon2_ctx(context, Argon2_d);
|
||||
}
|
||||
|
||||
int argon2i_ctx(argon2_context *context) {
|
||||
return argon2_ctx(context, Argon2_i);
|
||||
}
|
||||
|
||||
int argon2id_ctx(argon2_context *context) {
|
||||
return argon2_ctx(context, Argon2_id);
|
||||
}
|
||||
|
||||
int argon2_verify_ctx(argon2_context *context, const char *hash,
|
||||
argon2_type type) {
|
||||
int ret = argon2_ctx(context, type);
|
||||
if (ret != ARGON2_OK) {
|
||||
return ret;
|
||||
}
|
||||
|
||||
if (argon2_compare((uint8_t *)hash, context->out, context->outlen)) {
|
||||
return ARGON2_VERIFY_MISMATCH;
|
||||
}
|
||||
|
||||
return ARGON2_OK;
|
||||
}
|
||||
|
||||
int argon2d_verify_ctx(argon2_context *context, const char *hash) {
|
||||
return argon2_verify_ctx(context, hash, Argon2_d);
|
||||
}
|
||||
|
||||
int argon2i_verify_ctx(argon2_context *context, const char *hash) {
|
||||
return argon2_verify_ctx(context, hash, Argon2_i);
|
||||
}
|
||||
|
||||
int argon2id_verify_ctx(argon2_context *context, const char *hash) {
|
||||
return argon2_verify_ctx(context, hash, Argon2_id);
|
||||
}
|
||||
|
||||
const char *argon2_error_message(int error_code) {
|
||||
switch (error_code) {
|
||||
case ARGON2_OK:
|
||||
return "OK";
|
||||
case ARGON2_OUTPUT_PTR_NULL:
|
||||
return "Output pointer is NULL";
|
||||
case ARGON2_OUTPUT_TOO_SHORT:
|
||||
return "Output is too short";
|
||||
case ARGON2_OUTPUT_TOO_LONG:
|
||||
return "Output is too long";
|
||||
case ARGON2_PWD_TOO_SHORT:
|
||||
return "Password is too short";
|
||||
case ARGON2_PWD_TOO_LONG:
|
||||
return "Password is too long";
|
||||
case ARGON2_SALT_TOO_SHORT:
|
||||
return "Salt is too short";
|
||||
case ARGON2_SALT_TOO_LONG:
|
||||
return "Salt is too long";
|
||||
case ARGON2_AD_TOO_SHORT:
|
||||
return "Associated data is too short";
|
||||
case ARGON2_AD_TOO_LONG:
|
||||
return "Associated data is too long";
|
||||
case ARGON2_SECRET_TOO_SHORT:
|
||||
return "Secret is too short";
|
||||
case ARGON2_SECRET_TOO_LONG:
|
||||
return "Secret is too long";
|
||||
case ARGON2_TIME_TOO_SMALL:
|
||||
return "Time cost is too small";
|
||||
case ARGON2_TIME_TOO_LARGE:
|
||||
return "Time cost is too large";
|
||||
case ARGON2_MEMORY_TOO_LITTLE:
|
||||
return "Memory cost is too small";
|
||||
case ARGON2_MEMORY_TOO_MUCH:
|
||||
return "Memory cost is too large";
|
||||
case ARGON2_LANES_TOO_FEW:
|
||||
return "Too few lanes";
|
||||
case ARGON2_LANES_TOO_MANY:
|
||||
return "Too many lanes";
|
||||
case ARGON2_PWD_PTR_MISMATCH:
|
||||
return "Password pointer is NULL, but password length is not 0";
|
||||
case ARGON2_SALT_PTR_MISMATCH:
|
||||
return "Salt pointer is NULL, but salt length is not 0";
|
||||
case ARGON2_SECRET_PTR_MISMATCH:
|
||||
return "Secret pointer is NULL, but secret length is not 0";
|
||||
case ARGON2_AD_PTR_MISMATCH:
|
||||
return "Associated data pointer is NULL, but ad length is not 0";
|
||||
case ARGON2_MEMORY_ALLOCATION_ERROR:
|
||||
return "Memory allocation error";
|
||||
case ARGON2_FREE_MEMORY_CBK_NULL:
|
||||
return "The free memory callback is NULL";
|
||||
case ARGON2_ALLOCATE_MEMORY_CBK_NULL:
|
||||
return "The allocate memory callback is NULL";
|
||||
case ARGON2_INCORRECT_PARAMETER:
|
||||
return "Argon2_Context context is NULL";
|
||||
case ARGON2_INCORRECT_TYPE:
|
||||
return "There is no such version of Argon2";
|
||||
case ARGON2_OUT_PTR_MISMATCH:
|
||||
return "Output pointer mismatch";
|
||||
case ARGON2_THREADS_TOO_FEW:
|
||||
return "Not enough threads";
|
||||
case ARGON2_THREADS_TOO_MANY:
|
||||
return "Too many threads";
|
||||
case ARGON2_MISSING_ARGS:
|
||||
return "Missing arguments";
|
||||
case ARGON2_ENCODING_FAIL:
|
||||
return "Encoding failed";
|
||||
case ARGON2_DECODING_FAIL:
|
||||
return "Decoding failed";
|
||||
case ARGON2_THREAD_FAIL:
|
||||
return "Threading failure";
|
||||
case ARGON2_DECODING_LENGTH_FAIL:
|
||||
return "Some of encoded parameters are too long or too short";
|
||||
case ARGON2_VERIFY_MISMATCH:
|
||||
return "The password does not match the supplied hash";
|
||||
default:
|
||||
return "Unknown error code";
|
||||
}
|
||||
}
|
||||
|
||||
size_t argon2_encodedlen(uint32_t t_cost, uint32_t m_cost, uint32_t parallelism,
|
||||
uint32_t saltlen, uint32_t hashlen, argon2_type type) {
|
||||
return strlen("$$v=$m=,t=,p=$$") + strlen(argon2_type2string(type, 0)) +
|
||||
numlen(t_cost) + numlen(m_cost) + numlen(parallelism) +
|
||||
b64len(saltlen) + b64len(hashlen) + numlen(ARGON2_VERSION_NUMBER) +
|
||||
1;
|
||||
}
|
90
src/3rdparty/argon2/lib/blake2/blake2-impl.h
vendored
Normal file
90
src/3rdparty/argon2/lib/blake2/blake2-impl.h
vendored
Normal file
|
@ -0,0 +1,90 @@
|
|||
#ifndef ARGON2_BLAKE2_IMPL_H
|
||||
#define ARGON2_BLAKE2_IMPL_H
|
||||
|
||||
#include <stdint.h>
|
||||
|
||||
/* Argon2 Team - Begin Code */
|
||||
/*
|
||||
Not an exhaustive list, but should cover the majority of modern platforms
|
||||
Additionally, the code will always be correct---this is only a performance
|
||||
tweak.
|
||||
*/
|
||||
#if (defined(__BYTE_ORDER__) && \
|
||||
(__BYTE_ORDER__ == __ORDER_LITTLE_ENDIAN__)) || \
|
||||
defined(__LITTLE_ENDIAN__) || defined(__ARMEL__) || defined(__MIPSEL__) || \
|
||||
defined(__AARCH64EL__) || defined(__amd64__) || defined(__i386__) || \
|
||||
defined(_M_IX86) || defined(_M_X64) || defined(_M_AMD64) || \
|
||||
defined(_M_ARM)
|
||||
#define NATIVE_LITTLE_ENDIAN
|
||||
#endif
|
||||
/* Argon2 Team - End Code */
|
||||
|
||||
static inline uint32_t load32(const void *src) {
|
||||
#if defined(NATIVE_LITTLE_ENDIAN)
|
||||
return *(const uint32_t *)src;
|
||||
#else
|
||||
const uint8_t *p = (const uint8_t *)src;
|
||||
uint32_t w = *p++;
|
||||
w |= (uint32_t)(*p++) << 8;
|
||||
w |= (uint32_t)(*p++) << 16;
|
||||
w |= (uint32_t)(*p++) << 24;
|
||||
return w;
|
||||
#endif
|
||||
}
|
||||
|
||||
static inline uint64_t load64(const void *src) {
|
||||
#if defined(NATIVE_LITTLE_ENDIAN)
|
||||
return *(const uint64_t *)src;
|
||||
#else
|
||||
const uint8_t *p = (const uint8_t *)src;
|
||||
uint64_t w = *p++;
|
||||
w |= (uint64_t)(*p++) << 8;
|
||||
w |= (uint64_t)(*p++) << 16;
|
||||
w |= (uint64_t)(*p++) << 24;
|
||||
w |= (uint64_t)(*p++) << 32;
|
||||
w |= (uint64_t)(*p++) << 40;
|
||||
w |= (uint64_t)(*p++) << 48;
|
||||
w |= (uint64_t)(*p++) << 56;
|
||||
return w;
|
||||
#endif
|
||||
}
|
||||
|
||||
static inline void store32(void *dst, uint32_t w) {
|
||||
#if defined(NATIVE_LITTLE_ENDIAN)
|
||||
*(uint32_t *)dst = w;
|
||||
#else
|
||||
uint8_t *p = (uint8_t *)dst;
|
||||
*p++ = (uint8_t)w;
|
||||
w >>= 8;
|
||||
*p++ = (uint8_t)w;
|
||||
w >>= 8;
|
||||
*p++ = (uint8_t)w;
|
||||
w >>= 8;
|
||||
*p++ = (uint8_t)w;
|
||||
#endif
|
||||
}
|
||||
|
||||
static inline void store64(void *dst, uint64_t w) {
|
||||
#if defined(NATIVE_LITTLE_ENDIAN)
|
||||
*(uint64_t *)dst = w;
|
||||
#else
|
||||
uint8_t *p = (uint8_t *)dst;
|
||||
*p++ = (uint8_t)w;
|
||||
w >>= 8;
|
||||
*p++ = (uint8_t)w;
|
||||
w >>= 8;
|
||||
*p++ = (uint8_t)w;
|
||||
w >>= 8;
|
||||
*p++ = (uint8_t)w;
|
||||
w >>= 8;
|
||||
*p++ = (uint8_t)w;
|
||||
w >>= 8;
|
||||
*p++ = (uint8_t)w;
|
||||
w >>= 8;
|
||||
*p++ = (uint8_t)w;
|
||||
w >>= 8;
|
||||
*p++ = (uint8_t)w;
|
||||
#endif
|
||||
}
|
||||
|
||||
#endif // ARGON2_BLAKE2_IMPL_H
|
225
src/3rdparty/argon2/lib/blake2/blake2.c
vendored
Normal file
225
src/3rdparty/argon2/lib/blake2/blake2.c
vendored
Normal file
|
@ -0,0 +1,225 @@
|
|||
#include <string.h>
|
||||
|
||||
#include "blake2/blake2.h"
|
||||
#include "blake2/blake2-impl.h"
|
||||
|
||||
#include "core.h"
|
||||
|
||||
static const uint64_t blake2b_IV[8] = {
|
||||
UINT64_C(0x6a09e667f3bcc908), UINT64_C(0xbb67ae8584caa73b),
|
||||
UINT64_C(0x3c6ef372fe94f82b), UINT64_C(0xa54ff53a5f1d36f1),
|
||||
UINT64_C(0x510e527fade682d1), UINT64_C(0x9b05688c2b3e6c1f),
|
||||
UINT64_C(0x1f83d9abfb41bd6b), UINT64_C(0x5be0cd19137e2179)
|
||||
};
|
||||
|
||||
#define rotr64(x, n) (((x) >> (n)) | ((x) << (64 - (n))))
|
||||
|
||||
static const unsigned int blake2b_sigma[12][16] = {
|
||||
{0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15},
|
||||
{14, 10, 4, 8, 9, 15, 13, 6, 1, 12, 0, 2, 11, 7, 5, 3},
|
||||
{11, 8, 12, 0, 5, 2, 15, 13, 10, 14, 3, 6, 7, 1, 9, 4},
|
||||
{7, 9, 3, 1, 13, 12, 11, 14, 2, 6, 5, 10, 4, 0, 15, 8},
|
||||
{9, 0, 5, 7, 2, 4, 10, 15, 14, 1, 11, 12, 6, 8, 3, 13},
|
||||
{2, 12, 6, 10, 0, 11, 8, 3, 4, 13, 7, 5, 15, 14, 1, 9},
|
||||
{12, 5, 1, 15, 14, 13, 4, 10, 0, 7, 6, 3, 9, 2, 8, 11},
|
||||
{13, 11, 7, 14, 12, 1, 3, 9, 5, 0, 15, 4, 8, 6, 2, 10},
|
||||
{6, 15, 14, 9, 11, 3, 0, 8, 12, 2, 13, 7, 1, 4, 10, 5},
|
||||
{10, 2, 8, 4, 7, 6, 1, 5, 15, 11, 9, 14, 3, 12, 13, 0},
|
||||
{0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15},
|
||||
{14, 10, 4, 8, 9, 15, 13, 6, 1, 12, 0, 2, 11, 7, 5, 3},
|
||||
};
|
||||
|
||||
#define G(m, r, i, a, b, c, d) \
|
||||
do { \
|
||||
a = a + b + m[blake2b_sigma[r][2 * i + 0]]; \
|
||||
d = rotr64(d ^ a, 32); \
|
||||
c = c + d; \
|
||||
b = rotr64(b ^ c, 24); \
|
||||
a = a + b + m[blake2b_sigma[r][2 * i + 1]]; \
|
||||
d = rotr64(d ^ a, 16); \
|
||||
c = c + d; \
|
||||
b = rotr64(b ^ c, 63); \
|
||||
} while ((void)0, 0)
|
||||
|
||||
#define ROUND(m, v, r) \
|
||||
do { \
|
||||
G(m, r, 0, v[0], v[4], v[ 8], v[12]); \
|
||||
G(m, r, 1, v[1], v[5], v[ 9], v[13]); \
|
||||
G(m, r, 2, v[2], v[6], v[10], v[14]); \
|
||||
G(m, r, 3, v[3], v[7], v[11], v[15]); \
|
||||
G(m, r, 4, v[0], v[5], v[10], v[15]); \
|
||||
G(m, r, 5, v[1], v[6], v[11], v[12]); \
|
||||
G(m, r, 6, v[2], v[7], v[ 8], v[13]); \
|
||||
G(m, r, 7, v[3], v[4], v[ 9], v[14]); \
|
||||
} while ((void)0, 0)
|
||||
|
||||
void blake2b_compress(blake2b_state *S, const void *block, uint64_t f0)
|
||||
{
|
||||
uint64_t m[16];
|
||||
uint64_t v[16];
|
||||
|
||||
m[ 0] = load64((const uint64_t *)block + 0);
|
||||
m[ 1] = load64((const uint64_t *)block + 1);
|
||||
m[ 2] = load64((const uint64_t *)block + 2);
|
||||
m[ 3] = load64((const uint64_t *)block + 3);
|
||||
m[ 4] = load64((const uint64_t *)block + 4);
|
||||
m[ 5] = load64((const uint64_t *)block + 5);
|
||||
m[ 6] = load64((const uint64_t *)block + 6);
|
||||
m[ 7] = load64((const uint64_t *)block + 7);
|
||||
m[ 8] = load64((const uint64_t *)block + 8);
|
||||
m[ 9] = load64((const uint64_t *)block + 9);
|
||||
m[10] = load64((const uint64_t *)block + 10);
|
||||
m[11] = load64((const uint64_t *)block + 11);
|
||||
m[12] = load64((const uint64_t *)block + 12);
|
||||
m[13] = load64((const uint64_t *)block + 13);
|
||||
m[14] = load64((const uint64_t *)block + 14);
|
||||
m[15] = load64((const uint64_t *)block + 15);
|
||||
|
||||
v[ 0] = S->h[0];
|
||||
v[ 1] = S->h[1];
|
||||
v[ 2] = S->h[2];
|
||||
v[ 3] = S->h[3];
|
||||
v[ 4] = S->h[4];
|
||||
v[ 5] = S->h[5];
|
||||
v[ 6] = S->h[6];
|
||||
v[ 7] = S->h[7];
|
||||
v[ 8] = blake2b_IV[0];
|
||||
v[ 9] = blake2b_IV[1];
|
||||
v[10] = blake2b_IV[2];
|
||||
v[11] = blake2b_IV[3];
|
||||
v[12] = blake2b_IV[4] ^ S->t[0];
|
||||
v[13] = blake2b_IV[5] ^ S->t[1];
|
||||
v[14] = blake2b_IV[6] ^ f0;
|
||||
v[15] = blake2b_IV[7];
|
||||
|
||||
ROUND(m, v, 0);
|
||||
ROUND(m, v, 1);
|
||||
ROUND(m, v, 2);
|
||||
ROUND(m, v, 3);
|
||||
ROUND(m, v, 4);
|
||||
ROUND(m, v, 5);
|
||||
ROUND(m, v, 6);
|
||||
ROUND(m, v, 7);
|
||||
ROUND(m, v, 8);
|
||||
ROUND(m, v, 9);
|
||||
ROUND(m, v, 10);
|
||||
ROUND(m, v, 11);
|
||||
|
||||
S->h[0] ^= v[0] ^ v[ 8];
|
||||
S->h[1] ^= v[1] ^ v[ 9];
|
||||
S->h[2] ^= v[2] ^ v[10];
|
||||
S->h[3] ^= v[3] ^ v[11];
|
||||
S->h[4] ^= v[4] ^ v[12];
|
||||
S->h[5] ^= v[5] ^ v[13];
|
||||
S->h[6] ^= v[6] ^ v[14];
|
||||
S->h[7] ^= v[7] ^ v[15];
|
||||
}
|
||||
|
||||
static void blake2b_increment_counter(blake2b_state *S, uint64_t inc)
|
||||
{
|
||||
S->t[0] += inc;
|
||||
S->t[1] += (S->t[0] < inc);
|
||||
}
|
||||
|
||||
static void blake2b_init_state(blake2b_state *S)
|
||||
{
|
||||
memcpy(S->h, blake2b_IV, sizeof(S->h));
|
||||
S->t[1] = S->t[0] = 0;
|
||||
S->buflen = 0;
|
||||
}
|
||||
|
||||
void blake2b_init(blake2b_state *S, size_t outlen)
|
||||
{
|
||||
blake2b_init_state(S);
|
||||
/* XOR initial state with param block: */
|
||||
S->h[0] ^= (uint64_t)outlen | (UINT64_C(1) << 16) | (UINT64_C(1) << 24);
|
||||
}
|
||||
|
||||
void blake2b_update(blake2b_state *S, const void *in, size_t inlen)
|
||||
{
|
||||
const uint8_t *pin = (const uint8_t *)in;
|
||||
|
||||
if (S->buflen + inlen > BLAKE2B_BLOCKBYTES) {
|
||||
size_t left = S->buflen;
|
||||
size_t fill = BLAKE2B_BLOCKBYTES - left;
|
||||
memcpy(&S->buf[left], pin, fill);
|
||||
blake2b_increment_counter(S, BLAKE2B_BLOCKBYTES);
|
||||
blake2b_compress(S, S->buf, 0);
|
||||
S->buflen = 0;
|
||||
inlen -= fill;
|
||||
pin += fill;
|
||||
/* Avoid buffer copies when possible */
|
||||
while (inlen > BLAKE2B_BLOCKBYTES) {
|
||||
blake2b_increment_counter(S, BLAKE2B_BLOCKBYTES);
|
||||
blake2b_compress(S, pin, 0);
|
||||
inlen -= BLAKE2B_BLOCKBYTES;
|
||||
pin += BLAKE2B_BLOCKBYTES;
|
||||
}
|
||||
}
|
||||
memcpy(&S->buf[S->buflen], pin, inlen);
|
||||
S->buflen += inlen;
|
||||
}
|
||||
|
||||
void blake2b_final(blake2b_state *S, void *out, size_t outlen)
|
||||
{
|
||||
uint8_t buffer[BLAKE2B_OUTBYTES] = {0};
|
||||
unsigned int i;
|
||||
|
||||
blake2b_increment_counter(S, S->buflen);
|
||||
memset(&S->buf[S->buflen], 0, BLAKE2B_BLOCKBYTES - S->buflen); /* Padding */
|
||||
blake2b_compress(S, S->buf, UINT64_C(0xFFFFFFFFFFFFFFFF));
|
||||
|
||||
for (i = 0; i < 8; ++i) { /* Output full hash to temp buffer */
|
||||
store64(buffer + i * sizeof(uint64_t), S->h[i]);
|
||||
}
|
||||
|
||||
memcpy(out, buffer, outlen);
|
||||
clear_internal_memory(buffer, sizeof(buffer));
|
||||
clear_internal_memory(S->buf, sizeof(S->buf));
|
||||
clear_internal_memory(S->h, sizeof(S->h));
|
||||
}
|
||||
|
||||
void blake2b_long(void *out, size_t outlen, const void *in, size_t inlen)
|
||||
{
|
||||
uint8_t *pout = (uint8_t *)out;
|
||||
blake2b_state blake_state;
|
||||
uint8_t outlen_bytes[sizeof(uint32_t)] = {0};
|
||||
|
||||
store32(outlen_bytes, (uint32_t)outlen);
|
||||
if (outlen <= BLAKE2B_OUTBYTES) {
|
||||
blake2b_init(&blake_state, outlen);
|
||||
blake2b_update(&blake_state, outlen_bytes, sizeof(outlen_bytes));
|
||||
blake2b_update(&blake_state, in, inlen);
|
||||
blake2b_final(&blake_state, pout, outlen);
|
||||
} else {
|
||||
uint32_t toproduce;
|
||||
uint8_t out_buffer[BLAKE2B_OUTBYTES];
|
||||
|
||||
blake2b_init(&blake_state, BLAKE2B_OUTBYTES);
|
||||
blake2b_update(&blake_state, outlen_bytes, sizeof(outlen_bytes));
|
||||
blake2b_update(&blake_state, in, inlen);
|
||||
blake2b_final(&blake_state, out_buffer, BLAKE2B_OUTBYTES);
|
||||
|
||||
memcpy(pout, out_buffer, BLAKE2B_OUTBYTES / 2);
|
||||
pout += BLAKE2B_OUTBYTES / 2;
|
||||
toproduce = (uint32_t)outlen - BLAKE2B_OUTBYTES / 2;
|
||||
|
||||
while (toproduce > BLAKE2B_OUTBYTES) {
|
||||
blake2b_init(&blake_state, BLAKE2B_OUTBYTES);
|
||||
blake2b_update(&blake_state, out_buffer, BLAKE2B_OUTBYTES);
|
||||
blake2b_final(&blake_state, out_buffer, BLAKE2B_OUTBYTES);
|
||||
|
||||
memcpy(pout, out_buffer, BLAKE2B_OUTBYTES / 2);
|
||||
pout += BLAKE2B_OUTBYTES / 2;
|
||||
toproduce -= BLAKE2B_OUTBYTES / 2;
|
||||
}
|
||||
|
||||
blake2b_init(&blake_state, toproduce);
|
||||
blake2b_update(&blake_state, out_buffer, BLAKE2B_OUTBYTES);
|
||||
blake2b_final(&blake_state, out_buffer, toproduce);
|
||||
|
||||
memcpy(pout, out_buffer, toproduce);
|
||||
|
||||
clear_internal_memory(out_buffer, sizeof(out_buffer));
|
||||
}
|
||||
}
|
30
src/3rdparty/argon2/lib/blake2/blake2.h
vendored
Normal file
30
src/3rdparty/argon2/lib/blake2/blake2.h
vendored
Normal file
|
@ -0,0 +1,30 @@
|
|||
#ifndef ARGON2_BLAKE2_H
|
||||
#define ARGON2_BLAKE2_H
|
||||
|
||||
#include <stddef.h>
|
||||
#include <stdint.h>
|
||||
|
||||
enum blake2b_constant {
|
||||
BLAKE2B_BLOCKBYTES = 128,
|
||||
BLAKE2B_OUTBYTES = 64,
|
||||
BLAKE2B_KEYBYTES = 64,
|
||||
BLAKE2B_SALTBYTES = 16,
|
||||
BLAKE2B_PERSONALBYTES = 16
|
||||
};
|
||||
|
||||
typedef struct __blake2b_state {
|
||||
uint64_t h[8];
|
||||
uint64_t t[2];
|
||||
uint8_t buf[BLAKE2B_BLOCKBYTES];
|
||||
size_t buflen;
|
||||
} blake2b_state;
|
||||
|
||||
/* Streaming API */
|
||||
void blake2b_init(blake2b_state *S, size_t outlen);
|
||||
void blake2b_update(blake2b_state *S, const void *in, size_t inlen);
|
||||
void blake2b_final(blake2b_state *S, void *out, size_t outlen);
|
||||
|
||||
void blake2b_long(void *out, size_t outlen, const void *in, size_t inlen);
|
||||
|
||||
#endif // ARGON2_BLAKE2_H
|
||||
|
633
src/3rdparty/argon2/lib/core.c
vendored
Normal file
633
src/3rdparty/argon2/lib/core.c
vendored
Normal file
|
@ -0,0 +1,633 @@
|
|||
/*
|
||||
* Argon2 source code package
|
||||
*
|
||||
* Written by Daniel Dinu and Dmitry Khovratovich, 2015
|
||||
*
|
||||
* This work is licensed under a Creative Commons CC0 1.0 License/Waiver.
|
||||
*
|
||||
* You should have received a copy of the CC0 Public Domain Dedication along
|
||||
* with
|
||||
* this software. If not, see
|
||||
* <http://creativecommons.org/publicdomain/zero/1.0/>.
|
||||
*/
|
||||
|
||||
/*For memory wiping*/
|
||||
#ifdef _MSC_VER
|
||||
#include <windows.h>
|
||||
#include <winbase.h> /* For SecureZeroMemory */
|
||||
#endif
|
||||
#if defined __STDC_LIB_EXT1__
|
||||
#define __STDC_WANT_LIB_EXT1__ 1
|
||||
#endif
|
||||
#define VC_GE_2005(version) (version >= 1400)
|
||||
|
||||
#include <inttypes.h>
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
|
||||
#include "core.h"
|
||||
#include "thread.h"
|
||||
#include "blake2/blake2.h"
|
||||
#include "blake2/blake2-impl.h"
|
||||
|
||||
#include "genkat.h"
|
||||
|
||||
#if defined(__clang__)
|
||||
#if __has_attribute(optnone)
|
||||
#define NOT_OPTIMIZED __attribute__((optnone))
|
||||
#endif
|
||||
#elif defined(__GNUC__)
|
||||
#define GCC_VERSION \
|
||||
(__GNUC__ * 10000 + __GNUC_MINOR__ * 100 + __GNUC_PATCHLEVEL__)
|
||||
#if GCC_VERSION >= 40400
|
||||
#define NOT_OPTIMIZED __attribute__((optimize("O0")))
|
||||
#endif
|
||||
#endif
|
||||
#ifndef NOT_OPTIMIZED
|
||||
#define NOT_OPTIMIZED
|
||||
#endif
|
||||
|
||||
/***************Instance and Position constructors**********/
|
||||
void init_block_value(block *b, uint8_t in) { memset(b->v, in, sizeof(b->v)); }
|
||||
|
||||
void copy_block(block *dst, const block *src) {
|
||||
memcpy(dst->v, src->v, sizeof(uint64_t) * ARGON2_QWORDS_IN_BLOCK);
|
||||
}
|
||||
|
||||
void xor_block(block *dst, const block *src) {
|
||||
int i;
|
||||
for (i = 0; i < ARGON2_QWORDS_IN_BLOCK; ++i) {
|
||||
dst->v[i] ^= src->v[i];
|
||||
}
|
||||
}
|
||||
|
||||
static void load_block(block *dst, const void *input) {
|
||||
unsigned i;
|
||||
for (i = 0; i < ARGON2_QWORDS_IN_BLOCK; ++i) {
|
||||
dst->v[i] = load64((const uint8_t *)input + i * sizeof(dst->v[i]));
|
||||
}
|
||||
}
|
||||
|
||||
static void store_block(void *output, const block *src) {
|
||||
unsigned i;
|
||||
for (i = 0; i < ARGON2_QWORDS_IN_BLOCK; ++i) {
|
||||
store64((uint8_t *)output + i * sizeof(src->v[i]), src->v[i]);
|
||||
}
|
||||
}
|
||||
|
||||
/***************Memory functions*****************/
|
||||
|
||||
int allocate_memory(const argon2_context *context,
|
||||
argon2_instance_t *instance) {
|
||||
size_t blocks = instance->memory_blocks;
|
||||
size_t memory_size = blocks * ARGON2_BLOCK_SIZE;
|
||||
|
||||
/* 0. Check for memory supplied by user: */
|
||||
/* NOTE: Sufficient memory size is already checked in argon2_ctx_mem() */
|
||||
if (instance->memory != NULL) {
|
||||
return ARGON2_OK;
|
||||
}
|
||||
|
||||
/* 1. Check for multiplication overflow */
|
||||
if (blocks != 0 && memory_size / ARGON2_BLOCK_SIZE != blocks) {
|
||||
return ARGON2_MEMORY_ALLOCATION_ERROR;
|
||||
}
|
||||
|
||||
/* 2. Try to allocate with appropriate allocator */
|
||||
if (context->allocate_cbk) {
|
||||
(context->allocate_cbk)((uint8_t **)&instance->memory, memory_size);
|
||||
} else {
|
||||
instance->memory = malloc(memory_size);
|
||||
}
|
||||
|
||||
if (instance->memory == NULL) {
|
||||
return ARGON2_MEMORY_ALLOCATION_ERROR;
|
||||
}
|
||||
|
||||
return ARGON2_OK;
|
||||
}
|
||||
|
||||
void free_memory(const argon2_context *context,
|
||||
const argon2_instance_t *instance) {
|
||||
size_t memory_size = instance->memory_blocks * ARGON2_BLOCK_SIZE;
|
||||
|
||||
clear_internal_memory(instance->memory, memory_size);
|
||||
|
||||
if (instance->keep_memory) {
|
||||
/* user-supplied memory -- do not free */
|
||||
return;
|
||||
}
|
||||
|
||||
if (context->free_cbk) {
|
||||
(context->free_cbk)((uint8_t *)instance->memory, memory_size);
|
||||
} else {
|
||||
free(instance->memory);
|
||||
}
|
||||
}
|
||||
|
||||
void NOT_OPTIMIZED secure_wipe_memory(void *v, size_t n) {
|
||||
#if defined(_MSC_VER) && VC_GE_2005(_MSC_VER)
|
||||
SecureZeroMemory(v, n);
|
||||
#elif defined memset_s
|
||||
memset_s(v, n, 0, n);
|
||||
#elif defined(__OpenBSD__)
|
||||
explicit_bzero(v, n);
|
||||
#else
|
||||
static void *(*const volatile memset_sec)(void *, int, size_t) = &memset;
|
||||
memset_sec(v, 0, n);
|
||||
#endif
|
||||
}
|
||||
|
||||
/* Memory clear flag defaults to true. */
|
||||
int FLAG_clear_internal_memory = 1;
|
||||
void clear_internal_memory(void *v, size_t n) {
|
||||
if (FLAG_clear_internal_memory && v) {
|
||||
secure_wipe_memory(v, n);
|
||||
}
|
||||
}
|
||||
|
||||
void finalize(const argon2_context *context, argon2_instance_t *instance) {
|
||||
if (context != NULL && instance != NULL) {
|
||||
block blockhash;
|
||||
uint32_t l;
|
||||
|
||||
copy_block(&blockhash, instance->memory + instance->lane_length - 1);
|
||||
|
||||
/* XOR the last blocks */
|
||||
for (l = 1; l < instance->lanes; ++l) {
|
||||
uint32_t last_block_in_lane =
|
||||
l * instance->lane_length + (instance->lane_length - 1);
|
||||
xor_block(&blockhash, instance->memory + last_block_in_lane);
|
||||
}
|
||||
|
||||
/* Hash the result */
|
||||
{
|
||||
uint8_t blockhash_bytes[ARGON2_BLOCK_SIZE];
|
||||
store_block(blockhash_bytes, &blockhash);
|
||||
blake2b_long(context->out, context->outlen, blockhash_bytes,
|
||||
ARGON2_BLOCK_SIZE);
|
||||
/* clear blockhash and blockhash_bytes */
|
||||
clear_internal_memory(blockhash.v, ARGON2_BLOCK_SIZE);
|
||||
clear_internal_memory(blockhash_bytes, ARGON2_BLOCK_SIZE);
|
||||
}
|
||||
|
||||
if (instance->print_internals) {
|
||||
print_tag(context->out, context->outlen);
|
||||
}
|
||||
|
||||
free_memory(context, instance);
|
||||
}
|
||||
}
|
||||
|
||||
uint32_t index_alpha(const argon2_instance_t *instance,
|
||||
const argon2_position_t *position, uint32_t pseudo_rand,
|
||||
int same_lane) {
|
||||
/*
|
||||
* Pass 0:
|
||||
* This lane : all already finished segments plus already constructed
|
||||
* blocks in this segment
|
||||
* Other lanes : all already finished segments
|
||||
* Pass 1+:
|
||||
* This lane : (SYNC_POINTS - 1) last segments plus already constructed
|
||||
* blocks in this segment
|
||||
* Other lanes : (SYNC_POINTS - 1) last segments
|
||||
*/
|
||||
uint32_t reference_area_size;
|
||||
uint64_t relative_position;
|
||||
uint32_t start_position, absolute_position;
|
||||
|
||||
if (0 == position->pass) {
|
||||
/* First pass */
|
||||
if (0 == position->slice) {
|
||||
/* First slice */
|
||||
reference_area_size =
|
||||
position->index - 1; /* all but the previous */
|
||||
} else {
|
||||
if (same_lane) {
|
||||
/* The same lane => add current segment */
|
||||
reference_area_size =
|
||||
position->slice * instance->segment_length +
|
||||
position->index - 1;
|
||||
} else {
|
||||
reference_area_size =
|
||||
position->slice * instance->segment_length +
|
||||
((position->index == 0) ? (-1) : 0);
|
||||
}
|
||||
}
|
||||
} else {
|
||||
/* Second pass */
|
||||
if (same_lane) {
|
||||
reference_area_size = instance->lane_length -
|
||||
instance->segment_length + position->index -
|
||||
1;
|
||||
} else {
|
||||
reference_area_size = instance->lane_length -
|
||||
instance->segment_length +
|
||||
((position->index == 0) ? (-1) : 0);
|
||||
}
|
||||
}
|
||||
|
||||
/* 1.2.4. Mapping pseudo_rand to 0..<reference_area_size-1> and produce
|
||||
* relative position */
|
||||
relative_position = pseudo_rand;
|
||||
relative_position = relative_position * relative_position >> 32;
|
||||
relative_position = reference_area_size - 1 -
|
||||
(reference_area_size * relative_position >> 32);
|
||||
|
||||
/* 1.2.5 Computing starting position */
|
||||
start_position = 0;
|
||||
|
||||
if (0 != position->pass) {
|
||||
start_position = (position->slice == ARGON2_SYNC_POINTS - 1)
|
||||
? 0
|
||||
: (position->slice + 1) * instance->segment_length;
|
||||
}
|
||||
|
||||
/* 1.2.6. Computing absolute position */
|
||||
absolute_position = (start_position + relative_position) %
|
||||
instance->lane_length; /* absolute position */
|
||||
return absolute_position;
|
||||
}
|
||||
|
||||
#ifdef _WIN32
|
||||
static unsigned __stdcall fill_segment_thr(void *thread_data)
|
||||
#else
|
||||
static void *fill_segment_thr(void *thread_data)
|
||||
#endif
|
||||
{
|
||||
argon2_thread_data *my_data = thread_data;
|
||||
fill_segment(my_data->instance_ptr, my_data->pos);
|
||||
argon2_thread_exit();
|
||||
return 0;
|
||||
}
|
||||
|
||||
/* Single-threaded version for p=1 case */
|
||||
static int fill_memory_blocks_st(argon2_instance_t *instance) {
|
||||
uint32_t r, s, l;
|
||||
|
||||
for (r = 0; r < instance->passes; ++r) {
|
||||
for (s = 0; s < ARGON2_SYNC_POINTS; ++s) {
|
||||
for (l = 0; l < instance->lanes; ++l) {
|
||||
argon2_position_t position = { r, l, (uint8_t)s, 0 };
|
||||
fill_segment(instance, position);
|
||||
}
|
||||
}
|
||||
|
||||
if (instance->print_internals) {
|
||||
internal_kat(instance, r); /* Print all memory blocks */
|
||||
}
|
||||
}
|
||||
return ARGON2_OK;
|
||||
}
|
||||
|
||||
/* Multi-threaded version for p > 1 case */
|
||||
static int fill_memory_blocks_mt(argon2_instance_t *instance) {
|
||||
uint32_t r, s;
|
||||
argon2_thread_handle_t *thread = NULL;
|
||||
argon2_thread_data *thr_data = NULL;
|
||||
int rc = ARGON2_OK;
|
||||
|
||||
/* 1. Allocating space for threads */
|
||||
thread = calloc(instance->lanes, sizeof(argon2_thread_handle_t));
|
||||
if (thread == NULL) {
|
||||
rc = ARGON2_MEMORY_ALLOCATION_ERROR;
|
||||
goto fail;
|
||||
}
|
||||
|
||||
thr_data = calloc(instance->lanes, sizeof(argon2_thread_data));
|
||||
if (thr_data == NULL) {
|
||||
rc = ARGON2_MEMORY_ALLOCATION_ERROR;
|
||||
goto fail;
|
||||
}
|
||||
|
||||
for (r = 0; r < instance->passes; ++r) {
|
||||
for (s = 0; s < ARGON2_SYNC_POINTS; ++s) {
|
||||
uint32_t l;
|
||||
|
||||
/* 2. Calling threads */
|
||||
for (l = 0; l < instance->lanes; ++l) {
|
||||
argon2_position_t position;
|
||||
|
||||
/* 2.1 Join a thread if limit is exceeded */
|
||||
if (l >= instance->threads) {
|
||||
if (argon2_thread_join(thread[l - instance->threads])) {
|
||||
rc = ARGON2_THREAD_FAIL;
|
||||
goto fail;
|
||||
}
|
||||
}
|
||||
|
||||
/* 2.2 Create thread */
|
||||
position.pass = r;
|
||||
position.lane = l;
|
||||
position.slice = (uint8_t)s;
|
||||
position.index = 0;
|
||||
thr_data[l].instance_ptr =
|
||||
instance; /* preparing the thread input */
|
||||
memcpy(&(thr_data[l].pos), &position,
|
||||
sizeof(argon2_position_t));
|
||||
if (argon2_thread_create(&thread[l], &fill_segment_thr,
|
||||
(void *)&thr_data[l])) {
|
||||
rc = ARGON2_THREAD_FAIL;
|
||||
goto fail;
|
||||
}
|
||||
|
||||
/* fill_segment(instance, position); */
|
||||
/*Non-thread equivalent of the lines above */
|
||||
}
|
||||
|
||||
/* 3. Joining remaining threads */
|
||||
for (l = instance->lanes - instance->threads; l < instance->lanes;
|
||||
++l) {
|
||||
if (argon2_thread_join(thread[l])) {
|
||||
rc = ARGON2_THREAD_FAIL;
|
||||
goto fail;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (instance->print_internals) {
|
||||
internal_kat(instance, r); /* Print all memory blocks */
|
||||
}
|
||||
}
|
||||
|
||||
fail:
|
||||
if (thread != NULL) {
|
||||
free(thread);
|
||||
}
|
||||
if (thr_data != NULL) {
|
||||
free(thr_data);
|
||||
}
|
||||
return rc;
|
||||
}
|
||||
|
||||
int fill_memory_blocks(argon2_instance_t *instance) {
|
||||
if (instance == NULL || instance->lanes == 0) {
|
||||
return ARGON2_INCORRECT_PARAMETER;
|
||||
}
|
||||
|
||||
return instance->threads == 1 ?
|
||||
fill_memory_blocks_st(instance) : fill_memory_blocks_mt(instance);
|
||||
}
|
||||
|
||||
int validate_inputs(const argon2_context *context) {
|
||||
if (NULL == context) {
|
||||
return ARGON2_INCORRECT_PARAMETER;
|
||||
}
|
||||
|
||||
if (NULL == context->out) {
|
||||
return ARGON2_OUTPUT_PTR_NULL;
|
||||
}
|
||||
|
||||
/* Validate output length */
|
||||
if (ARGON2_MIN_OUTLEN > context->outlen) {
|
||||
return ARGON2_OUTPUT_TOO_SHORT;
|
||||
}
|
||||
|
||||
if (ARGON2_MAX_OUTLEN < context->outlen) {
|
||||
return ARGON2_OUTPUT_TOO_LONG;
|
||||
}
|
||||
|
||||
/* Validate password (required param) */
|
||||
if (NULL == context->pwd) {
|
||||
if (0 != context->pwdlen) {
|
||||
return ARGON2_PWD_PTR_MISMATCH;
|
||||
}
|
||||
}
|
||||
|
||||
if (ARGON2_MIN_PWD_LENGTH > context->pwdlen) {
|
||||
return ARGON2_PWD_TOO_SHORT;
|
||||
}
|
||||
|
||||
if (ARGON2_MAX_PWD_LENGTH < context->pwdlen) {
|
||||
return ARGON2_PWD_TOO_LONG;
|
||||
}
|
||||
|
||||
/* Validate salt (required param) */
|
||||
if (NULL == context->salt) {
|
||||
if (0 != context->saltlen) {
|
||||
return ARGON2_SALT_PTR_MISMATCH;
|
||||
}
|
||||
}
|
||||
|
||||
if (ARGON2_MIN_SALT_LENGTH > context->saltlen) {
|
||||
return ARGON2_SALT_TOO_SHORT;
|
||||
}
|
||||
|
||||
if (ARGON2_MAX_SALT_LENGTH < context->saltlen) {
|
||||
return ARGON2_SALT_TOO_LONG;
|
||||
}
|
||||
|
||||
/* Validate secret (optional param) */
|
||||
if (NULL == context->secret) {
|
||||
if (0 != context->secretlen) {
|
||||
return ARGON2_SECRET_PTR_MISMATCH;
|
||||
}
|
||||
} else {
|
||||
if (ARGON2_MIN_SECRET > context->secretlen) {
|
||||
return ARGON2_SECRET_TOO_SHORT;
|
||||
}
|
||||
if (ARGON2_MAX_SECRET < context->secretlen) {
|
||||
return ARGON2_SECRET_TOO_LONG;
|
||||
}
|
||||
}
|
||||
|
||||
/* Validate associated data (optional param) */
|
||||
if (NULL == context->ad) {
|
||||
if (0 != context->adlen) {
|
||||
return ARGON2_AD_PTR_MISMATCH;
|
||||
}
|
||||
} else {
|
||||
if (ARGON2_MIN_AD_LENGTH > context->adlen) {
|
||||
return ARGON2_AD_TOO_SHORT;
|
||||
}
|
||||
if (ARGON2_MAX_AD_LENGTH < context->adlen) {
|
||||
return ARGON2_AD_TOO_LONG;
|
||||
}
|
||||
}
|
||||
|
||||
/* Validate memory cost */
|
||||
if (ARGON2_MIN_MEMORY > context->m_cost) {
|
||||
return ARGON2_MEMORY_TOO_LITTLE;
|
||||
}
|
||||
|
||||
if (ARGON2_MAX_MEMORY < context->m_cost) {
|
||||
return ARGON2_MEMORY_TOO_MUCH;
|
||||
}
|
||||
|
||||
if (context->m_cost < 8 * context->lanes) {
|
||||
return ARGON2_MEMORY_TOO_LITTLE;
|
||||
}
|
||||
|
||||
/* Validate time cost */
|
||||
if (ARGON2_MIN_TIME > context->t_cost) {
|
||||
return ARGON2_TIME_TOO_SMALL;
|
||||
}
|
||||
|
||||
if (ARGON2_MAX_TIME < context->t_cost) {
|
||||
return ARGON2_TIME_TOO_LARGE;
|
||||
}
|
||||
|
||||
/* Validate lanes */
|
||||
if (ARGON2_MIN_LANES > context->lanes) {
|
||||
return ARGON2_LANES_TOO_FEW;
|
||||
}
|
||||
|
||||
if (ARGON2_MAX_LANES < context->lanes) {
|
||||
return ARGON2_LANES_TOO_MANY;
|
||||
}
|
||||
|
||||
/* Validate threads */
|
||||
if (ARGON2_MIN_THREADS > context->threads) {
|
||||
return ARGON2_THREADS_TOO_FEW;
|
||||
}
|
||||
|
||||
if (ARGON2_MAX_THREADS < context->threads) {
|
||||
return ARGON2_THREADS_TOO_MANY;
|
||||
}
|
||||
|
||||
if (NULL != context->allocate_cbk && NULL == context->free_cbk) {
|
||||
return ARGON2_FREE_MEMORY_CBK_NULL;
|
||||
}
|
||||
|
||||
if (NULL == context->allocate_cbk && NULL != context->free_cbk) {
|
||||
return ARGON2_ALLOCATE_MEMORY_CBK_NULL;
|
||||
}
|
||||
|
||||
return ARGON2_OK;
|
||||
}
|
||||
|
||||
void fill_first_blocks(uint8_t *blockhash, const argon2_instance_t *instance) {
|
||||
uint32_t l;
|
||||
/* Make the first and second block in each lane as G(H0||0||i) or
|
||||
G(H0||1||i) */
|
||||
uint8_t blockhash_bytes[ARGON2_BLOCK_SIZE];
|
||||
for (l = 0; l < instance->lanes; ++l) {
|
||||
|
||||
store32(blockhash + ARGON2_PREHASH_DIGEST_LENGTH, 0);
|
||||
store32(blockhash + ARGON2_PREHASH_DIGEST_LENGTH + 4, l);
|
||||
blake2b_long(blockhash_bytes, ARGON2_BLOCK_SIZE, blockhash,
|
||||
ARGON2_PREHASH_SEED_LENGTH);
|
||||
load_block(&instance->memory[l * instance->lane_length + 0],
|
||||
blockhash_bytes);
|
||||
|
||||
store32(blockhash + ARGON2_PREHASH_DIGEST_LENGTH, 1);
|
||||
blake2b_long(blockhash_bytes, ARGON2_BLOCK_SIZE, blockhash,
|
||||
ARGON2_PREHASH_SEED_LENGTH);
|
||||
load_block(&instance->memory[l * instance->lane_length + 1],
|
||||
blockhash_bytes);
|
||||
}
|
||||
clear_internal_memory(blockhash_bytes, ARGON2_BLOCK_SIZE);
|
||||
}
|
||||
|
||||
void initial_hash(uint8_t *blockhash, argon2_context *context,
|
||||
argon2_type type) {
|
||||
blake2b_state BlakeHash;
|
||||
uint8_t value[sizeof(uint32_t)];
|
||||
|
||||
if (NULL == context || NULL == blockhash) {
|
||||
return;
|
||||
}
|
||||
|
||||
blake2b_init(&BlakeHash, ARGON2_PREHASH_DIGEST_LENGTH);
|
||||
|
||||
store32(&value, context->lanes);
|
||||
blake2b_update(&BlakeHash, (const uint8_t *)&value, sizeof(value));
|
||||
|
||||
store32(&value, context->outlen);
|
||||
blake2b_update(&BlakeHash, (const uint8_t *)&value, sizeof(value));
|
||||
|
||||
store32(&value, context->m_cost);
|
||||
blake2b_update(&BlakeHash, (const uint8_t *)&value, sizeof(value));
|
||||
|
||||
store32(&value, context->t_cost);
|
||||
blake2b_update(&BlakeHash, (const uint8_t *)&value, sizeof(value));
|
||||
|
||||
store32(&value, context->version);
|
||||
blake2b_update(&BlakeHash, (const uint8_t *)&value, sizeof(value));
|
||||
|
||||
store32(&value, (uint32_t)type);
|
||||
blake2b_update(&BlakeHash, (const uint8_t *)&value, sizeof(value));
|
||||
|
||||
store32(&value, context->pwdlen);
|
||||
blake2b_update(&BlakeHash, (const uint8_t *)&value, sizeof(value));
|
||||
|
||||
if (context->pwd != NULL) {
|
||||
blake2b_update(&BlakeHash, (const uint8_t *)context->pwd,
|
||||
context->pwdlen);
|
||||
|
||||
if (context->flags & ARGON2_FLAG_CLEAR_PASSWORD) {
|
||||
secure_wipe_memory(context->pwd, context->pwdlen);
|
||||
context->pwdlen = 0;
|
||||
}
|
||||
}
|
||||
|
||||
store32(&value, context->saltlen);
|
||||
blake2b_update(&BlakeHash, (const uint8_t *)&value, sizeof(value));
|
||||
|
||||
if (context->salt != NULL) {
|
||||
blake2b_update(&BlakeHash, (const uint8_t *)context->salt,
|
||||
context->saltlen);
|
||||
}
|
||||
|
||||
store32(&value, context->secretlen);
|
||||
blake2b_update(&BlakeHash, (const uint8_t *)&value, sizeof(value));
|
||||
|
||||
if (context->secret != NULL) {
|
||||
blake2b_update(&BlakeHash, (const uint8_t *)context->secret,
|
||||
context->secretlen);
|
||||
|
||||
if (context->flags & ARGON2_FLAG_CLEAR_SECRET) {
|
||||
secure_wipe_memory(context->secret, context->secretlen);
|
||||
context->secretlen = 0;
|
||||
}
|
||||
}
|
||||
|
||||
store32(&value, context->adlen);
|
||||
blake2b_update(&BlakeHash, (const uint8_t *)&value, sizeof(value));
|
||||
|
||||
if (context->ad != NULL) {
|
||||
blake2b_update(&BlakeHash, (const uint8_t *)context->ad,
|
||||
context->adlen);
|
||||
}
|
||||
|
||||
blake2b_final(&BlakeHash, blockhash, ARGON2_PREHASH_DIGEST_LENGTH);
|
||||
}
|
||||
|
||||
int initialize(argon2_instance_t *instance, argon2_context *context) {
|
||||
uint8_t blockhash[ARGON2_PREHASH_SEED_LENGTH];
|
||||
int result = ARGON2_OK;
|
||||
|
||||
if (instance == NULL || context == NULL)
|
||||
return ARGON2_INCORRECT_PARAMETER;
|
||||
instance->context_ptr = context;
|
||||
|
||||
/* 1. Memory allocation */
|
||||
|
||||
result = allocate_memory(context, instance);
|
||||
if (result != ARGON2_OK) {
|
||||
return result;
|
||||
}
|
||||
|
||||
/* 2. Initial hashing */
|
||||
/* H_0 + 8 extra bytes to produce the first blocks */
|
||||
/* uint8_t blockhash[ARGON2_PREHASH_SEED_LENGTH]; */
|
||||
/* Hashing all inputs */
|
||||
initial_hash(blockhash, context, instance->type);
|
||||
/* Zeroing 8 extra bytes */
|
||||
clear_internal_memory(blockhash + ARGON2_PREHASH_DIGEST_LENGTH,
|
||||
ARGON2_PREHASH_SEED_LENGTH -
|
||||
ARGON2_PREHASH_DIGEST_LENGTH);
|
||||
|
||||
if (instance->print_internals) {
|
||||
initial_kat(blockhash, context, instance->type);
|
||||
}
|
||||
|
||||
/* 3. Creating first blocks, we always have at least two blocks in a slice
|
||||
*/
|
||||
fill_first_blocks(blockhash, instance);
|
||||
/* Clearing the hash */
|
||||
clear_internal_memory(blockhash, ARGON2_PREHASH_SEED_LENGTH);
|
||||
|
||||
return ARGON2_OK;
|
||||
}
|
226
src/3rdparty/argon2/lib/core.h
vendored
Normal file
226
src/3rdparty/argon2/lib/core.h
vendored
Normal file
|
@ -0,0 +1,226 @@
|
|||
/*
|
||||
* Argon2 source code package
|
||||
*
|
||||
* Written by Daniel Dinu and Dmitry Khovratovich, 2015
|
||||
*
|
||||
* This work is licensed under a Creative Commons CC0 1.0 License/Waiver.
|
||||
*
|
||||
* You should have received a copy of the CC0 Public Domain Dedication along
|
||||
* with
|
||||
* this software. If not, see
|
||||
* <http://creativecommons.org/publicdomain/zero/1.0/>.
|
||||
*/
|
||||
|
||||
#ifndef ARGON2_CORE_H
|
||||
#define ARGON2_CORE_H
|
||||
|
||||
#include "argon2.h"
|
||||
|
||||
#if defined(_MSC_VER)
|
||||
#define ALIGN(n) __declspec(align(16))
|
||||
#elif defined(__GNUC__) || defined(__clang)
|
||||
#define ALIGN(x) __attribute__((__aligned__(x)))
|
||||
#else
|
||||
#define ALIGN(x)
|
||||
#endif
|
||||
|
||||
#define CONST_CAST(x) (x)(uintptr_t)
|
||||
|
||||
/**********************Argon2 internal constants*******************************/
|
||||
|
||||
enum argon2_core_constants {
|
||||
/* Memory block size in bytes */
|
||||
ARGON2_BLOCK_SIZE = 1024,
|
||||
ARGON2_QWORDS_IN_BLOCK = ARGON2_BLOCK_SIZE / 8,
|
||||
ARGON2_OWORDS_IN_BLOCK = ARGON2_BLOCK_SIZE / 16,
|
||||
|
||||
/* Number of pseudo-random values generated by one call to Blake in Argon2i
|
||||
to
|
||||
generate reference block positions */
|
||||
ARGON2_ADDRESSES_IN_BLOCK = 128,
|
||||
|
||||
/* Pre-hashing digest length and its extension*/
|
||||
ARGON2_PREHASH_DIGEST_LENGTH = 64,
|
||||
ARGON2_PREHASH_SEED_LENGTH = 72
|
||||
};
|
||||
|
||||
/*************************Argon2 internal data types***********************/
|
||||
|
||||
/*
|
||||
* Structure for the (1KB) memory block implemented as 128 64-bit words.
|
||||
* Memory blocks can be copied, XORed. Internal words can be accessed by [] (no
|
||||
* bounds checking).
|
||||
*/
|
||||
typedef struct block_ { uint64_t v[ARGON2_QWORDS_IN_BLOCK]; } block;
|
||||
|
||||
/*****************Functions that work with the block******************/
|
||||
|
||||
/* Initialize each byte of the block with @in */
|
||||
void init_block_value(block *b, uint8_t in);
|
||||
|
||||
/* Copy block @src to block @dst */
|
||||
void copy_block(block *dst, const block *src);
|
||||
|
||||
/* XOR @src onto @dst bytewise */
|
||||
void xor_block(block *dst, const block *src);
|
||||
|
||||
/*
|
||||
* Argon2 instance: memory pointer, number of passes, amount of memory, type,
|
||||
* and derived values.
|
||||
* Used to evaluate the number and location of blocks to construct in each
|
||||
* thread
|
||||
*/
|
||||
typedef struct Argon2_instance_t {
|
||||
block *memory; /* Memory pointer */
|
||||
uint32_t version;
|
||||
uint32_t passes; /* Number of passes */
|
||||
uint32_t memory_blocks; /* Number of blocks in memory */
|
||||
uint32_t segment_length;
|
||||
uint32_t lane_length;
|
||||
uint32_t lanes;
|
||||
uint32_t threads;
|
||||
argon2_type type;
|
||||
int print_internals; /* whether to print the memory blocks */
|
||||
int keep_memory;
|
||||
argon2_context *context_ptr; /* points back to original context */
|
||||
} argon2_instance_t;
|
||||
|
||||
/*
|
||||
* Argon2 position: where we construct the block right now. Used to distribute
|
||||
* work between threads.
|
||||
*/
|
||||
typedef struct Argon2_position_t {
|
||||
uint32_t pass;
|
||||
uint32_t lane;
|
||||
uint8_t slice;
|
||||
uint32_t index;
|
||||
} argon2_position_t;
|
||||
|
||||
/*Struct that holds the inputs for thread handling FillSegment*/
|
||||
typedef struct Argon2_thread_data {
|
||||
argon2_instance_t *instance_ptr;
|
||||
argon2_position_t pos;
|
||||
} argon2_thread_data;
|
||||
|
||||
/*************************Argon2 core functions********************************/
|
||||
|
||||
/* Allocates memory to the given pointer, uses the appropriate allocator as
|
||||
* specified in the context. Total allocated memory is num*size.
|
||||
* @param context argon2_context which specifies the allocator
|
||||
* @param instance the Argon2 instance
|
||||
* @return ARGON2_OK if memory is allocated successfully
|
||||
*/
|
||||
int allocate_memory(const argon2_context *context,
|
||||
argon2_instance_t *instance);
|
||||
|
||||
/*
|
||||
* Frees memory at the given pointer, uses the appropriate deallocator as
|
||||
* specified in the context. Also cleans the memory using clear_internal_memory.
|
||||
* @param context argon2_context which specifies the deallocator
|
||||
* @param instance the Argon2 instance
|
||||
*/
|
||||
void free_memory(const argon2_context *context,
|
||||
const argon2_instance_t *instance);
|
||||
|
||||
/* Function that securely cleans the memory. This ignores any flags set
|
||||
* regarding clearing memory. Usually one just calls clear_internal_memory.
|
||||
* @param mem Pointer to the memory
|
||||
* @param s Memory size in bytes
|
||||
*/
|
||||
void secure_wipe_memory(void *v, size_t n);
|
||||
|
||||
/* Function that securely clears the memory if FLAG_clear_internal_memory is
|
||||
* set. If the flag isn't set, this function does nothing.
|
||||
* @param mem Pointer to the memory
|
||||
* @param s Memory size in bytes
|
||||
*/
|
||||
ARGON2_PUBLIC void clear_internal_memory(void *v, size_t n);
|
||||
|
||||
/*
|
||||
* Computes absolute position of reference block in the lane following a skewed
|
||||
* distribution and using a pseudo-random value as input
|
||||
* @param instance Pointer to the current instance
|
||||
* @param position Pointer to the current position
|
||||
* @param pseudo_rand 32-bit pseudo-random value used to determine the position
|
||||
* @param same_lane Indicates if the block will be taken from the current lane.
|
||||
* If so we can reference the current segment
|
||||
* @pre All pointers must be valid
|
||||
*/
|
||||
uint32_t index_alpha(const argon2_instance_t *instance,
|
||||
const argon2_position_t *position, uint32_t pseudo_rand,
|
||||
int same_lane);
|
||||
|
||||
/*
|
||||
* Function that validates all inputs against predefined restrictions and return
|
||||
* an error code
|
||||
* @param context Pointer to current Argon2 context
|
||||
* @return ARGON2_OK if everything is all right, otherwise one of error codes
|
||||
* (all defined in <argon2.h>
|
||||
*/
|
||||
int validate_inputs(const argon2_context *context);
|
||||
|
||||
/*
|
||||
* Hashes all the inputs into @a blockhash[PREHASH_DIGEST_LENGTH], clears
|
||||
* password and secret if needed
|
||||
* @param context Pointer to the Argon2 internal structure containing memory
|
||||
* pointer, and parameters for time and space requirements.
|
||||
* @param blockhash Buffer for pre-hashing digest
|
||||
* @param type Argon2 type
|
||||
* @pre @a blockhash must have at least @a PREHASH_DIGEST_LENGTH bytes
|
||||
* allocated
|
||||
*/
|
||||
void initial_hash(uint8_t *blockhash, argon2_context *context,
|
||||
argon2_type type);
|
||||
|
||||
/*
|
||||
* Function creates first 2 blocks per lane
|
||||
* @param instance Pointer to the current instance
|
||||
* @param blockhash Pointer to the pre-hashing digest
|
||||
* @pre blockhash must point to @a PREHASH_SEED_LENGTH allocated values
|
||||
*/
|
||||
void fill_first_blocks(uint8_t *blockhash, const argon2_instance_t *instance);
|
||||
|
||||
/*
|
||||
* Function allocates memory, hashes the inputs with Blake, and creates first
|
||||
* two blocks. Returns the pointer to the main memory with 2 blocks per lane
|
||||
* initialized
|
||||
* @param context Pointer to the Argon2 internal structure containing memory
|
||||
* pointer, and parameters for time and space requirements.
|
||||
* @param instance Current Argon2 instance
|
||||
* @return Zero if successful, -1 if memory failed to allocate. @context->state
|
||||
* will be modified if successful.
|
||||
*/
|
||||
int initialize(argon2_instance_t *instance, argon2_context *context);
|
||||
|
||||
/*
|
||||
* XORing the last block of each lane, hashing it, making the tag. Deallocates
|
||||
* the memory.
|
||||
* @param context Pointer to current Argon2 context (use only the out parameters
|
||||
* from it)
|
||||
* @param instance Pointer to current instance of Argon2
|
||||
* @pre instance->state must point to necessary amount of memory
|
||||
* @pre context->out must point to outlen bytes of memory
|
||||
* @pre if context->free_cbk is not NULL, it should point to a function that
|
||||
* deallocates memory
|
||||
*/
|
||||
void finalize(const argon2_context *context, argon2_instance_t *instance);
|
||||
|
||||
/*
|
||||
* Function that fills the segment using previous segments also from other
|
||||
* threads
|
||||
* @param instance Pointer to the current instance
|
||||
* @param position Current position
|
||||
* @pre all block pointers must be valid
|
||||
*/
|
||||
void fill_segment(const argon2_instance_t *instance,
|
||||
argon2_position_t position);
|
||||
|
||||
/*
|
||||
* Function that fills the entire memory t_cost times based on the first two
|
||||
* blocks in each lane
|
||||
* @param instance Pointer to the current instance
|
||||
* @return ARGON2_OK if successful, @context->state
|
||||
*/
|
||||
int fill_memory_blocks(argon2_instance_t *instance);
|
||||
|
||||
#endif
|
432
src/3rdparty/argon2/lib/encoding.c
vendored
Normal file
432
src/3rdparty/argon2/lib/encoding.c
vendored
Normal file
|
@ -0,0 +1,432 @@
|
|||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
#include <limits.h>
|
||||
#include "encoding.h"
|
||||
#include "core.h"
|
||||
|
||||
/*
|
||||
* Example code for a decoder and encoder of "hash strings", with Argon2
|
||||
* parameters.
|
||||
*
|
||||
* This code comprises three sections:
|
||||
*
|
||||
* -- The first section contains generic Base64 encoding and decoding
|
||||
* functions. It is conceptually applicable to any hash function
|
||||
* implementation that uses Base64 to encode and decode parameters,
|
||||
* salts and outputs. It could be made into a library, provided that
|
||||
* the relevant functions are made public (non-static) and be given
|
||||
* reasonable names to avoid collisions with other functions.
|
||||
*
|
||||
* -- The second section is specific to Argon2. It encodes and decodes
|
||||
* the parameters, salts and outputs. It does not compute the hash
|
||||
* itself.
|
||||
*
|
||||
* The code was originally written by Thomas Pornin <pornin@bolet.org>,
|
||||
* to whom comments and remarks may be sent. It is released under what
|
||||
* should amount to Public Domain or its closest equivalent; the
|
||||
* following mantra is supposed to incarnate that fact with all the
|
||||
* proper legal rituals:
|
||||
*
|
||||
* ---------------------------------------------------------------------
|
||||
* This file is provided under the terms of Creative Commons CC0 1.0
|
||||
* Public Domain Dedication. To the extent possible under law, the
|
||||
* author (Thomas Pornin) has waived all copyright and related or
|
||||
* neighboring rights to this file. This work is published from: Canada.
|
||||
* ---------------------------------------------------------------------
|
||||
*
|
||||
* Copyright (c) 2015 Thomas Pornin
|
||||
*/
|
||||
|
||||
/* ==================================================================== */
|
||||
/*
|
||||
* Common code; could be shared between different hash functions.
|
||||
*
|
||||
* Note: the Base64 functions below assume that uppercase letters (resp.
|
||||
* lowercase letters) have consecutive numerical codes, that fit on 8
|
||||
* bits. All modern systems use ASCII-compatible charsets, where these
|
||||
* properties are true. If you are stuck with a dinosaur of a system
|
||||
* that still defaults to EBCDIC then you already have much bigger
|
||||
* interoperability issues to deal with.
|
||||
*/
|
||||
|
||||
/*
|
||||
* Some macros for constant-time comparisons. These work over values in
|
||||
* the 0..255 range. Returned value is 0x00 on "false", 0xFF on "true".
|
||||
*/
|
||||
#define EQ(x, y) ((((0U - ((unsigned)(x) ^ (unsigned)(y))) >> 8) & 0xFF) ^ 0xFF)
|
||||
#define GT(x, y) ((((unsigned)(y) - (unsigned)(x)) >> 8) & 0xFF)
|
||||
#define GE(x, y) (GT(y, x) ^ 0xFF)
|
||||
#define LT(x, y) GT(y, x)
|
||||
#define LE(x, y) GE(y, x)
|
||||
|
||||
/*
|
||||
* Convert value x (0..63) to corresponding Base64 character.
|
||||
*/
|
||||
static int b64_byte_to_char(unsigned x) {
|
||||
return (LT(x, 26) & (x + 'A')) |
|
||||
(GE(x, 26) & LT(x, 52) & (x + ('a' - 26))) |
|
||||
(GE(x, 52) & LT(x, 62) & (x + ('0' - 52))) | (EQ(x, 62) & '+') |
|
||||
(EQ(x, 63) & '/');
|
||||
}
|
||||
|
||||
/*
|
||||
* Convert character c to the corresponding 6-bit value. If character c
|
||||
* is not a Base64 character, then 0xFF (255) is returned.
|
||||
*/
|
||||
static unsigned b64_char_to_byte(int c) {
|
||||
unsigned x;
|
||||
|
||||
x = (GE(c, 'A') & LE(c, 'Z') & (c - 'A')) |
|
||||
(GE(c, 'a') & LE(c, 'z') & (c - ('a' - 26))) |
|
||||
(GE(c, '0') & LE(c, '9') & (c - ('0' - 52))) | (EQ(c, '+') & 62) |
|
||||
(EQ(c, '/') & 63);
|
||||
return x | (EQ(x, 0) & (EQ(c, 'A') ^ 0xFF));
|
||||
}
|
||||
|
||||
/*
|
||||
* Convert some bytes to Base64. 'dst_len' is the length (in characters)
|
||||
* of the output buffer 'dst'; if that buffer is not large enough to
|
||||
* receive the result (including the terminating 0), then (size_t)-1
|
||||
* is returned. Otherwise, the zero-terminated Base64 string is written
|
||||
* in the buffer, and the output length (counted WITHOUT the terminating
|
||||
* zero) is returned.
|
||||
*/
|
||||
static size_t to_base64(char *dst, size_t dst_len, const void *src,
|
||||
size_t src_len) {
|
||||
size_t olen;
|
||||
const unsigned char *buf;
|
||||
unsigned acc, acc_len;
|
||||
|
||||
olen = (src_len / 3) << 2;
|
||||
switch (src_len % 3) {
|
||||
case 2:
|
||||
olen++;
|
||||
/* fall through */
|
||||
case 1:
|
||||
olen += 2;
|
||||
break;
|
||||
}
|
||||
if (dst_len <= olen) {
|
||||
return (size_t)-1;
|
||||
}
|
||||
acc = 0;
|
||||
acc_len = 0;
|
||||
buf = (const unsigned char *)src;
|
||||
while (src_len-- > 0) {
|
||||
acc = (acc << 8) + (*buf++);
|
||||
acc_len += 8;
|
||||
while (acc_len >= 6) {
|
||||
acc_len -= 6;
|
||||
*dst++ = (char)b64_byte_to_char((acc >> acc_len) & 0x3F);
|
||||
}
|
||||
}
|
||||
if (acc_len > 0) {
|
||||
*dst++ = (char)b64_byte_to_char((acc << (6 - acc_len)) & 0x3F);
|
||||
}
|
||||
*dst++ = 0;
|
||||
return olen;
|
||||
}
|
||||
|
||||
/*
|
||||
* Decode Base64 chars into bytes. The '*dst_len' value must initially
|
||||
* contain the length of the output buffer '*dst'; when the decoding
|
||||
* ends, the actual number of decoded bytes is written back in
|
||||
* '*dst_len'.
|
||||
*
|
||||
* Decoding stops when a non-Base64 character is encountered, or when
|
||||
* the output buffer capacity is exceeded. If an error occurred (output
|
||||
* buffer is too small, invalid last characters leading to unprocessed
|
||||
* buffered bits), then NULL is returned; otherwise, the returned value
|
||||
* points to the first non-Base64 character in the source stream, which
|
||||
* may be the terminating zero.
|
||||
*/
|
||||
static const char *from_base64(void *dst, size_t *dst_len, const char *src) {
|
||||
size_t len;
|
||||
unsigned char *buf;
|
||||
unsigned acc, acc_len;
|
||||
|
||||
buf = (unsigned char *)dst;
|
||||
len = 0;
|
||||
acc = 0;
|
||||
acc_len = 0;
|
||||
for (;;) {
|
||||
unsigned d;
|
||||
|
||||
d = b64_char_to_byte(*src);
|
||||
if (d == 0xFF) {
|
||||
break;
|
||||
}
|
||||
src++;
|
||||
acc = (acc << 6) + d;
|
||||
acc_len += 6;
|
||||
if (acc_len >= 8) {
|
||||
acc_len -= 8;
|
||||
if ((len++) >= *dst_len) {
|
||||
return NULL;
|
||||
}
|
||||
*buf++ = (acc >> acc_len) & 0xFF;
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
* If the input length is equal to 1 modulo 4 (which is
|
||||
* invalid), then there will remain 6 unprocessed bits;
|
||||
* otherwise, only 0, 2 or 4 bits are buffered. The buffered
|
||||
* bits must also all be zero.
|
||||
*/
|
||||
if (acc_len > 4 || (acc & (((unsigned)1 << acc_len) - 1)) != 0) {
|
||||
return NULL;
|
||||
}
|
||||
*dst_len = len;
|
||||
return src;
|
||||
}
|
||||
|
||||
/*
|
||||
* Decode decimal integer from 'str'; the value is written in '*v'.
|
||||
* Returned value is a pointer to the next non-decimal character in the
|
||||
* string. If there is no digit at all, or the value encoding is not
|
||||
* minimal (extra leading zeros), or the value does not fit in an
|
||||
* 'unsigned long', then NULL is returned.
|
||||
*/
|
||||
static const char *decode_decimal(const char *str, unsigned long *v) {
|
||||
const char *orig;
|
||||
unsigned long acc;
|
||||
|
||||
acc = 0;
|
||||
for (orig = str;; str++) {
|
||||
int c;
|
||||
|
||||
c = *str;
|
||||
if (c < '0' || c > '9') {
|
||||
break;
|
||||
}
|
||||
c -= '0';
|
||||
if (acc > (ULONG_MAX / 10)) {
|
||||
return NULL;
|
||||
}
|
||||
acc *= 10;
|
||||
if ((unsigned long)c > (ULONG_MAX - acc)) {
|
||||
return NULL;
|
||||
}
|
||||
acc += (unsigned long)c;
|
||||
}
|
||||
if (str == orig || (*orig == '0' && str != (orig + 1))) {
|
||||
return NULL;
|
||||
}
|
||||
*v = acc;
|
||||
return str;
|
||||
}
|
||||
|
||||
/* ==================================================================== */
|
||||
/*
|
||||
* Code specific to Argon2.
|
||||
*
|
||||
* The code below applies the following format:
|
||||
*
|
||||
* $argon2<T>[$v=<num>]$m=<num>,t=<num>,p=<num>$<bin>$<bin>
|
||||
*
|
||||
* where <T> is either 'd', 'id', or 'i', <num> is a decimal integer (positive,
|
||||
* fits in an 'unsigned long'), and <bin> is Base64-encoded data (no '=' padding
|
||||
* characters, no newline or whitespace).
|
||||
*
|
||||
* The last two binary chunks (encoded in Base64) are, in that order,
|
||||
* the salt and the output. Both are required. The binary salt length and the
|
||||
* output length must be in the allowed ranges defined in argon2.h.
|
||||
*
|
||||
* The ctx struct must contain buffers large enough to hold the salt and pwd
|
||||
* when it is fed into decode_string.
|
||||
*/
|
||||
|
||||
int decode_string(argon2_context *ctx, const char *str, argon2_type type) {
|
||||
|
||||
/* check for prefix */
|
||||
#define CC(prefix) \
|
||||
do { \
|
||||
size_t cc_len = strlen(prefix); \
|
||||
if (strncmp(str, prefix, cc_len) != 0) { \
|
||||
return ARGON2_DECODING_FAIL; \
|
||||
} \
|
||||
str += cc_len; \
|
||||
} while ((void)0, 0)
|
||||
|
||||
/* optional prefix checking with supplied code */
|
||||
#define CC_opt(prefix, code) \
|
||||
do { \
|
||||
size_t cc_len = strlen(prefix); \
|
||||
if (strncmp(str, prefix, cc_len) == 0) { \
|
||||
str += cc_len; \
|
||||
{ code; } \
|
||||
} \
|
||||
} while ((void)0, 0)
|
||||
|
||||
/* Decoding prefix into uint32_t decimal */
|
||||
#define DECIMAL_U32(x) \
|
||||
do { \
|
||||
unsigned long dec_x; \
|
||||
str = decode_decimal(str, &dec_x); \
|
||||
if (str == NULL || dec_x > UINT32_MAX) { \
|
||||
return ARGON2_DECODING_FAIL; \
|
||||
} \
|
||||
(x) = (uint32_t)dec_x; \
|
||||
} while ((void)0, 0)
|
||||
|
||||
/* Decoding base64 into a binary buffer */
|
||||
#define BIN(buf, max_len, len) \
|
||||
do { \
|
||||
size_t bin_len = (max_len); \
|
||||
str = from_base64(buf, &bin_len, str); \
|
||||
if (str == NULL || bin_len > UINT32_MAX) { \
|
||||
return ARGON2_DECODING_FAIL; \
|
||||
} \
|
||||
(len) = (uint32_t)bin_len; \
|
||||
} while ((void)0, 0)
|
||||
|
||||
size_t maxsaltlen = ctx->saltlen;
|
||||
size_t maxoutlen = ctx->outlen;
|
||||
int validation_result;
|
||||
const char* type_string;
|
||||
|
||||
/* We should start with the argon2_type we are using */
|
||||
type_string = argon2_type2string(type, 0);
|
||||
if (!type_string) {
|
||||
return ARGON2_INCORRECT_TYPE;
|
||||
}
|
||||
|
||||
CC("$");
|
||||
CC(type_string);
|
||||
|
||||
/* Reading the version number if the default is suppressed */
|
||||
ctx->version = ARGON2_VERSION_10;
|
||||
CC_opt("$v=", DECIMAL_U32(ctx->version));
|
||||
|
||||
CC("$m=");
|
||||
DECIMAL_U32(ctx->m_cost);
|
||||
CC(",t=");
|
||||
DECIMAL_U32(ctx->t_cost);
|
||||
CC(",p=");
|
||||
DECIMAL_U32(ctx->lanes);
|
||||
ctx->threads = ctx->lanes;
|
||||
|
||||
CC("$");
|
||||
BIN(ctx->salt, maxsaltlen, ctx->saltlen);
|
||||
CC("$");
|
||||
BIN(ctx->out, maxoutlen, ctx->outlen);
|
||||
|
||||
/* The rest of the fields get the default values */
|
||||
ctx->secret = NULL;
|
||||
ctx->secretlen = 0;
|
||||
ctx->ad = NULL;
|
||||
ctx->adlen = 0;
|
||||
ctx->allocate_cbk = NULL;
|
||||
ctx->free_cbk = NULL;
|
||||
ctx->flags = ARGON2_DEFAULT_FLAGS;
|
||||
|
||||
/* On return, must have valid context */
|
||||
validation_result = validate_inputs(ctx);
|
||||
if (validation_result != ARGON2_OK) {
|
||||
return validation_result;
|
||||
}
|
||||
|
||||
/* Can't have any additional characters */
|
||||
if (*str == 0) {
|
||||
return ARGON2_OK;
|
||||
} else {
|
||||
return ARGON2_DECODING_FAIL;
|
||||
}
|
||||
#undef CC
|
||||
#undef CC_opt
|
||||
#undef DECIMAL_U32
|
||||
#undef BIN
|
||||
}
|
||||
|
||||
int encode_string(char *dst, size_t dst_len, argon2_context *ctx,
|
||||
argon2_type type) {
|
||||
#define SS(str) \
|
||||
do { \
|
||||
size_t pp_len = strlen(str); \
|
||||
if (pp_len >= dst_len) { \
|
||||
return ARGON2_ENCODING_FAIL; \
|
||||
} \
|
||||
memcpy(dst, str, pp_len + 1); \
|
||||
dst += pp_len; \
|
||||
dst_len -= pp_len; \
|
||||
} while ((void)0, 0)
|
||||
|
||||
#define SX(x) \
|
||||
do { \
|
||||
char tmp[30]; \
|
||||
sprintf(tmp, "%lu", (unsigned long)(x)); \
|
||||
SS(tmp); \
|
||||
} while ((void)0, 0)
|
||||
|
||||
#define SB(buf, len) \
|
||||
do { \
|
||||
size_t sb_len = to_base64(dst, dst_len, buf, len); \
|
||||
if (sb_len == (size_t)-1) { \
|
||||
return ARGON2_ENCODING_FAIL; \
|
||||
} \
|
||||
dst += sb_len; \
|
||||
dst_len -= sb_len; \
|
||||
} while ((void)0, 0)
|
||||
|
||||
const char* type_string = argon2_type2string(type, 0);
|
||||
int validation_result = validate_inputs(ctx);
|
||||
|
||||
if (!type_string) {
|
||||
return ARGON2_ENCODING_FAIL;
|
||||
}
|
||||
|
||||
if (validation_result != ARGON2_OK) {
|
||||
return validation_result;
|
||||
}
|
||||
|
||||
SS("$");
|
||||
SS(type_string);
|
||||
|
||||
SS("$v=");
|
||||
SX(ctx->version);
|
||||
|
||||
SS("$m=");
|
||||
SX(ctx->m_cost);
|
||||
SS(",t=");
|
||||
SX(ctx->t_cost);
|
||||
SS(",p=");
|
||||
SX(ctx->lanes);
|
||||
|
||||
SS("$");
|
||||
SB(ctx->salt, ctx->saltlen);
|
||||
|
||||
SS("$");
|
||||
SB(ctx->out, ctx->outlen);
|
||||
return ARGON2_OK;
|
||||
|
||||
#undef SS
|
||||
#undef SX
|
||||
#undef SB
|
||||
}
|
||||
|
||||
size_t b64len(uint32_t len) {
|
||||
size_t olen = ((size_t)len / 3) << 2;
|
||||
|
||||
switch (len % 3) {
|
||||
case 2:
|
||||
olen++;
|
||||
/* fall through */
|
||||
case 1:
|
||||
olen += 2;
|
||||
break;
|
||||
}
|
||||
|
||||
return olen;
|
||||
}
|
||||
|
||||
size_t numlen(uint32_t num) {
|
||||
size_t len = 1;
|
||||
while (num >= 10) {
|
||||
++len;
|
||||
num = num / 10;
|
||||
}
|
||||
return len;
|
||||
}
|
||||
|
40
src/3rdparty/argon2/lib/encoding.h
vendored
Normal file
40
src/3rdparty/argon2/lib/encoding.h
vendored
Normal file
|
@ -0,0 +1,40 @@
|
|||
#ifndef ENCODING_H
|
||||
#define ENCODING_H
|
||||
#include "argon2.h"
|
||||
|
||||
#define ARGON2_MAX_DECODED_LANES UINT32_C(255)
|
||||
#define ARGON2_MIN_DECODED_SALT_LEN UINT32_C(8)
|
||||
#define ARGON2_MIN_DECODED_OUT_LEN UINT32_C(12)
|
||||
|
||||
/*
|
||||
* encode an Argon2 hash string into the provided buffer. 'dst_len'
|
||||
* contains the size, in characters, of the 'dst' buffer; if 'dst_len'
|
||||
* is less than the number of required characters (including the
|
||||
* terminating 0), then this function returns ARGON2_ENCODING_ERROR.
|
||||
*
|
||||
* on success, ARGON2_OK is returned.
|
||||
*/
|
||||
int encode_string(char *dst, size_t dst_len, argon2_context *ctx,
|
||||
argon2_type type);
|
||||
|
||||
/*
|
||||
* Decodes an Argon2 hash string into the provided structure 'ctx'.
|
||||
* The only fields that must be set prior to this call are ctx.saltlen and
|
||||
* ctx.outlen (which must be the maximal salt and out length values that are
|
||||
* allowed), ctx.salt and ctx.out (which must be buffers of the specified
|
||||
* length), and ctx.pwd and ctx.pwdlen which must hold a valid password.
|
||||
*
|
||||
* Invalid input string causes an error. On success, the ctx is valid and all
|
||||
* fields have been initialized.
|
||||
*
|
||||
* Returned value is ARGON2_OK on success, other ARGON2_ codes on error.
|
||||
*/
|
||||
int decode_string(argon2_context *ctx, const char *str, argon2_type type);
|
||||
|
||||
/* Returns the length of the encoded byte stream with length len */
|
||||
size_t b64len(uint32_t len);
|
||||
|
||||
/* Returns the length of the encoded number num */
|
||||
size_t numlen(uint32_t num);
|
||||
|
||||
#endif
|
117
src/3rdparty/argon2/lib/genkat.c
vendored
Normal file
117
src/3rdparty/argon2/lib/genkat.c
vendored
Normal file
|
@ -0,0 +1,117 @@
|
|||
/*
|
||||
* Argon2 source code package
|
||||
*
|
||||
* Written by Daniel Dinu and Dmitry Khovratovich, 2015
|
||||
*
|
||||
* This work is licensed under a Creative Commons CC0 1.0 License/Waiver.
|
||||
*
|
||||
* You should have received a copy of the CC0 Public Domain Dedication along
|
||||
* with
|
||||
* this software. If not, see
|
||||
* <http://creativecommons.org/publicdomain/zero/1.0/>.
|
||||
*/
|
||||
|
||||
#include <inttypes.h>
|
||||
#include <stdio.h>
|
||||
|
||||
#include "genkat.h"
|
||||
|
||||
void initial_kat(const uint8_t *blockhash, const argon2_context *context,
|
||||
argon2_type type) {
|
||||
unsigned i;
|
||||
|
||||
if (blockhash != NULL && context != NULL) {
|
||||
printf("=======================================\n");
|
||||
|
||||
printf("%s version number %d\n", argon2_type2string(type, 1),
|
||||
context->version);
|
||||
|
||||
printf("=======================================\n");
|
||||
|
||||
|
||||
printf("Memory: %u KiB, Iterations: %u, Parallelism: %u lanes, Tag "
|
||||
"length: %u bytes\n",
|
||||
context->m_cost, context->t_cost, context->lanes,
|
||||
context->outlen);
|
||||
|
||||
printf("Password[%u]: ", context->pwdlen);
|
||||
|
||||
if (context->flags & ARGON2_FLAG_CLEAR_PASSWORD) {
|
||||
printf("CLEARED\n");
|
||||
} else {
|
||||
for (i = 0; i < context->pwdlen; ++i) {
|
||||
printf("%2.2x ", ((unsigned char *)context->pwd)[i]);
|
||||
}
|
||||
|
||||
printf("\n");
|
||||
}
|
||||
|
||||
printf("Salt[%u]: ", context->saltlen);
|
||||
|
||||
for (i = 0; i < context->saltlen; ++i) {
|
||||
printf("%2.2x ", ((unsigned char *)context->salt)[i]);
|
||||
}
|
||||
|
||||
printf("\n");
|
||||
|
||||
printf("Secret[%u]: ", context->secretlen);
|
||||
|
||||
if (context->flags & ARGON2_FLAG_CLEAR_SECRET) {
|
||||
printf("CLEARED\n");
|
||||
} else {
|
||||
for (i = 0; i < context->secretlen; ++i) {
|
||||
printf("%2.2x ", ((unsigned char *)context->secret)[i]);
|
||||
}
|
||||
|
||||
printf("\n");
|
||||
}
|
||||
|
||||
printf("Associated data[%u]: ", context->adlen);
|
||||
|
||||
for (i = 0; i < context->adlen; ++i) {
|
||||
printf("%2.2x ", ((unsigned char *)context->ad)[i]);
|
||||
}
|
||||
|
||||
printf("\n");
|
||||
|
||||
printf("Pre-hashing digest: ");
|
||||
|
||||
for (i = 0; i < ARGON2_PREHASH_DIGEST_LENGTH; ++i) {
|
||||
printf("%2.2x ", ((unsigned char *)blockhash)[i]);
|
||||
}
|
||||
|
||||
printf("\n");
|
||||
}
|
||||
}
|
||||
|
||||
void print_tag(const void *out, uint32_t outlen) {
|
||||
unsigned i;
|
||||
if (out != NULL) {
|
||||
printf("Tag: ");
|
||||
|
||||
for (i = 0; i < outlen; ++i) {
|
||||
printf("%2.2x ", ((uint8_t *)out)[i]);
|
||||
}
|
||||
|
||||
printf("\n");
|
||||
}
|
||||
}
|
||||
|
||||
void internal_kat(const argon2_instance_t *instance, uint32_t pass) {
|
||||
|
||||
if (instance != NULL) {
|
||||
uint32_t i, j;
|
||||
printf("\n After pass %u:\n", pass);
|
||||
|
||||
for (i = 0; i < instance->memory_blocks; ++i) {
|
||||
uint32_t how_many_words =
|
||||
(instance->memory_blocks > ARGON2_QWORDS_IN_BLOCK)
|
||||
? 1
|
||||
: ARGON2_QWORDS_IN_BLOCK;
|
||||
|
||||
for (j = 0; j < how_many_words; ++j)
|
||||
printf("Block %.4u [%3u]: %016" PRIx64 "\n", i, j,
|
||||
instance->memory[i].v[j]);
|
||||
}
|
||||
}
|
||||
}
|
47
src/3rdparty/argon2/lib/genkat.h
vendored
Normal file
47
src/3rdparty/argon2/lib/genkat.h
vendored
Normal file
|
@ -0,0 +1,47 @@
|
|||
/*
|
||||
* Argon2 source code package
|
||||
*
|
||||
* Written by Daniel Dinu and Dmitry Khovratovich, 2015
|
||||
*
|
||||
* This work is licensed under a Creative Commons CC0 1.0 License/Waiver.
|
||||
*
|
||||
* You should have received a copy of the CC0 Public Domain Dedication along
|
||||
* with
|
||||
* this software. If not, see
|
||||
* <http://creativecommons.org/publicdomain/zero/1.0/>.
|
||||
*/
|
||||
|
||||
#ifndef ARGON2_KAT_H
|
||||
#define ARGON2_KAT_H
|
||||
|
||||
#include "core.h"
|
||||
|
||||
/*
|
||||
* Initial KAT function that prints the inputs to the file
|
||||
* @param blockhash Array that contains pre-hashing digest
|
||||
* @param context Holds inputs
|
||||
* @param type Argon2 type
|
||||
* @pre blockhash must point to INPUT_INITIAL_HASH_LENGTH bytes
|
||||
* @pre context member pointers must point to allocated memory of size according
|
||||
* to the length values
|
||||
*/
|
||||
void initial_kat(const uint8_t *blockhash, const argon2_context *context,
|
||||
argon2_type type);
|
||||
|
||||
/*
|
||||
* Function that prints the output tag
|
||||
* @param out output array pointer
|
||||
* @param outlen digest length
|
||||
* @pre out must point to @a outlen bytes
|
||||
**/
|
||||
void print_tag(const void *out, uint32_t outlen);
|
||||
|
||||
/*
|
||||
* Function that prints the internal state at given moment
|
||||
* @param instance pointer to the current instance
|
||||
* @param pass current pass number
|
||||
* @pre instance must have necessary memory allocated
|
||||
**/
|
||||
void internal_kat(const argon2_instance_t *instance, uint32_t pass);
|
||||
|
||||
#endif
|
120
src/3rdparty/argon2/lib/impl-select.c
vendored
Normal file
120
src/3rdparty/argon2/lib/impl-select.c
vendored
Normal file
|
@ -0,0 +1,120 @@
|
|||
#include <time.h>
|
||||
#include <string.h>
|
||||
|
||||
#include "impl-select.h"
|
||||
|
||||
#include "argon2.h"
|
||||
|
||||
#define log_maybe(file, ...) \
|
||||
do { \
|
||||
if (file) { \
|
||||
fprintf(file, __VA_ARGS__); \
|
||||
} \
|
||||
} while((void)0, 0)
|
||||
|
||||
#define BENCH_SAMPLES 512
|
||||
#define BENCH_MEM_BLOCKS 512
|
||||
|
||||
static argon2_impl selected_argon_impl = {
|
||||
"(default)", NULL, fill_segment_default
|
||||
};
|
||||
|
||||
/* the benchmark routine is not thread-safe, so we can use a global var here: */
|
||||
static block memory[BENCH_MEM_BLOCKS];
|
||||
|
||||
static uint64_t benchmark_impl(const argon2_impl *impl) {
|
||||
clock_t time;
|
||||
unsigned int i;
|
||||
uint64_t bench;
|
||||
argon2_instance_t instance;
|
||||
argon2_position_t pos;
|
||||
|
||||
memset(memory, 0, sizeof(memory));
|
||||
|
||||
instance.version = ARGON2_VERSION_NUMBER;
|
||||
instance.memory = memory;
|
||||
instance.passes = 1;
|
||||
instance.memory_blocks = BENCH_MEM_BLOCKS;
|
||||
instance.segment_length = BENCH_MEM_BLOCKS / ARGON2_SYNC_POINTS;
|
||||
instance.lane_length = instance.segment_length * ARGON2_SYNC_POINTS;
|
||||
instance.lanes = 1;
|
||||
instance.threads = 1;
|
||||
instance.type = Argon2_i;
|
||||
|
||||
pos.lane = 0;
|
||||
pos.pass = 0;
|
||||
pos.slice = 0;
|
||||
pos.index = 0;
|
||||
|
||||
/* warm-up cache: */
|
||||
impl->fill_segment(&instance, pos);
|
||||
|
||||
/* OK, now measure: */
|
||||
bench = 0;
|
||||
time = clock();
|
||||
for (i = 0; i < BENCH_SAMPLES; i++) {
|
||||
impl->fill_segment(&instance, pos);
|
||||
}
|
||||
time = clock() - time;
|
||||
bench = (uint64_t)time;
|
||||
return bench;
|
||||
}
|
||||
|
||||
static void select_impl(FILE *out, const char *prefix)
|
||||
{
|
||||
argon2_impl_list impls;
|
||||
unsigned int i;
|
||||
const argon2_impl *best_impl = NULL;
|
||||
uint64_t best_bench = UINT_MAX;
|
||||
|
||||
log_maybe(out, "%sSelecting best fill_segment implementation...\n", prefix);
|
||||
|
||||
argon2_get_impl_list(&impls);
|
||||
|
||||
for (i = 0; i < impls.count; i++) {
|
||||
const argon2_impl *impl = &impls.entries[i];
|
||||
uint64_t bench;
|
||||
|
||||
log_maybe(out, "%s%s: Checking availability... ", prefix, impl->name);
|
||||
if (impl->check != NULL && !impl->check()) {
|
||||
log_maybe(out, "FAILED!\n");
|
||||
continue;
|
||||
}
|
||||
log_maybe(out, "OK!\n");
|
||||
|
||||
log_maybe(out, "%s%s: Benchmarking...\n", prefix, impl->name);
|
||||
bench = benchmark_impl(impl);
|
||||
log_maybe(out, "%s%s: Benchmark result: %llu\n", prefix, impl->name,
|
||||
(unsigned long long)bench);
|
||||
|
||||
if (bench < best_bench) {
|
||||
best_bench = bench;
|
||||
best_impl = impl;
|
||||
}
|
||||
}
|
||||
|
||||
if (best_impl != NULL) {
|
||||
log_maybe(out,
|
||||
"%sBest implementation: '%s' (bench %llu)\n", prefix,
|
||||
best_impl->name, (unsigned long long)best_bench);
|
||||
|
||||
selected_argon_impl = *best_impl;
|
||||
} else {
|
||||
log_maybe(out,
|
||||
"%sNo optimized implementation available, using default!\n",
|
||||
prefix);
|
||||
}
|
||||
}
|
||||
|
||||
void fill_segment(const argon2_instance_t *instance, argon2_position_t position)
|
||||
{
|
||||
selected_argon_impl.fill_segment(instance, position);
|
||||
}
|
||||
|
||||
void argon2_select_impl(FILE *out, const char *prefix)
|
||||
{
|
||||
if (prefix == NULL) {
|
||||
prefix = "";
|
||||
}
|
||||
select_impl(out, prefix);
|
||||
}
|
23
src/3rdparty/argon2/lib/impl-select.h
vendored
Normal file
23
src/3rdparty/argon2/lib/impl-select.h
vendored
Normal file
|
@ -0,0 +1,23 @@
|
|||
#ifndef ARGON2_IMPL_SELECT_H
|
||||
#define ARGON2_IMPL_SELECT_H
|
||||
|
||||
#include "core.h"
|
||||
|
||||
typedef struct Argon2_impl {
|
||||
const char *name;
|
||||
int (*check)(void);
|
||||
void (*fill_segment)(const argon2_instance_t *instance,
|
||||
argon2_position_t position);
|
||||
} argon2_impl;
|
||||
|
||||
typedef struct Argon2_impl_list {
|
||||
const argon2_impl *entries;
|
||||
size_t count;
|
||||
} argon2_impl_list;
|
||||
|
||||
void argon2_get_impl_list(argon2_impl_list *list);
|
||||
void fill_segment_default(const argon2_instance_t *instance,
|
||||
argon2_position_t position);
|
||||
|
||||
#endif // ARGON2_IMPL_SELECT_H
|
||||
|
36
src/3rdparty/argon2/lib/thread.c
vendored
Normal file
36
src/3rdparty/argon2/lib/thread.c
vendored
Normal file
|
@ -0,0 +1,36 @@
|
|||
#include "thread.h"
|
||||
#if defined(_WIN32)
|
||||
#include <windows.h>
|
||||
#endif
|
||||
|
||||
int argon2_thread_create(argon2_thread_handle_t *handle,
|
||||
argon2_thread_func_t func, void *args) {
|
||||
if (NULL == handle || func == NULL) {
|
||||
return -1;
|
||||
}
|
||||
#if defined(_WIN32)
|
||||
*handle = _beginthreadex(NULL, 0, func, args, 0, NULL);
|
||||
return *handle != 0 ? 0 : -1;
|
||||
#else
|
||||
return pthread_create(handle, NULL, func, args);
|
||||
#endif
|
||||
}
|
||||
|
||||
int argon2_thread_join(argon2_thread_handle_t handle) {
|
||||
#if defined(_WIN32)
|
||||
if (WaitForSingleObject((HANDLE)handle, INFINITE) == WAIT_OBJECT_0) {
|
||||
return CloseHandle((HANDLE)handle) != 0 ? 0 : -1;
|
||||
}
|
||||
return -1;
|
||||
#else
|
||||
return pthread_join(handle, NULL);
|
||||
#endif
|
||||
}
|
||||
|
||||
void argon2_thread_exit(void) {
|
||||
#if defined(_WIN32)
|
||||
_endthreadex(0);
|
||||
#else
|
||||
pthread_exit(NULL);
|
||||
#endif
|
||||
}
|
47
src/3rdparty/argon2/lib/thread.h
vendored
Normal file
47
src/3rdparty/argon2/lib/thread.h
vendored
Normal file
|
@ -0,0 +1,47 @@
|
|||
#ifndef ARGON2_THREAD_H
|
||||
#define ARGON2_THREAD_H
|
||||
/*
|
||||
Here we implement an abstraction layer for the simpĺe requirements
|
||||
of the Argon2 code. We only require 3 primitives---thread creation,
|
||||
joining, and termination---so full emulation of the pthreads API
|
||||
is unwarranted. Currently we wrap pthreads and Win32 threads.
|
||||
|
||||
The API defines 2 types: the function pointer type,
|
||||
argon2_thread_func_t,
|
||||
and the type of the thread handle---argon2_thread_handle_t.
|
||||
*/
|
||||
#if defined(_WIN32)
|
||||
#include <process.h>
|
||||
#include <stdint.h>
|
||||
typedef unsigned(__stdcall *argon2_thread_func_t)(void *);
|
||||
typedef uintptr_t argon2_thread_handle_t;
|
||||
#else
|
||||
#include <pthread.h>
|
||||
typedef void *(*argon2_thread_func_t)(void *);
|
||||
typedef pthread_t argon2_thread_handle_t;
|
||||
#endif
|
||||
|
||||
/* Creates a thread
|
||||
* @param handle pointer to a thread handle, which is the output of this
|
||||
* function. Must not be NULL.
|
||||
* @param func A function pointer for the thread's entry point. Must not be
|
||||
* NULL.
|
||||
* @param args Pointer that is passed as an argument to @func. May be NULL.
|
||||
* @return 0 if @handle and @func are valid pointers and a thread is successfuly
|
||||
* created.
|
||||
*/
|
||||
int argon2_thread_create(argon2_thread_handle_t *handle,
|
||||
argon2_thread_func_t func, void *args);
|
||||
|
||||
/* Waits for a thread to terminate
|
||||
* @param handle Handle to a thread created with argon2_thread_create.
|
||||
* @return 0 if @handle is a valid handle, and joining completed successfully.
|
||||
*/
|
||||
int argon2_thread_join(argon2_thread_handle_t handle);
|
||||
|
||||
/* Terminate the current thread. Must be run inside a thread created by
|
||||
* argon2_thread_create.
|
||||
*/
|
||||
void argon2_thread_exit(void);
|
||||
|
||||
#endif
|
74
src/3rdparty/argon2/m4/ax_check_compile_flag.m4
vendored
Normal file
74
src/3rdparty/argon2/m4/ax_check_compile_flag.m4
vendored
Normal file
|
@ -0,0 +1,74 @@
|
|||
# ===========================================================================
|
||||
# http://www.gnu.org/software/autoconf-archive/ax_check_compile_flag.html
|
||||
# ===========================================================================
|
||||
#
|
||||
# SYNOPSIS
|
||||
#
|
||||
# AX_CHECK_COMPILE_FLAG(FLAG, [ACTION-SUCCESS], [ACTION-FAILURE], [EXTRA-FLAGS], [INPUT])
|
||||
#
|
||||
# DESCRIPTION
|
||||
#
|
||||
# Check whether the given FLAG works with the current language's compiler
|
||||
# or gives an error. (Warnings, however, are ignored)
|
||||
#
|
||||
# ACTION-SUCCESS/ACTION-FAILURE are shell commands to execute on
|
||||
# success/failure.
|
||||
#
|
||||
# If EXTRA-FLAGS is defined, it is added to the current language's default
|
||||
# flags (e.g. CFLAGS) when the check is done. The check is thus made with
|
||||
# the flags: "CFLAGS EXTRA-FLAGS FLAG". This can for example be used to
|
||||
# force the compiler to issue an error when a bad flag is given.
|
||||
#
|
||||
# INPUT gives an alternative input source to AC_COMPILE_IFELSE.
|
||||
#
|
||||
# NOTE: Implementation based on AX_CFLAGS_GCC_OPTION. Please keep this
|
||||
# macro in sync with AX_CHECK_{PREPROC,LINK}_FLAG.
|
||||
#
|
||||
# LICENSE
|
||||
#
|
||||
# Copyright (c) 2008 Guido U. Draheim <guidod@gmx.de>
|
||||
# Copyright (c) 2011 Maarten Bosmans <mkbosmans@gmail.com>
|
||||
#
|
||||
# This program is free software: you can redistribute it and/or modify it
|
||||
# under the terms of the GNU General Public License as published by the
|
||||
# Free Software Foundation, either version 3 of the License, or (at your
|
||||
# option) any later version.
|
||||
#
|
||||
# This program is distributed in the hope that it will be useful, but
|
||||
# WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General
|
||||
# Public License for more details.
|
||||
#
|
||||
# You should have received a copy of the GNU General Public License along
|
||||
# with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
#
|
||||
# As a special exception, the respective Autoconf Macro's copyright owner
|
||||
# gives unlimited permission to copy, distribute and modify the configure
|
||||
# scripts that are the output of Autoconf when processing the Macro. You
|
||||
# need not follow the terms of the GNU General Public License when using
|
||||
# or distributing such scripts, even though portions of the text of the
|
||||
# Macro appear in them. The GNU General Public License (GPL) does govern
|
||||
# all other use of the material that constitutes the Autoconf Macro.
|
||||
#
|
||||
# This special exception to the GPL applies to versions of the Autoconf
|
||||
# Macro released by the Autoconf Archive. When you make and distribute a
|
||||
# modified version of the Autoconf Macro, you may extend this special
|
||||
# exception to the GPL to apply to your modified version as well.
|
||||
|
||||
#serial 4
|
||||
|
||||
AC_DEFUN([AX_CHECK_COMPILE_FLAG],
|
||||
[AC_PREREQ(2.64)dnl for _AC_LANG_PREFIX and AS_VAR_IF
|
||||
AS_VAR_PUSHDEF([CACHEVAR],[ax_cv_check_[]_AC_LANG_ABBREV[]flags_$4_$1])dnl
|
||||
AC_CACHE_CHECK([whether _AC_LANG compiler accepts $1], CACHEVAR, [
|
||||
ax_check_save_flags=$[]_AC_LANG_PREFIX[]FLAGS
|
||||
_AC_LANG_PREFIX[]FLAGS="$[]_AC_LANG_PREFIX[]FLAGS $4 $1"
|
||||
AC_COMPILE_IFELSE([m4_default([$5],[AC_LANG_PROGRAM()])],
|
||||
[AS_VAR_SET(CACHEVAR,[yes])],
|
||||
[AS_VAR_SET(CACHEVAR,[no])])
|
||||
_AC_LANG_PREFIX[]FLAGS=$ax_check_save_flags])
|
||||
AS_VAR_IF(CACHEVAR,yes,
|
||||
[m4_default([$2], :)],
|
||||
[m4_default([$3], :)])
|
||||
AS_VAR_POPDEF([CACHEVAR])dnl
|
||||
])dnl AX_CHECK_COMPILE_FLAGS
|
485
src/3rdparty/argon2/m4/ax_pthread.m4
vendored
Normal file
485
src/3rdparty/argon2/m4/ax_pthread.m4
vendored
Normal file
|
@ -0,0 +1,485 @@
|
|||
# ===========================================================================
|
||||
# http://www.gnu.org/software/autoconf-archive/ax_pthread.html
|
||||
# ===========================================================================
|
||||
#
|
||||
# SYNOPSIS
|
||||
#
|
||||
# AX_PTHREAD([ACTION-IF-FOUND[, ACTION-IF-NOT-FOUND]])
|
||||
#
|
||||
# DESCRIPTION
|
||||
#
|
||||
# This macro figures out how to build C programs using POSIX threads. It
|
||||
# sets the PTHREAD_LIBS output variable to the threads library and linker
|
||||
# flags, and the PTHREAD_CFLAGS output variable to any special C compiler
|
||||
# flags that are needed. (The user can also force certain compiler
|
||||
# flags/libs to be tested by setting these environment variables.)
|
||||
#
|
||||
# Also sets PTHREAD_CC to any special C compiler that is needed for
|
||||
# multi-threaded programs (defaults to the value of CC otherwise). (This
|
||||
# is necessary on AIX to use the special cc_r compiler alias.)
|
||||
#
|
||||
# NOTE: You are assumed to not only compile your program with these flags,
|
||||
# but also to link with them as well. For example, you might link with
|
||||
# $PTHREAD_CC $CFLAGS $PTHREAD_CFLAGS $LDFLAGS ... $PTHREAD_LIBS $LIBS
|
||||
#
|
||||
# If you are only building threaded programs, you may wish to use these
|
||||
# variables in your default LIBS, CFLAGS, and CC:
|
||||
#
|
||||
# LIBS="$PTHREAD_LIBS $LIBS"
|
||||
# CFLAGS="$CFLAGS $PTHREAD_CFLAGS"
|
||||
# CC="$PTHREAD_CC"
|
||||
#
|
||||
# In addition, if the PTHREAD_CREATE_JOINABLE thread-attribute constant
|
||||
# has a nonstandard name, this macro defines PTHREAD_CREATE_JOINABLE to
|
||||
# that name (e.g. PTHREAD_CREATE_UNDETACHED on AIX).
|
||||
#
|
||||
# Also HAVE_PTHREAD_PRIO_INHERIT is defined if pthread is found and the
|
||||
# PTHREAD_PRIO_INHERIT symbol is defined when compiling with
|
||||
# PTHREAD_CFLAGS.
|
||||
#
|
||||
# ACTION-IF-FOUND is a list of shell commands to run if a threads library
|
||||
# is found, and ACTION-IF-NOT-FOUND is a list of commands to run it if it
|
||||
# is not found. If ACTION-IF-FOUND is not specified, the default action
|
||||
# will define HAVE_PTHREAD.
|
||||
#
|
||||
# Please let the authors know if this macro fails on any platform, or if
|
||||
# you have any other suggestions or comments. This macro was based on work
|
||||
# by SGJ on autoconf scripts for FFTW (http://www.fftw.org/) (with help
|
||||
# from M. Frigo), as well as ac_pthread and hb_pthread macros posted by
|
||||
# Alejandro Forero Cuervo to the autoconf macro repository. We are also
|
||||
# grateful for the helpful feedback of numerous users.
|
||||
#
|
||||
# Updated for Autoconf 2.68 by Daniel Richard G.
|
||||
#
|
||||
# LICENSE
|
||||
#
|
||||
# Copyright (c) 2008 Steven G. Johnson <stevenj@alum.mit.edu>
|
||||
# Copyright (c) 2011 Daniel Richard G. <skunk@iSKUNK.ORG>
|
||||
#
|
||||
# This program is free software: you can redistribute it and/or modify it
|
||||
# under the terms of the GNU General Public License as published by the
|
||||
# Free Software Foundation, either version 3 of the License, or (at your
|
||||
# option) any later version.
|
||||
#
|
||||
# This program is distributed in the hope that it will be useful, but
|
||||
# WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General
|
||||
# Public License for more details.
|
||||
#
|
||||
# You should have received a copy of the GNU General Public License along
|
||||
# with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
#
|
||||
# As a special exception, the respective Autoconf Macro's copyright owner
|
||||
# gives unlimited permission to copy, distribute and modify the configure
|
||||
# scripts that are the output of Autoconf when processing the Macro. You
|
||||
# need not follow the terms of the GNU General Public License when using
|
||||
# or distributing such scripts, even though portions of the text of the
|
||||
# Macro appear in them. The GNU General Public License (GPL) does govern
|
||||
# all other use of the material that constitutes the Autoconf Macro.
|
||||
#
|
||||
# This special exception to the GPL applies to versions of the Autoconf
|
||||
# Macro released by the Autoconf Archive. When you make and distribute a
|
||||
# modified version of the Autoconf Macro, you may extend this special
|
||||
# exception to the GPL to apply to your modified version as well.
|
||||
|
||||
#serial 23
|
||||
|
||||
AU_ALIAS([ACX_PTHREAD], [AX_PTHREAD])
|
||||
AC_DEFUN([AX_PTHREAD], [
|
||||
AC_REQUIRE([AC_CANONICAL_HOST])
|
||||
AC_REQUIRE([AC_PROG_CC])
|
||||
AC_REQUIRE([AC_PROG_SED])
|
||||
AC_LANG_PUSH([C])
|
||||
ax_pthread_ok=no
|
||||
|
||||
# We used to check for pthread.h first, but this fails if pthread.h
|
||||
# requires special compiler flags (e.g. on Tru64 or Sequent).
|
||||
# It gets checked for in the link test anyway.
|
||||
|
||||
# First of all, check if the user has set any of the PTHREAD_LIBS,
|
||||
# etcetera environment variables, and if threads linking works using
|
||||
# them:
|
||||
if test "x$PTHREAD_CFLAGS$PTHREAD_LIBS" != "x"; then
|
||||
ax_pthread_save_CC="$CC"
|
||||
ax_pthread_save_CFLAGS="$CFLAGS"
|
||||
ax_pthread_save_LIBS="$LIBS"
|
||||
AS_IF([test "x$PTHREAD_CC" != "x"], [CC="$PTHREAD_CC"])
|
||||
CFLAGS="$CFLAGS $PTHREAD_CFLAGS"
|
||||
LIBS="$PTHREAD_LIBS $LIBS"
|
||||
AC_MSG_CHECKING([for pthread_join using $CC $PTHREAD_CFLAGS $PTHREAD_LIBS])
|
||||
AC_LINK_IFELSE([AC_LANG_CALL([], [pthread_join])], [ax_pthread_ok=yes])
|
||||
AC_MSG_RESULT([$ax_pthread_ok])
|
||||
if test "x$ax_pthread_ok" = "xno"; then
|
||||
PTHREAD_LIBS=""
|
||||
PTHREAD_CFLAGS=""
|
||||
fi
|
||||
CC="$ax_pthread_save_CC"
|
||||
CFLAGS="$ax_pthread_save_CFLAGS"
|
||||
LIBS="$ax_pthread_save_LIBS"
|
||||
fi
|
||||
|
||||
# We must check for the threads library under a number of different
|
||||
# names; the ordering is very important because some systems
|
||||
# (e.g. DEC) have both -lpthread and -lpthreads, where one of the
|
||||
# libraries is broken (non-POSIX).
|
||||
|
||||
# Create a list of thread flags to try. Items starting with a "-" are
|
||||
# C compiler flags, and other items are library names, except for "none"
|
||||
# which indicates that we try without any flags at all, and "pthread-config"
|
||||
# which is a program returning the flags for the Pth emulation library.
|
||||
|
||||
ax_pthread_flags="pthreads none -Kthread -pthread -pthreads -mthreads pthread --thread-safe -mt pthread-config"
|
||||
|
||||
# The ordering *is* (sometimes) important. Some notes on the
|
||||
# individual items follow:
|
||||
|
||||
# pthreads: AIX (must check this before -lpthread)
|
||||
# none: in case threads are in libc; should be tried before -Kthread and
|
||||
# other compiler flags to prevent continual compiler warnings
|
||||
# -Kthread: Sequent (threads in libc, but -Kthread needed for pthread.h)
|
||||
# -pthread: Linux/gcc (kernel threads), BSD/gcc (userland threads), Tru64
|
||||
# (Note: HP C rejects this with "bad form for `-t' option")
|
||||
# -pthreads: Solaris/gcc (Note: HP C also rejects)
|
||||
# -mt: Sun Workshop C (may only link SunOS threads [-lthread], but it
|
||||
# doesn't hurt to check since this sometimes defines pthreads and
|
||||
# -D_REENTRANT too), HP C (must be checked before -lpthread, which
|
||||
# is present but should not be used directly; and before -mthreads,
|
||||
# because the compiler interprets this as "-mt" + "-hreads")
|
||||
# -mthreads: Mingw32/gcc, Lynx/gcc
|
||||
# pthread: Linux, etcetera
|
||||
# --thread-safe: KAI C++
|
||||
# pthread-config: use pthread-config program (for GNU Pth library)
|
||||
|
||||
case $host_os in
|
||||
|
||||
freebsd*)
|
||||
|
||||
# -kthread: FreeBSD kernel threads (preferred to -pthread since SMP-able)
|
||||
# lthread: LinuxThreads port on FreeBSD (also preferred to -pthread)
|
||||
|
||||
ax_pthread_flags="-kthread lthread $ax_pthread_flags"
|
||||
;;
|
||||
|
||||
hpux*)
|
||||
|
||||
# From the cc(1) man page: "[-mt] Sets various -D flags to enable
|
||||
# multi-threading and also sets -lpthread."
|
||||
|
||||
ax_pthread_flags="-mt -pthread pthread $ax_pthread_flags"
|
||||
;;
|
||||
|
||||
openedition*)
|
||||
|
||||
# IBM z/OS requires a feature-test macro to be defined in order to
|
||||
# enable POSIX threads at all, so give the user a hint if this is
|
||||
# not set. (We don't define these ourselves, as they can affect
|
||||
# other portions of the system API in unpredictable ways.)
|
||||
|
||||
AC_EGREP_CPP([AX_PTHREAD_ZOS_MISSING],
|
||||
[
|
||||
# if !defined(_OPEN_THREADS) && !defined(_UNIX03_THREADS)
|
||||
AX_PTHREAD_ZOS_MISSING
|
||||
# endif
|
||||
],
|
||||
[AC_MSG_WARN([IBM z/OS requires -D_OPEN_THREADS or -D_UNIX03_THREADS to enable pthreads support.])])
|
||||
;;
|
||||
|
||||
solaris*)
|
||||
|
||||
# On Solaris (at least, for some versions), libc contains stubbed
|
||||
# (non-functional) versions of the pthreads routines, so link-based
|
||||
# tests will erroneously succeed. (N.B.: The stubs are missing
|
||||
# pthread_cleanup_push, or rather a function called by this macro,
|
||||
# so we could check for that, but who knows whether they'll stub
|
||||
# that too in a future libc.) So we'll check first for the
|
||||
# standard Solaris way of linking pthreads (-mt -lpthread).
|
||||
|
||||
ax_pthread_flags="-mt,pthread pthread $ax_pthread_flags"
|
||||
;;
|
||||
esac
|
||||
|
||||
# GCC generally uses -pthread, or -pthreads on some platforms (e.g. SPARC)
|
||||
|
||||
AS_IF([test "x$GCC" = "xyes"],
|
||||
[ax_pthread_flags="-pthread -pthreads $ax_pthread_flags"])
|
||||
|
||||
# The presence of a feature test macro requesting re-entrant function
|
||||
# definitions is, on some systems, a strong hint that pthreads support is
|
||||
# correctly enabled
|
||||
|
||||
case $host_os in
|
||||
darwin* | hpux* | linux* | osf* | solaris*)
|
||||
ax_pthread_check_macro="_REENTRANT"
|
||||
;;
|
||||
|
||||
aix*)
|
||||
ax_pthread_check_macro="_THREAD_SAFE"
|
||||
;;
|
||||
|
||||
*)
|
||||
ax_pthread_check_macro="--"
|
||||
;;
|
||||
esac
|
||||
AS_IF([test "x$ax_pthread_check_macro" = "x--"],
|
||||
[ax_pthread_check_cond=0],
|
||||
[ax_pthread_check_cond="!defined($ax_pthread_check_macro)"])
|
||||
|
||||
# Are we compiling with Clang?
|
||||
|
||||
AC_CACHE_CHECK([whether $CC is Clang],
|
||||
[ax_cv_PTHREAD_CLANG],
|
||||
[ax_cv_PTHREAD_CLANG=no
|
||||
# Note that Autoconf sets GCC=yes for Clang as well as GCC
|
||||
if test "x$GCC" = "xyes"; then
|
||||
AC_EGREP_CPP([AX_PTHREAD_CC_IS_CLANG],
|
||||
[/* Note: Clang 2.7 lacks __clang_[a-z]+__ */
|
||||
# if defined(__clang__) && defined(__llvm__)
|
||||
AX_PTHREAD_CC_IS_CLANG
|
||||
# endif
|
||||
],
|
||||
[ax_cv_PTHREAD_CLANG=yes])
|
||||
fi
|
||||
])
|
||||
ax_pthread_clang="$ax_cv_PTHREAD_CLANG"
|
||||
|
||||
ax_pthread_clang_warning=no
|
||||
|
||||
# Clang needs special handling, because older versions handle the -pthread
|
||||
# option in a rather... idiosyncratic way
|
||||
|
||||
if test "x$ax_pthread_clang" = "xyes"; then
|
||||
|
||||
# Clang takes -pthread; it has never supported any other flag
|
||||
|
||||
# (Note 1: This will need to be revisited if a system that Clang
|
||||
# supports has POSIX threads in a separate library. This tends not
|
||||
# to be the way of modern systems, but it's conceivable.)
|
||||
|
||||
# (Note 2: On some systems, notably Darwin, -pthread is not needed
|
||||
# to get POSIX threads support; the API is always present and
|
||||
# active. We could reasonably leave PTHREAD_CFLAGS empty. But
|
||||
# -pthread does define _REENTRANT, and while the Darwin headers
|
||||
# ignore this macro, third-party headers might not.)
|
||||
|
||||
PTHREAD_CFLAGS="-pthread"
|
||||
PTHREAD_LIBS=
|
||||
|
||||
ax_pthread_ok=yes
|
||||
|
||||
# However, older versions of Clang make a point of warning the user
|
||||
# that, in an invocation where only linking and no compilation is
|
||||
# taking place, the -pthread option has no effect ("argument unused
|
||||
# during compilation"). They expect -pthread to be passed in only
|
||||
# when source code is being compiled.
|
||||
#
|
||||
# Problem is, this is at odds with the way Automake and most other
|
||||
# C build frameworks function, which is that the same flags used in
|
||||
# compilation (CFLAGS) are also used in linking. Many systems
|
||||
# supported by AX_PTHREAD require exactly this for POSIX threads
|
||||
# support, and in fact it is often not straightforward to specify a
|
||||
# flag that is used only in the compilation phase and not in
|
||||
# linking. Such a scenario is extremely rare in practice.
|
||||
#
|
||||
# Even though use of the -pthread flag in linking would only print
|
||||
# a warning, this can be a nuisance for well-run software projects
|
||||
# that build with -Werror. So if the active version of Clang has
|
||||
# this misfeature, we search for an option to squash it.
|
||||
|
||||
AC_CACHE_CHECK([whether Clang needs flag to prevent "argument unused" warning when linking with -pthread],
|
||||
[ax_cv_PTHREAD_CLANG_NO_WARN_FLAG],
|
||||
[ax_cv_PTHREAD_CLANG_NO_WARN_FLAG=unknown
|
||||
# Create an alternate version of $ac_link that compiles and
|
||||
# links in two steps (.c -> .o, .o -> exe) instead of one
|
||||
# (.c -> exe), because the warning occurs only in the second
|
||||
# step
|
||||
ax_pthread_save_ac_link="$ac_link"
|
||||
ax_pthread_sed='s/conftest\.\$ac_ext/conftest.$ac_objext/g'
|
||||
ax_pthread_link_step=`$as_echo "$ac_link" | sed "$ax_pthread_sed"`
|
||||
ax_pthread_2step_ac_link="($ac_compile) && (echo ==== >&5) && ($ax_pthread_link_step)"
|
||||
ax_pthread_save_CFLAGS="$CFLAGS"
|
||||
for ax_pthread_try in '' -Qunused-arguments -Wno-unused-command-line-argument unknown; do
|
||||
AS_IF([test "x$ax_pthread_try" = "xunknown"], [break])
|
||||
CFLAGS="-Werror -Wunknown-warning-option $ax_pthread_try -pthread $ax_pthread_save_CFLAGS"
|
||||
ac_link="$ax_pthread_save_ac_link"
|
||||
AC_LINK_IFELSE([AC_LANG_SOURCE([[int main(void){return 0;}]])],
|
||||
[ac_link="$ax_pthread_2step_ac_link"
|
||||
AC_LINK_IFELSE([AC_LANG_SOURCE([[int main(void){return 0;}]])],
|
||||
[break])
|
||||
])
|
||||
done
|
||||
ac_link="$ax_pthread_save_ac_link"
|
||||
CFLAGS="$ax_pthread_save_CFLAGS"
|
||||
AS_IF([test "x$ax_pthread_try" = "x"], [ax_pthread_try=no])
|
||||
ax_cv_PTHREAD_CLANG_NO_WARN_FLAG="$ax_pthread_try"
|
||||
])
|
||||
|
||||
case "$ax_cv_PTHREAD_CLANG_NO_WARN_FLAG" in
|
||||
no | unknown) ;;
|
||||
*) PTHREAD_CFLAGS="$ax_cv_PTHREAD_CLANG_NO_WARN_FLAG $PTHREAD_CFLAGS" ;;
|
||||
esac
|
||||
|
||||
fi # $ax_pthread_clang = yes
|
||||
|
||||
if test "x$ax_pthread_ok" = "xno"; then
|
||||
for ax_pthread_try_flag in $ax_pthread_flags; do
|
||||
|
||||
case $ax_pthread_try_flag in
|
||||
none)
|
||||
AC_MSG_CHECKING([whether pthreads work without any flags])
|
||||
;;
|
||||
|
||||
-mt,pthread)
|
||||
AC_MSG_CHECKING([whether pthreads work with -mt -lpthread])
|
||||
PTHREAD_CFLAGS="-mt"
|
||||
PTHREAD_LIBS="-lpthread"
|
||||
;;
|
||||
|
||||
-*)
|
||||
AC_MSG_CHECKING([whether pthreads work with $ax_pthread_try_flag])
|
||||
PTHREAD_CFLAGS="$ax_pthread_try_flag"
|
||||
;;
|
||||
|
||||
pthread-config)
|
||||
AC_CHECK_PROG([ax_pthread_config], [pthread-config], [yes], [no])
|
||||
AS_IF([test "x$ax_pthread_config" = "xno"], [continue])
|
||||
PTHREAD_CFLAGS="`pthread-config --cflags`"
|
||||
PTHREAD_LIBS="`pthread-config --ldflags` `pthread-config --libs`"
|
||||
;;
|
||||
|
||||
*)
|
||||
AC_MSG_CHECKING([for the pthreads library -l$ax_pthread_try_flag])
|
||||
PTHREAD_LIBS="-l$ax_pthread_try_flag"
|
||||
;;
|
||||
esac
|
||||
|
||||
ax_pthread_save_CFLAGS="$CFLAGS"
|
||||
ax_pthread_save_LIBS="$LIBS"
|
||||
CFLAGS="$CFLAGS $PTHREAD_CFLAGS"
|
||||
LIBS="$PTHREAD_LIBS $LIBS"
|
||||
|
||||
# Check for various functions. We must include pthread.h,
|
||||
# since some functions may be macros. (On the Sequent, we
|
||||
# need a special flag -Kthread to make this header compile.)
|
||||
# We check for pthread_join because it is in -lpthread on IRIX
|
||||
# while pthread_create is in libc. We check for pthread_attr_init
|
||||
# due to DEC craziness with -lpthreads. We check for
|
||||
# pthread_cleanup_push because it is one of the few pthread
|
||||
# functions on Solaris that doesn't have a non-functional libc stub.
|
||||
# We try pthread_create on general principles.
|
||||
|
||||
AC_LINK_IFELSE([AC_LANG_PROGRAM([#include <pthread.h>
|
||||
# if $ax_pthread_check_cond
|
||||
# error "$ax_pthread_check_macro must be defined"
|
||||
# endif
|
||||
static void routine(void *a) { a = 0; }
|
||||
static void *start_routine(void *a) { return a; }],
|
||||
[pthread_t th; pthread_attr_t attr;
|
||||
pthread_create(&th, 0, start_routine, 0);
|
||||
pthread_join(th, 0);
|
||||
pthread_attr_init(&attr);
|
||||
pthread_cleanup_push(routine, 0);
|
||||
pthread_cleanup_pop(0) /* ; */])],
|
||||
[ax_pthread_ok=yes],
|
||||
[])
|
||||
|
||||
CFLAGS="$ax_pthread_save_CFLAGS"
|
||||
LIBS="$ax_pthread_save_LIBS"
|
||||
|
||||
AC_MSG_RESULT([$ax_pthread_ok])
|
||||
AS_IF([test "x$ax_pthread_ok" = "xyes"], [break])
|
||||
|
||||
PTHREAD_LIBS=""
|
||||
PTHREAD_CFLAGS=""
|
||||
done
|
||||
fi
|
||||
|
||||
# Various other checks:
|
||||
if test "x$ax_pthread_ok" = "xyes"; then
|
||||
ax_pthread_save_CFLAGS="$CFLAGS"
|
||||
ax_pthread_save_LIBS="$LIBS"
|
||||
CFLAGS="$CFLAGS $PTHREAD_CFLAGS"
|
||||
LIBS="$PTHREAD_LIBS $LIBS"
|
||||
|
||||
# Detect AIX lossage: JOINABLE attribute is called UNDETACHED.
|
||||
AC_CACHE_CHECK([for joinable pthread attribute],
|
||||
[ax_cv_PTHREAD_JOINABLE_ATTR],
|
||||
[ax_cv_PTHREAD_JOINABLE_ATTR=unknown
|
||||
for ax_pthread_attr in PTHREAD_CREATE_JOINABLE PTHREAD_CREATE_UNDETACHED; do
|
||||
AC_LINK_IFELSE([AC_LANG_PROGRAM([#include <pthread.h>],
|
||||
[int attr = $ax_pthread_attr; return attr /* ; */])],
|
||||
[ax_cv_PTHREAD_JOINABLE_ATTR=$ax_pthread_attr; break],
|
||||
[])
|
||||
done
|
||||
])
|
||||
AS_IF([test "x$ax_cv_PTHREAD_JOINABLE_ATTR" != "xunknown" && \
|
||||
test "x$ax_cv_PTHREAD_JOINABLE_ATTR" != "xPTHREAD_CREATE_JOINABLE" && \
|
||||
test "x$ax_pthread_joinable_attr_defined" != "xyes"],
|
||||
[AC_DEFINE_UNQUOTED([PTHREAD_CREATE_JOINABLE],
|
||||
[$ax_cv_PTHREAD_JOINABLE_ATTR],
|
||||
[Define to necessary symbol if this constant
|
||||
uses a non-standard name on your system.])
|
||||
ax_pthread_joinable_attr_defined=yes
|
||||
])
|
||||
|
||||
AC_CACHE_CHECK([whether more special flags are required for pthreads],
|
||||
[ax_cv_PTHREAD_SPECIAL_FLAGS],
|
||||
[ax_cv_PTHREAD_SPECIAL_FLAGS=no
|
||||
case $host_os in
|
||||
solaris*)
|
||||
ax_cv_PTHREAD_SPECIAL_FLAGS="-D_POSIX_PTHREAD_SEMANTICS"
|
||||
;;
|
||||
esac
|
||||
])
|
||||
AS_IF([test "x$ax_cv_PTHREAD_SPECIAL_FLAGS" != "xno" && \
|
||||
test "x$ax_pthread_special_flags_added" != "xyes"],
|
||||
[PTHREAD_CFLAGS="$ax_cv_PTHREAD_SPECIAL_FLAGS $PTHREAD_CFLAGS"
|
||||
ax_pthread_special_flags_added=yes])
|
||||
|
||||
AC_CACHE_CHECK([for PTHREAD_PRIO_INHERIT],
|
||||
[ax_cv_PTHREAD_PRIO_INHERIT],
|
||||
[AC_LINK_IFELSE([AC_LANG_PROGRAM([[#include <pthread.h>]],
|
||||
[[int i = PTHREAD_PRIO_INHERIT;]])],
|
||||
[ax_cv_PTHREAD_PRIO_INHERIT=yes],
|
||||
[ax_cv_PTHREAD_PRIO_INHERIT=no])
|
||||
])
|
||||
AS_IF([test "x$ax_cv_PTHREAD_PRIO_INHERIT" = "xyes" && \
|
||||
test "x$ax_pthread_prio_inherit_defined" != "xyes"],
|
||||
[AC_DEFINE([HAVE_PTHREAD_PRIO_INHERIT], [1], [Have PTHREAD_PRIO_INHERIT.])
|
||||
ax_pthread_prio_inherit_defined=yes
|
||||
])
|
||||
|
||||
CFLAGS="$ax_pthread_save_CFLAGS"
|
||||
LIBS="$ax_pthread_save_LIBS"
|
||||
|
||||
# More AIX lossage: compile with *_r variant
|
||||
if test "x$GCC" != "xyes"; then
|
||||
case $host_os in
|
||||
aix*)
|
||||
AS_CASE(["x/$CC"],
|
||||
[x*/c89|x*/c89_128|x*/c99|x*/c99_128|x*/cc|x*/cc128|x*/xlc|x*/xlc_v6|x*/xlc128|x*/xlc128_v6],
|
||||
[#handle absolute path differently from PATH based program lookup
|
||||
AS_CASE(["x$CC"],
|
||||
[x/*],
|
||||
[AS_IF([AS_EXECUTABLE_P([${CC}_r])],[PTHREAD_CC="${CC}_r"])],
|
||||
[AC_CHECK_PROGS([PTHREAD_CC],[${CC}_r],[$CC])])])
|
||||
;;
|
||||
esac
|
||||
fi
|
||||
fi
|
||||
|
||||
test -n "$PTHREAD_CC" || PTHREAD_CC="$CC"
|
||||
|
||||
AC_SUBST([PTHREAD_LIBS])
|
||||
AC_SUBST([PTHREAD_CFLAGS])
|
||||
AC_SUBST([PTHREAD_CC])
|
||||
|
||||
# Finally, execute ACTION-IF-FOUND/ACTION-IF-NOT-FOUND:
|
||||
if test "x$ax_pthread_ok" = "xyes"; then
|
||||
ifelse([$1],,[AC_DEFINE([HAVE_PTHREAD],[1],[Define if you have POSIX threads libraries and header files.])],[$1])
|
||||
:
|
||||
else
|
||||
ax_pthread_ok=no
|
||||
$2
|
||||
fi
|
||||
AC_LANG_POP
|
||||
])dnl AX_PTHREAD
|
3
src/3rdparty/argon2/qmake/arch/arch.pro
vendored
Normal file
3
src/3rdparty/argon2/qmake/arch/arch.pro
vendored
Normal file
|
@ -0,0 +1,3 @@
|
|||
TEMPLATE = subdirs
|
||||
|
||||
SUBDIRS += $$ARCH
|
1
src/3rdparty/argon2/qmake/arch/generic/generic.pro
vendored
Normal file
1
src/3rdparty/argon2/qmake/arch/generic/generic.pro
vendored
Normal file
|
@ -0,0 +1 @@
|
|||
TEMPLATE = subdirs
|
23
src/3rdparty/argon2/qmake/arch/x86_64/libargon2-avx2/libargon2-avx2.pro
vendored
Normal file
23
src/3rdparty/argon2/qmake/arch/x86_64/libargon2-avx2/libargon2-avx2.pro
vendored
Normal file
|
@ -0,0 +1,23 @@
|
|||
QT -= core gui
|
||||
|
||||
TARGET = argon2-avx2
|
||||
TEMPLATE = lib
|
||||
CONFIG += staticlib
|
||||
|
||||
ARGON2_ROOT = ../../../..
|
||||
|
||||
INCLUDEPATH += \
|
||||
$$ARGON2_ROOT/include \
|
||||
$$ARGON2_ROOT/lib \
|
||||
$$ARGON2_ROOT/arch/$$ARCH/lib
|
||||
|
||||
USE_AVX2 {
|
||||
DEFINES += HAVE_AVX2
|
||||
QMAKE_CFLAGS += -mavx2
|
||||
}
|
||||
|
||||
SOURCES += \
|
||||
$$ARGON2_ROOT/arch/x86_64/lib/argon2-avx2.c
|
||||
|
||||
HEADERS += \
|
||||
$$ARGON2_ROOT/arch/x86_64/lib/argon2-avx2.h
|
23
src/3rdparty/argon2/qmake/arch/x86_64/libargon2-avx512f/libargon2-avx512f.pro
vendored
Normal file
23
src/3rdparty/argon2/qmake/arch/x86_64/libargon2-avx512f/libargon2-avx512f.pro
vendored
Normal file
|
@ -0,0 +1,23 @@
|
|||
QT -= core gui
|
||||
|
||||
TARGET = argon2-avx512f
|
||||
TEMPLATE = lib
|
||||
CONFIG += staticlib
|
||||
|
||||
ARGON2_ROOT = ../../../..
|
||||
|
||||
INCLUDEPATH += \
|
||||
$$ARGON2_ROOT/include \
|
||||
$$ARGON2_ROOT/lib \
|
||||
$$ARGON2_ROOT/arch/$$ARCH/lib
|
||||
|
||||
USE_AVX512F {
|
||||
DEFINES += HAVE_AVX512F
|
||||
QMAKE_CFLAGS += -mavx512f
|
||||
}
|
||||
|
||||
SOURCES += \
|
||||
$$ARGON2_ROOT/arch/x86_64/lib/argon2-avx512f.c
|
||||
|
||||
HEADERS += \
|
||||
$$ARGON2_ROOT/arch/x86_64/lib/argon2-avx512f.h
|
24
src/3rdparty/argon2/qmake/arch/x86_64/libargon2-sse2/libargon2-sse2.pro
vendored
Normal file
24
src/3rdparty/argon2/qmake/arch/x86_64/libargon2-sse2/libargon2-sse2.pro
vendored
Normal file
|
@ -0,0 +1,24 @@
|
|||
QT -= core gui
|
||||
|
||||
TARGET = argon2-sse2
|
||||
TEMPLATE = lib
|
||||
CONFIG += staticlib
|
||||
|
||||
ARGON2_ROOT = ../../../..
|
||||
|
||||
INCLUDEPATH += \
|
||||
$$ARGON2_ROOT/include \
|
||||
$$ARGON2_ROOT/lib \
|
||||
$$ARGON2_ROOT/arch/$$ARCH/lib
|
||||
|
||||
USE_SSE2 | USE_SSSE3 | USE_XOP | USE_AVX2 {
|
||||
DEFINES += HAVE_SSE2
|
||||
QMAKE_CFLAGS += -msse2
|
||||
}
|
||||
|
||||
SOURCES += \
|
||||
$$ARGON2_ROOT/arch/x86_64/lib/argon2-sse2.c
|
||||
|
||||
HEADERS += \
|
||||
$$ARGON2_ROOT/arch/x86_64/lib/argon2-sse2.h \
|
||||
$$ARGON2_ROOT/arch/x86_64/lib/argon2-template-128.h
|
24
src/3rdparty/argon2/qmake/arch/x86_64/libargon2-ssse3/libargon2-ssse3.pro
vendored
Normal file
24
src/3rdparty/argon2/qmake/arch/x86_64/libargon2-ssse3/libargon2-ssse3.pro
vendored
Normal file
|
@ -0,0 +1,24 @@
|
|||
QT -= core gui
|
||||
|
||||
TARGET = argon2-ssse3
|
||||
TEMPLATE = lib
|
||||
CONFIG += staticlib
|
||||
|
||||
ARGON2_ROOT = ../../../..
|
||||
|
||||
INCLUDEPATH += \
|
||||
$$ARGON2_ROOT/include \
|
||||
$$ARGON2_ROOT/lib \
|
||||
$$ARGON2_ROOT/arch/$$ARCH/lib
|
||||
|
||||
USE_SSSE3 | USE_XOP | USE_AVX2 {
|
||||
DEFINES += HAVE_SSSE3
|
||||
QMAKE_CFLAGS += -mssse3
|
||||
}
|
||||
|
||||
SOURCES += \
|
||||
$$ARGON2_ROOT/arch/x86_64/lib/argon2-ssse3.c
|
||||
|
||||
HEADERS += \
|
||||
$$ARGON2_ROOT/arch/x86_64/lib/argon2-ssse3.h \
|
||||
$$ARGON2_ROOT/arch/x86_64/lib/argon2-template-128.h
|
24
src/3rdparty/argon2/qmake/arch/x86_64/libargon2-xop/libargon2-xop.pro
vendored
Normal file
24
src/3rdparty/argon2/qmake/arch/x86_64/libargon2-xop/libargon2-xop.pro
vendored
Normal file
|
@ -0,0 +1,24 @@
|
|||
QT -= core gui
|
||||
|
||||
TARGET = argon2-xop
|
||||
TEMPLATE = lib
|
||||
CONFIG += staticlib
|
||||
|
||||
ARGON2_ROOT = ../../../..
|
||||
|
||||
INCLUDEPATH += \
|
||||
$$ARGON2_ROOT/include \
|
||||
$$ARGON2_ROOT/lib \
|
||||
$$ARGON2_ROOT/arch/$$ARCH/lib
|
||||
|
||||
USE_XOP {
|
||||
DEFINES += HAVE_XOP
|
||||
QMAKE_CFLAGS += -mxop
|
||||
}
|
||||
|
||||
SOURCES += \
|
||||
$$ARGON2_ROOT/arch/x86_64/lib/argon2-xop.c
|
||||
|
||||
HEADERS += \
|
||||
$$ARGON2_ROOT/arch/x86_64/lib/argon2-xop.h \
|
||||
$$ARGON2_ROOT/arch/x86_64/lib/argon2-template-128.h
|
8
src/3rdparty/argon2/qmake/arch/x86_64/x86_64.pro
vendored
Normal file
8
src/3rdparty/argon2/qmake/arch/x86_64/x86_64.pro
vendored
Normal file
|
@ -0,0 +1,8 @@
|
|||
TEMPLATE = subdirs
|
||||
|
||||
SUBDIRS += \
|
||||
libargon2-sse2 \
|
||||
libargon2-ssse3 \
|
||||
libargon2-xop \
|
||||
libargon2-avx2 \
|
||||
libargon2-avx512f
|
19
src/3rdparty/argon2/qmake/argon2-bench2/argon2-bench2.pro
vendored
Normal file
19
src/3rdparty/argon2/qmake/argon2-bench2/argon2-bench2.pro
vendored
Normal file
|
@ -0,0 +1,19 @@
|
|||
TEMPLATE = app
|
||||
CONFIG += console c++11
|
||||
CONFIG -= app_bundle
|
||||
CONFIG -= qt
|
||||
|
||||
ARGON2_ROOT = ../..
|
||||
|
||||
SOURCES += \
|
||||
$$ARGON2_ROOT/src/bench2.c
|
||||
|
||||
HEADERS += \
|
||||
$$ARGON2_ROOT/src/timing.h
|
||||
|
||||
win32:CONFIG(release, debug|release): LIBS += -L$$OUT_PWD/../libargon2/release/ -largon2
|
||||
else:win32:CONFIG(debug, debug|release): LIBS += -L$$OUT_PWD/../libargon2/debug/ -largon2
|
||||
else:unix: LIBS += -L$$OUT_PWD/../libargon2/ -largon2
|
||||
|
||||
INCLUDEPATH += $$PWD/../../include
|
||||
DEPENDPATH += $$PWD/../../include
|
16
src/3rdparty/argon2/qmake/argon2-genkat/argon2-genkat.pro
vendored
Normal file
16
src/3rdparty/argon2/qmake/argon2-genkat/argon2-genkat.pro
vendored
Normal file
|
@ -0,0 +1,16 @@
|
|||
TEMPLATE = app
|
||||
CONFIG += console c++11
|
||||
CONFIG -= app_bundle
|
||||
CONFIG -= qt
|
||||
|
||||
ARGON2_ROOT = ../..
|
||||
|
||||
SOURCES += \
|
||||
$$ARGON2_ROOT/src/genkat.c
|
||||
|
||||
win32:CONFIG(release, debug|release): LIBS += -L$$OUT_PWD/../libargon2/release/ -largon2
|
||||
else:win32:CONFIG(debug, debug|release): LIBS += -L$$OUT_PWD/../libargon2/debug/ -largon2
|
||||
else:unix: LIBS += -L$$OUT_PWD/../libargon2/ -largon2
|
||||
|
||||
INCLUDEPATH += $$PWD/../../include
|
||||
DEPENDPATH += $$PWD/../../include
|
16
src/3rdparty/argon2/qmake/argon2-test/argon2-test.pro
vendored
Normal file
16
src/3rdparty/argon2/qmake/argon2-test/argon2-test.pro
vendored
Normal file
|
@ -0,0 +1,16 @@
|
|||
TEMPLATE = app
|
||||
CONFIG += console c++11
|
||||
CONFIG -= app_bundle
|
||||
CONFIG -= qt
|
||||
|
||||
ARGON2_ROOT = ../..
|
||||
|
||||
SOURCES += \
|
||||
$$ARGON2_ROOT/tests/test.c
|
||||
|
||||
win32:CONFIG(release, debug|release): LIBS += -L$$OUT_PWD/../libargon2/release/ -largon2
|
||||
else:win32:CONFIG(debug, debug|release): LIBS += -L$$OUT_PWD/../libargon2/debug/ -largon2
|
||||
else:unix: LIBS += -L$$OUT_PWD/../libargon2/ -largon2
|
||||
|
||||
INCLUDEPATH += $$PWD/../../include
|
||||
DEPENDPATH += $$PWD/../../include
|
9
src/3rdparty/argon2/qmake/argon2.pro
vendored
Normal file
9
src/3rdparty/argon2/qmake/argon2.pro
vendored
Normal file
|
@ -0,0 +1,9 @@
|
|||
TEMPLATE = subdirs
|
||||
|
||||
SUBDIRS += \
|
||||
arch \
|
||||
libargon2 \
|
||||
argon2 \
|
||||
argon2-genkat \
|
||||
argon2-bench2 \
|
||||
argon2-test
|
18
src/3rdparty/argon2/qmake/argon2/argon2.pro
vendored
Normal file
18
src/3rdparty/argon2/qmake/argon2/argon2.pro
vendored
Normal file
|
@ -0,0 +1,18 @@
|
|||
TEMPLATE = app
|
||||
CONFIG += console c++11
|
||||
CONFIG -= app_bundle
|
||||
CONFIG -= qt
|
||||
|
||||
ARGON2_ROOT = ../..
|
||||
|
||||
SOURCES += \
|
||||
$$ARGON2_ROOT/src/run.c
|
||||
|
||||
win32: DEFINES += argon2_EXPORT
|
||||
|
||||
win32:CONFIG(release, debug|release): LIBS += -L$$OUT_PWD/../libargon2/release/ -largon2
|
||||
else:win32:CONFIG(debug, debug|release): LIBS += -L$$OUT_PWD/../libargon2/debug/ -largon2
|
||||
else:unix: LIBS += -L$$OUT_PWD/../libargon2/ -largon2
|
||||
|
||||
INCLUDEPATH += $$PWD/../../include $$PWD/../../lib
|
||||
DEPENDPATH += $$PWD/../../include $$PWD/../../lib
|
119
src/3rdparty/argon2/qmake/libargon2/libargon2.pro
vendored
Normal file
119
src/3rdparty/argon2/qmake/libargon2/libargon2.pro
vendored
Normal file
|
@ -0,0 +1,119 @@
|
|||
#-------------------------------------------------
|
||||
#
|
||||
# Project created by QtCreator 2016-08-08T17:43:00
|
||||
#
|
||||
#-------------------------------------------------
|
||||
|
||||
QT -= core gui
|
||||
|
||||
TARGET = argon2
|
||||
TEMPLATE = lib
|
||||
|
||||
ARGON2_ROOT = ../..
|
||||
|
||||
INCLUDEPATH += \
|
||||
$$ARGON2_ROOT/include \
|
||||
$$ARGON2_ROOT/lib
|
||||
|
||||
SOURCES += \
|
||||
$$ARGON2_ROOT/lib/argon2.c \
|
||||
$$ARGON2_ROOT/lib/core.c \
|
||||
$$ARGON2_ROOT/lib/encoding.c \
|
||||
$$ARGON2_ROOT/lib/genkat.c \
|
||||
$$ARGON2_ROOT/lib/impl-select.c \
|
||||
$$ARGON2_ROOT/lib/thread.c \
|
||||
$$ARGON2_ROOT/lib/blake2/blake2.c
|
||||
|
||||
HEADERS += \
|
||||
$$ARGON2_ROOT/include/argon2.h \
|
||||
$$ARGON2_ROOT/lib/argon2-template-64.h \
|
||||
$$ARGON2_ROOT/lib/core.h \
|
||||
$$ARGON2_ROOT/lib/encoding.h \
|
||||
$$ARGON2_ROOT/lib/genkat.h \
|
||||
$$ARGON2_ROOT/lib/impl-select.h \
|
||||
$$ARGON2_ROOT/lib/thread.h \
|
||||
$$ARGON2_ROOT/lib/blake2/blake2.h \
|
||||
$$ARGON2_ROOT/lib/blake2/blake2-impl.h
|
||||
|
||||
equals(ARCH, x86_64) {
|
||||
SOURCES += \
|
||||
$$ARGON2_ROOT/arch/$$ARCH/lib/cpu-flags.c \
|
||||
$$ARGON2_ROOT/arch/$$ARCH/lib/argon2-arch.c
|
||||
|
||||
HEADERS += \
|
||||
$$ARGON2_ROOT/arch/$$ARCH/lib/cpu-flags.h
|
||||
|
||||
# libargon2-sse2.a:
|
||||
win32:CONFIG(release, debug|release): LIBS += -L$$OUT_PWD/../arch/x86_64/libargon2-sse2/release/ -largon2-sse2
|
||||
else:win32:CONFIG(debug, debug|release): LIBS += -L$$OUT_PWD/../arch/x86_64/libargon2-sse2/debug/ -largon2-sse2
|
||||
else:unix: LIBS += -L$$OUT_PWD/../arch/x86_64/libargon2-sse2/ -largon2-sse2
|
||||
|
||||
DEPENDPATH += $$PWD/../arch/x86_64/libargon2-sse2
|
||||
|
||||
win32-g++:CONFIG(release, debug|release): PRE_TARGETDEPS += $$OUT_PWD/../arch/x86_64/libargon2-sse2/release/libargon2-sse2.a
|
||||
else:win32-g++:CONFIG(debug, debug|release): PRE_TARGETDEPS += $$OUT_PWD/../arch/x86_64/libargon2-sse2/debug/libargon2-sse2.a
|
||||
else:win32:!win32-g++:CONFIG(release, debug|release): PRE_TARGETDEPS += $$OUT_PWD/../arch/x86_64/libargon2-sse2/release/argon2-sse2.lib
|
||||
else:win32:!win32-g++:CONFIG(debug, debug|release): PRE_TARGETDEPS += $$OUT_PWD/../arch/x86_64/libargon2-sse2/debug/argon2-sse2.lib
|
||||
else:unix: PRE_TARGETDEPS += $$OUT_PWD/../arch/x86_64/libargon2-sse2/libargon2-sse2.a
|
||||
|
||||
# libargon2-ssse3.a:
|
||||
win32:CONFIG(release, debug|release): LIBS += -L$$OUT_PWD/../arch/x86_64/libargon2-ssse3/release/ -largon2-ssse3
|
||||
else:win32:CONFIG(debug, debug|release): LIBS += -L$$OUT_PWD/../arch/x86_64/libargon2-ssse3/debug/ -largon2-ssse3
|
||||
else:unix: LIBS += -L$$OUT_PWD/../arch/x86_64/libargon2-ssse3/ -largon2-ssse3
|
||||
|
||||
DEPENDPATH += $$PWD/../arch/x86_64/libargon2-ssse3
|
||||
|
||||
win32-g++:CONFIG(release, debug|release): PRE_TARGETDEPS += $$OUT_PWD/../arch/x86_64/libargon2-ssse3/release/libargon2-ssse3.a
|
||||
else:win32-g++:CONFIG(debug, debug|release): PRE_TARGETDEPS += $$OUT_PWD/../arch/x86_64/libargon2-ssse3/debug/libargon2-ssse3.a
|
||||
else:win32:!win32-g++:CONFIG(release, debug|release): PRE_TARGETDEPS += $$OUT_PWD/../arch/x86_64/libargon2-ssse3/release/argon2-ssse3.lib
|
||||
else:win32:!win32-g++:CONFIG(debug, debug|release): PRE_TARGETDEPS += $$OUT_PWD/../arch/x86_64/libargon2-ssse3/debug/argon2-ssse3.lib
|
||||
else:unix: PRE_TARGETDEPS += $$OUT_PWD/../arch/x86_64/libargon2-ssse3/libargon2-ssse3.a
|
||||
|
||||
# libargon2-xop.a:
|
||||
win32:CONFIG(release, debug|release): LIBS += -L$$OUT_PWD/../arch/x86_64/libargon2-xop/release/ -largon2-xop
|
||||
else:win32:CONFIG(debug, debug|release): LIBS += -L$$OUT_PWD/../arch/x86_64/libargon2-xop/debug/ -largon2-xop
|
||||
else:unix: LIBS += -L$$OUT_PWD/../arch/x86_64/libargon2-xop/ -largon2-xop
|
||||
|
||||
DEPENDPATH += $$PWD/../arch/x86_64/libargon2-xop
|
||||
|
||||
win32-g++:CONFIG(release, debug|release): PRE_TARGETDEPS += $$OUT_PWD/../arch/x86_64/libargon2-xop/release/libargon2-xop.a
|
||||
else:win32-g++:CONFIG(debug, debug|release): PRE_TARGETDEPS += $$OUT_PWD/../arch/x86_64/libargon2-xop/debug/libargon2-xop.a
|
||||
else:win32:!win32-g++:CONFIG(release, debug|release): PRE_TARGETDEPS += $$OUT_PWD/../arch/x86_64/libargon2-xop/release/argon2-xop.lib
|
||||
else:win32:!win32-g++:CONFIG(debug, debug|release): PRE_TARGETDEPS += $$OUT_PWD/../arch/x86_64/libargon2-xop/debug/argon2-xop.lib
|
||||
else:unix: PRE_TARGETDEPS += $$OUT_PWD/../arch/x86_64/libargon2-xop/libargon2-xop.a
|
||||
|
||||
# libargon2-avx2.a:
|
||||
win32:CONFIG(release, debug|release): LIBS += -L$$OUT_PWD/../arch/x86_64/libargon2-avx2/release/ -largon2-avx2
|
||||
else:win32:CONFIG(debug, debug|release): LIBS += -L$$OUT_PWD/../arch/x86_64/libargon2-avx2/debug/ -largon2-avx2
|
||||
else:unix: LIBS += -L$$OUT_PWD/../arch/x86_64/libargon2-avx2/ -largon2-avx2
|
||||
|
||||
DEPENDPATH += $$PWD/../arch/x86_64/libargon2-avx2
|
||||
|
||||
win32-g++:CONFIG(release, debug|release): PRE_TARGETDEPS += $$OUT_PWD/../arch/x86_64/libargon2-avx2/release/libargon2-avx2.a
|
||||
else:win32-g++:CONFIG(debug, debug|release): PRE_TARGETDEPS += $$OUT_PWD/../arch/x86_64/libargon2-avx2/debug/libargon2-avx2.a
|
||||
else:win32:!win32-g++:CONFIG(release, debug|release): PRE_TARGETDEPS += $$OUT_PWD/../arch/x86_64/libargon2-avx2/release/argon2-avx2.lib
|
||||
else:win32:!win32-g++:CONFIG(debug, debug|release): PRE_TARGETDEPS += $$OUT_PWD/../arch/x86_64/libargon2-avx2/debug/argon2-avx2.lib
|
||||
else:unix: PRE_TARGETDEPS += $$OUT_PWD/../arch/x86_64/libargon2-avx2/libargon2-avx2.a
|
||||
|
||||
# libargon2-avx512f.a:
|
||||
win32:CONFIG(release, debug|release): LIBS += -L$$OUT_PWD/../arch/x86_64/libargon2-avx512f/release/ -largon2-avx512f
|
||||
else:win32:CONFIG(debug, debug|release): LIBS += -L$$OUT_PWD/../arch/x86_64/libargon2-avx512f/debug/ -largon2-avx512f
|
||||
else:unix: LIBS += -L$$OUT_PWD/../arch/x86_64/libargon2-avx512f/ -largon2-avx512f
|
||||
|
||||
DEPENDPATH += $$PWD/../arch/x86_64/libargon2-avx512f
|
||||
|
||||
win32-g++:CONFIG(release, debug|release): PRE_TARGETDEPS += $$OUT_PWD/../arch/x86_64/libargon2-avx512f/release/libargon2-avx512f.a
|
||||
else:win32-g++:CONFIG(debug, debug|release): PRE_TARGETDEPS += $$OUT_PWD/../arch/x86_64/libargon2-avx512f/debug/libargon2-avx512f.a
|
||||
else:win32:!win32-g++:CONFIG(release, debug|release): PRE_TARGETDEPS += $$OUT_PWD/../arch/x86_64/libargon2-avx512f/release/argon2-avx512f.lib
|
||||
else:win32:!win32-g++:CONFIG(debug, debug|release): PRE_TARGETDEPS += $$OUT_PWD/../arch/x86_64/libargon2-avx512f/debug/argon2-avx512f.lib
|
||||
else:unix: PRE_TARGETDEPS += $$OUT_PWD/../arch/x86_64/libargon2-avx512f/libargon2-avx512f.a
|
||||
}
|
||||
equals(ARCH, generic) {
|
||||
SOURCES += \
|
||||
$$ARGON2_ROOT/arch/$$ARCH/lib/argon2-arch.c
|
||||
}
|
||||
|
||||
unix {
|
||||
target.path = /usr/lib
|
||||
INSTALLS += target
|
||||
}
|
12
src/3rdparty/argon2/scripts/metacentrum/start-all-benchmarks.sh
vendored
Normal file
12
src/3rdparty/argon2/scripts/metacentrum/start-all-benchmarks.sh
vendored
Normal file
|
@ -0,0 +1,12 @@
|
|||
#!/bin/bash
|
||||
|
||||
dirname="$(dirname "$0")"
|
||||
|
||||
cd "$dirname" || exit 1
|
||||
|
||||
./start-benchmark.sh luna
|
||||
./start-benchmark.sh lex '' '' '' '' '' backfill
|
||||
./start-benchmark.sh mandos
|
||||
./start-benchmark.sh zubat
|
||||
PBS_SERVER=wagap.cerit-sc.cz \
|
||||
./start-benchmark.sh zapat '' '' '' '' '' default@wagap.cerit-sc.cz
|
75
src/3rdparty/argon2/scripts/metacentrum/start-benchmark.sh
vendored
Normal file
75
src/3rdparty/argon2/scripts/metacentrum/start-benchmark.sh
vendored
Normal file
|
@ -0,0 +1,75 @@
|
|||
#!/bin/bash
|
||||
|
||||
machine="$1"
|
||||
max_t_cost="$2"
|
||||
max_m_cost="$3"
|
||||
max_lanes="$4"
|
||||
branch="$5"
|
||||
duration="$6"
|
||||
queue="$7"
|
||||
run_tests="$8"
|
||||
|
||||
if [ -z "$machine" ]; then
|
||||
echo "ERROR: Machine must be specified!" 1>&2
|
||||
exit 1
|
||||
fi
|
||||
|
||||
if [ -z "$max_t_cost" ]; then
|
||||
max_t_cost=16
|
||||
fi
|
||||
|
||||
if [ -z "$max_m_cost" ]; then
|
||||
max_m_cost=$((8 * 1024 * 1024))
|
||||
fi
|
||||
|
||||
if [ -z "$max_lanes" ]; then
|
||||
max_lanes=16
|
||||
fi
|
||||
|
||||
if [ -z "$branch" ]; then
|
||||
branch='master'
|
||||
fi
|
||||
|
||||
if [ -z "$duration" ]; then
|
||||
duration=2h
|
||||
fi
|
||||
|
||||
REPO_URL='https://github.com/WOnder93/argon2.git'
|
||||
|
||||
dest_dir="$(pwd)"
|
||||
|
||||
task_file="$(mktemp)"
|
||||
|
||||
cat >$task_file <<EOF
|
||||
#!/bin/bash
|
||||
#PBS -N argon2-cpu-$machine-$branch
|
||||
#PBS -l walltime=$duration
|
||||
#PBS -l nodes=1:ppn=$max_lanes:cl_$machine
|
||||
#PBS -l mem=$(($max_m_cost / (1024 * 1024) + 1))gb
|
||||
$(if [ -n "$queue" ]; then echo "#PBS -q $queue"; fi)
|
||||
|
||||
module add cmake-3.6.1
|
||||
|
||||
mkdir -p "$dest_dir/\$PBS_JOBID" || exit 1
|
||||
|
||||
cd "$dest_dir/\$PBS_JOBID" || exit 1
|
||||
|
||||
git clone "$REPO_URL" argon2 || exit 1
|
||||
|
||||
cd argon2 || exit 1
|
||||
|
||||
git checkout "$branch" || exit 1
|
||||
|
||||
(autoreconf -i && ./configure && make) || exit 1
|
||||
|
||||
if [ "$run_tests" == "yes" ]; then
|
||||
make check
|
||||
fi
|
||||
|
||||
bash scripts/run-benchmark.sh $max_t_cost $max_m_cost $max_lanes \
|
||||
>"$dest_dir/\$PBS_JOBID/benchmark-$machine-$branch.csv"
|
||||
EOF
|
||||
|
||||
qsub "$task_file"
|
||||
|
||||
rm -f "$task_file"
|
40
src/3rdparty/argon2/scripts/run-benchmark.sh
vendored
Normal file
40
src/3rdparty/argon2/scripts/run-benchmark.sh
vendored
Normal file
|
@ -0,0 +1,40 @@
|
|||
#!/bin/bash
|
||||
|
||||
max_t_cost="$1"
|
||||
max_m_cost="$2"
|
||||
max_lanes="$3"
|
||||
|
||||
if [ -z "$max_t_cost" ]; then
|
||||
echo "ERROR: Maximum time cost must be specified!" 1>&2
|
||||
exit 1
|
||||
fi
|
||||
|
||||
if [ -z "$max_m_cost" ]; then
|
||||
echo "ERROR: Maximum memory cost must be specified!" 1>&2
|
||||
exit 1
|
||||
fi
|
||||
|
||||
if [ -z "$max_lanes" ]; then
|
||||
echo "ERROR: Maximum number of lanes must be specified!" 1>&2
|
||||
exit 1
|
||||
fi
|
||||
|
||||
dirname="$(dirname "$0")"
|
||||
|
||||
cd "$dirname/.." || exit 1
|
||||
|
||||
echo "t_cost,m_cost,lanes,ms_i,ms_d,ms_id"
|
||||
stdbuf -oL ./argon2-bench2 $max_t_cost $max_m_cost $max_lanes |
|
||||
stdbuf -oL tail -n +2 |
|
||||
while read line; do
|
||||
print_comma=0
|
||||
for x in $line; do
|
||||
if [ $print_comma -eq 1 ]; then
|
||||
echo -n ","
|
||||
else
|
||||
print_comma=1
|
||||
fi
|
||||
echo -n "$x"
|
||||
done
|
||||
echo
|
||||
done
|
179
src/3rdparty/argon2/src/bench2.c
vendored
Normal file
179
src/3rdparty/argon2/src/bench2.c
vendored
Normal file
|
@ -0,0 +1,179 @@
|
|||
#include <stdlib.h>
|
||||
#include <stdint.h>
|
||||
#include <string.h>
|
||||
#include <stdio.h>
|
||||
#include <math.h>
|
||||
|
||||
#include "argon2.h"
|
||||
|
||||
#include "timing.h"
|
||||
|
||||
#define ARGON2_BLOCK_SIZE 1024
|
||||
|
||||
#define BENCH_MAX_T_COST 16
|
||||
#define BENCH_MAX_M_COST (1024 * 1024)
|
||||
#define BENCH_MAX_THREADS 8
|
||||
#define BENCH_MIN_PASSES (1024 * 1024)
|
||||
#define BENCH_MAX_SAMPLES 128
|
||||
|
||||
#define BENCH_OUTLEN 16
|
||||
#define BENCH_INLEN 16
|
||||
|
||||
static double pick_min(const double *samples, size_t count)
|
||||
{
|
||||
size_t i;
|
||||
double min = INFINITY;
|
||||
for (i = 0; i < count; i++) {
|
||||
if (samples[i] < min) {
|
||||
min = samples[i];
|
||||
}
|
||||
}
|
||||
return min;
|
||||
}
|
||||
|
||||
static int benchmark(void *memory, size_t memory_size,
|
||||
uint32_t t_cost, uint32_t m_cost, uint32_t p)
|
||||
{
|
||||
static const unsigned char PASSWORD[BENCH_OUTLEN] = { 0 };
|
||||
static const unsigned char SALT[BENCH_INLEN] = { 1 };
|
||||
|
||||
unsigned char out[BENCH_OUTLEN];
|
||||
struct timestamp start, end;
|
||||
double ms_d[BENCH_MAX_SAMPLES];
|
||||
double ms_i[BENCH_MAX_SAMPLES];
|
||||
double ms_id[BENCH_MAX_SAMPLES];
|
||||
|
||||
double ms_d_final, ms_i_final, ms_id_final;
|
||||
unsigned int i, bench_samples;
|
||||
argon2_context ctx;
|
||||
|
||||
int res;
|
||||
|
||||
ctx.out = out;
|
||||
ctx.outlen = sizeof(out);
|
||||
ctx.pwd = (uint8_t *)PASSWORD;
|
||||
ctx.pwdlen = sizeof(PASSWORD);
|
||||
ctx.salt = (uint8_t *)SALT;
|
||||
ctx.saltlen = sizeof(SALT);
|
||||
ctx.secret = NULL;
|
||||
ctx.secretlen = 0;
|
||||
ctx.ad = NULL;
|
||||
ctx.adlen = 0;
|
||||
ctx.t_cost = t_cost;
|
||||
ctx.m_cost = m_cost;
|
||||
ctx.lanes = ctx.threads = p;
|
||||
ctx.version = ARGON2_VERSION_NUMBER;
|
||||
ctx.allocate_cbk = NULL;
|
||||
ctx.free_cbk = NULL;
|
||||
ctx.flags = ARGON2_DEFAULT_FLAGS;
|
||||
|
||||
bench_samples = (BENCH_MIN_PASSES * p) / (t_cost * m_cost);
|
||||
bench_samples += (BENCH_MIN_PASSES * p) % (t_cost * m_cost) != 0;
|
||||
|
||||
if (bench_samples > BENCH_MAX_SAMPLES) {
|
||||
bench_samples = BENCH_MAX_SAMPLES;
|
||||
}
|
||||
for (i = 0; i < bench_samples; i++) {
|
||||
timestamp_store(&start);
|
||||
res = argon2_ctx_mem(&ctx, Argon2_d, memory, memory_size);
|
||||
timestamp_store(&end);
|
||||
if (res != ARGON2_OK) {
|
||||
return res;
|
||||
}
|
||||
|
||||
ms_d[i] = timestamp_span_ms(&start, &end);
|
||||
}
|
||||
|
||||
for (i = 0; i < bench_samples; i++) {
|
||||
timestamp_store(&start);
|
||||
res = argon2_ctx_mem(&ctx, Argon2_i, memory, memory_size);
|
||||
timestamp_store(&end);
|
||||
if (res != ARGON2_OK) {
|
||||
return res;
|
||||
}
|
||||
|
||||
ms_i[i] = timestamp_span_ms(&start, &end);
|
||||
}
|
||||
|
||||
for (i = 0; i < bench_samples; i++) {
|
||||
timestamp_store(&start);
|
||||
res = argon2_ctx_mem(&ctx, Argon2_id, memory, memory_size);
|
||||
timestamp_store(&end);
|
||||
if (res != ARGON2_OK) {
|
||||
return res;
|
||||
}
|
||||
|
||||
ms_id[i] = timestamp_span_ms(&start, &end);
|
||||
}
|
||||
|
||||
ms_d_final = pick_min(ms_d, bench_samples);
|
||||
ms_i_final = pick_min(ms_i, bench_samples);
|
||||
ms_id_final = pick_min(ms_id, bench_samples);
|
||||
|
||||
printf("%8lu%16lu%8lu%16.6lf%16.6lf%16.6lf\n",
|
||||
(unsigned long)t_cost, (unsigned long)m_cost, (unsigned long)p,
|
||||
ms_d_final, ms_i_final, ms_id_final);
|
||||
return 0;
|
||||
}
|
||||
|
||||
int main(int argc, const char * const *argv)
|
||||
{
|
||||
uint32_t max_t_cost = BENCH_MAX_T_COST;
|
||||
uint32_t max_m_cost = BENCH_MAX_M_COST;
|
||||
uint32_t max_p = BENCH_MAX_THREADS;
|
||||
uint32_t t_cost, m_cost, p;
|
||||
char *end;
|
||||
int res;
|
||||
|
||||
if (argc >= 2) {
|
||||
max_t_cost = strtoul(argv[1], &end, 10);
|
||||
if (end == argv[1]) {
|
||||
fprintf(stderr, "ERROR: Invalid number format!\n");
|
||||
return 1;
|
||||
}
|
||||
}
|
||||
|
||||
if (argc >= 3) {
|
||||
max_m_cost = strtoul(argv[2], &end, 10);
|
||||
if (end == argv[2]) {
|
||||
fprintf(stderr, "ERROR: Invalid number format!\n");
|
||||
return 1;
|
||||
}
|
||||
}
|
||||
|
||||
if (argc >= 4) {
|
||||
max_p = strtoul(argv[3], &end, 10);
|
||||
if (end == argv[3]) {
|
||||
fprintf(stderr, "ERROR: Invalid number format!\n");
|
||||
return 1;
|
||||
}
|
||||
}
|
||||
|
||||
argon2_select_impl(stderr, "[libargon2] ");
|
||||
|
||||
size_t memory_size = (size_t)max_m_cost * (size_t)ARGON2_BLOCK_SIZE;
|
||||
void *memory = malloc(memory_size);
|
||||
if (memory == NULL) {
|
||||
fprintf(stderr, "ERROR: Memory allocation failed!\n");
|
||||
return 1;
|
||||
}
|
||||
/* make sure the whole memory gets mapped to physical pages: */
|
||||
memset(memory, 0xAB, memory_size);
|
||||
|
||||
printf("%8s%16s%8s%16s%16s%16s\n", "t_cost", "m_cost", "threads",
|
||||
"Argon2d (ms)", "Argon2i (ms)", "Argon2id (ms)");
|
||||
for (t_cost = 1; t_cost <= max_t_cost; t_cost *= 2) {
|
||||
uint32_t min_m_cost = max_p * ARGON2_SYNC_POINTS * 2;
|
||||
for (m_cost = min_m_cost; m_cost <= max_m_cost; m_cost *= 2) {
|
||||
for (p = 1; p <= max_p; p *= 2) {
|
||||
res = benchmark(memory, memory_size, t_cost, m_cost, p);
|
||||
if (res != 0) {
|
||||
free(memory);
|
||||
return res;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
free(memory);
|
||||
return 0;
|
||||
}
|
90
src/3rdparty/argon2/src/genkat.c
vendored
Normal file
90
src/3rdparty/argon2/src/genkat.c
vendored
Normal file
|
@ -0,0 +1,90 @@
|
|||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
|
||||
#include "argon2.h"
|
||||
|
||||
static void fatal(const char *error) {
|
||||
fprintf(stderr, "Error: %s\n", error);
|
||||
exit(1);
|
||||
}
|
||||
|
||||
static void generate_testvectors(argon2_type type, const uint32_t version) {
|
||||
#define TEST_OUTLEN 32
|
||||
#define TEST_PWDLEN 32
|
||||
#define TEST_SALTLEN 16
|
||||
#define TEST_SECRETLEN 8
|
||||
#define TEST_ADLEN 12
|
||||
argon2_context context;
|
||||
|
||||
unsigned char out[TEST_OUTLEN];
|
||||
unsigned char pwd[TEST_PWDLEN];
|
||||
unsigned char salt[TEST_SALTLEN];
|
||||
unsigned char secret[TEST_SECRETLEN];
|
||||
unsigned char ad[TEST_ADLEN];
|
||||
const allocate_fptr myown_allocator = NULL;
|
||||
const deallocate_fptr myown_deallocator = NULL;
|
||||
|
||||
unsigned t_cost = 3;
|
||||
unsigned m_cost = 32;
|
||||
unsigned lanes = 4;
|
||||
|
||||
memset(pwd, 1, TEST_OUTLEN);
|
||||
memset(salt, 2, TEST_SALTLEN);
|
||||
memset(secret, 3, TEST_SECRETLEN);
|
||||
memset(ad, 4, TEST_ADLEN);
|
||||
|
||||
context.out = out;
|
||||
context.outlen = TEST_OUTLEN;
|
||||
context.version = version;
|
||||
context.pwd = pwd;
|
||||
context.pwdlen = TEST_PWDLEN;
|
||||
context.salt = salt;
|
||||
context.saltlen = TEST_SALTLEN;
|
||||
context.secret = secret;
|
||||
context.secretlen = TEST_SECRETLEN;
|
||||
context.ad = ad;
|
||||
context.adlen = TEST_ADLEN;
|
||||
context.t_cost = t_cost;
|
||||
context.m_cost = m_cost;
|
||||
context.lanes = lanes;
|
||||
context.threads = lanes;
|
||||
context.allocate_cbk = myown_allocator;
|
||||
context.free_cbk = myown_deallocator;
|
||||
context.flags = ARGON2_DEFAULT_FLAGS | ARGON2_FLAG_GENKAT;
|
||||
|
||||
#undef TEST_OUTLEN
|
||||
#undef TEST_PWDLEN
|
||||
#undef TEST_SALTLEN
|
||||
#undef TEST_SECRETLEN
|
||||
#undef TEST_ADLEN
|
||||
|
||||
argon2_ctx(&context, type);
|
||||
}
|
||||
|
||||
int main(int argc, char *argv[]) {
|
||||
/* Get and check Argon2 type */
|
||||
const char *type_str = (argc > 1) ? argv[1] : "i";
|
||||
argon2_type type = Argon2_i;
|
||||
uint32_t version = ARGON2_VERSION_NUMBER;
|
||||
if (!strcmp(type_str, "d")) {
|
||||
type = Argon2_d;
|
||||
} else if (!strcmp(type_str, "i")) {
|
||||
type = Argon2_i;
|
||||
} else if (!strcmp(type_str, "id")) {
|
||||
type = Argon2_id;
|
||||
} else {
|
||||
fatal("wrong Argon2 type");
|
||||
}
|
||||
|
||||
/* Get and check Argon2 version number */
|
||||
if(argc > 2) {
|
||||
version = strtoul(argv[2], NULL, 10);
|
||||
}
|
||||
if (ARGON2_VERSION_10 != version && ARGON2_VERSION_NUMBER != version) {
|
||||
fatal("wrong Argon2 version number");
|
||||
}
|
||||
|
||||
generate_testvectors(type, version);
|
||||
return ARGON2_OK;
|
||||
}
|
315
src/3rdparty/argon2/src/run.c
vendored
Normal file
315
src/3rdparty/argon2/src/run.c
vendored
Normal file
|
@ -0,0 +1,315 @@
|
|||
/*
|
||||
* Argon2 source code package
|
||||
*
|
||||
* Written by Daniel Dinu and Dmitry Khovratovich, 2015
|
||||
*
|
||||
* This work is licensed under a Creative Commons CC0 1.0 License/Waiver.
|
||||
*
|
||||
* You should have received a copy of the CC0 Public Domain Dedication along
|
||||
* with
|
||||
* this software. If not, see
|
||||
* <http://creativecommons.org/publicdomain/zero/1.0/>.
|
||||
*/
|
||||
|
||||
#define _GNU_SOURCE 1
|
||||
|
||||
#include <inttypes.h>
|
||||
#include <stdint.h>
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
#include <time.h>
|
||||
|
||||
#include "argon2.h"
|
||||
#include "core.h"
|
||||
|
||||
#define T_COST_DEF 3
|
||||
#define LOG_M_COST_DEF 12 /* 2^12 = 4 MiB */
|
||||
#define LANES_DEF 1
|
||||
#define THREADS_DEF 1
|
||||
#define OUTLEN_DEF 32
|
||||
#define MAX_PASS_LEN 128
|
||||
|
||||
#define UNUSED_PARAMETER(x) (void)(x)
|
||||
|
||||
static void usage(const char *cmd) {
|
||||
printf("Usage: %s [-h] salt [-i|-d|-id] [-t iterations] [-m memory] "
|
||||
"[-p parallelism] [-l hash length] [-e|-r] [-v (10|13)]\n",
|
||||
cmd);
|
||||
printf("\tPassword is read from stdin\n");
|
||||
printf("Parameters:\n");
|
||||
printf("\tsalt\t\tThe salt to use, at least 8 characters\n");
|
||||
printf("\t-i\t\tUse Argon2i (this is the default)\n");
|
||||
printf("\t-d\t\tUse Argon2d instead of Argon2i\n");
|
||||
printf("\t-id\t\tUse Argon2id instead of Argon2i\n");
|
||||
printf("\t-t N\t\tSets the number of iterations to N (default = %d)\n",
|
||||
T_COST_DEF);
|
||||
printf("\t-m N\t\tSets the memory usage of 2^N KiB (default %d)\n",
|
||||
LOG_M_COST_DEF);
|
||||
printf("\t-p N\t\tSets parallelism to N threads (default %d)\n",
|
||||
THREADS_DEF);
|
||||
printf("\t-l N\t\tSets hash output length to N bytes (default %d)\n",
|
||||
OUTLEN_DEF);
|
||||
printf("\t-e\t\tOutput only encoded hash\n");
|
||||
printf("\t-r\t\tOutput only the raw bytes of the hash\n");
|
||||
printf("\t-v (10|13)\tArgon2 version (defaults to the most recent version, "
|
||||
"currently %x)\n", ARGON2_VERSION_NUMBER);
|
||||
printf("\t-h\t\tPrint %s usage\n", cmd);
|
||||
}
|
||||
|
||||
static void fatal(const char *error) {
|
||||
fprintf(stderr, "Error: %s\n", error);
|
||||
exit(1);
|
||||
}
|
||||
|
||||
static void print_hex(uint8_t *bytes, size_t bytes_len) {
|
||||
size_t i;
|
||||
for (i = 0; i < bytes_len; ++i) {
|
||||
printf("%02x", bytes[i]);
|
||||
}
|
||||
printf("\n");
|
||||
}
|
||||
|
||||
/*
|
||||
Runs Argon2 with certain inputs and parameters, inputs not cleared. Prints the
|
||||
Base64-encoded hash string
|
||||
@out output array with at least 32 bytes allocated
|
||||
@pwd NULL-terminated string, presumably from argv[]
|
||||
@salt salt array
|
||||
@t_cost number of iterations
|
||||
@m_cost amount of requested memory in KB
|
||||
@lanes amount of requested parallelism
|
||||
@threads actual parallelism
|
||||
@type Argon2 type we want to run
|
||||
@encoded_only display only the encoded hash
|
||||
@raw_only display only the hexadecimal of the hash
|
||||
@version Argon2 version
|
||||
*/
|
||||
static void run(uint32_t outlen, char *pwd, char *salt, uint32_t t_cost,
|
||||
uint32_t m_cost, uint32_t lanes, uint32_t threads,
|
||||
argon2_type type, int encoded_only, int raw_only,
|
||||
uint32_t version) {
|
||||
clock_t start_time, stop_time;
|
||||
size_t pwdlen, saltlen, encodedlen;
|
||||
int result;
|
||||
unsigned char * out = NULL;
|
||||
char * encoded = NULL;
|
||||
|
||||
start_time = clock();
|
||||
|
||||
if (!pwd) {
|
||||
fatal("password missing");
|
||||
}
|
||||
|
||||
if (!salt) {
|
||||
clear_internal_memory(pwd, strlen(pwd));
|
||||
fatal("salt missing");
|
||||
}
|
||||
|
||||
pwdlen = strlen(pwd);
|
||||
saltlen = strlen(salt);
|
||||
if(UINT32_MAX < saltlen) {
|
||||
fatal("salt is too long");
|
||||
}
|
||||
|
||||
UNUSED_PARAMETER(lanes);
|
||||
|
||||
out = malloc(outlen + 1);
|
||||
if (!out) {
|
||||
clear_internal_memory(pwd, strlen(pwd));
|
||||
fatal("could not allocate memory for output");
|
||||
}
|
||||
|
||||
encodedlen = argon2_encodedlen(t_cost, m_cost, lanes, (uint32_t)saltlen, outlen, type);
|
||||
encoded = malloc(encodedlen + 1);
|
||||
if (!encoded) {
|
||||
clear_internal_memory(pwd, strlen(pwd));
|
||||
fatal("could not allocate memory for hash");
|
||||
}
|
||||
|
||||
result = argon2_hash(t_cost, m_cost, threads, pwd, pwdlen, salt, saltlen,
|
||||
out, outlen, encoded, encodedlen, type, version);
|
||||
if (result != ARGON2_OK)
|
||||
fatal(argon2_error_message(result));
|
||||
|
||||
stop_time = clock();
|
||||
|
||||
if (encoded_only)
|
||||
puts(encoded);
|
||||
|
||||
if (raw_only)
|
||||
print_hex(out, outlen);
|
||||
|
||||
if (encoded_only || raw_only) {
|
||||
free(out);
|
||||
free(encoded);
|
||||
return;
|
||||
}
|
||||
|
||||
printf("Hash:\t\t");
|
||||
print_hex(out, outlen);
|
||||
free(out);
|
||||
|
||||
printf("Encoded:\t%s\n", encoded);
|
||||
|
||||
printf("%2.3f seconds\n",
|
||||
((double)stop_time - start_time) / (CLOCKS_PER_SEC));
|
||||
|
||||
result = argon2_verify(encoded, pwd, pwdlen, type);
|
||||
if (result != ARGON2_OK)
|
||||
fatal(argon2_error_message(result));
|
||||
printf("Verification ok\n");
|
||||
free(encoded);
|
||||
}
|
||||
|
||||
int main(int argc, char *argv[]) {
|
||||
uint32_t outlen = OUTLEN_DEF;
|
||||
uint32_t m_cost = 1 << LOG_M_COST_DEF;
|
||||
uint32_t t_cost = T_COST_DEF;
|
||||
uint32_t lanes = LANES_DEF;
|
||||
uint32_t threads = THREADS_DEF;
|
||||
argon2_type type = Argon2_i; /* Argon2i is the default type */
|
||||
int types_specified = 0;
|
||||
int encoded_only = 0;
|
||||
int raw_only = 0;
|
||||
uint32_t version = ARGON2_VERSION_NUMBER;
|
||||
int i;
|
||||
size_t n;
|
||||
char pwd[MAX_PASS_LEN], *salt;
|
||||
|
||||
if (argc < 2) {
|
||||
usage(argv[0]);
|
||||
return ARGON2_MISSING_ARGS;
|
||||
} else if (argc >= 2 && strcmp(argv[1], "-h") == 0) {
|
||||
usage(argv[0]);
|
||||
return 1;
|
||||
}
|
||||
|
||||
argon2_select_impl(stderr, "[libargon2] ");
|
||||
|
||||
/* get password from stdin */
|
||||
n = fread(pwd, 1, sizeof pwd - 1, stdin);
|
||||
if(n < 1) {
|
||||
fatal("no password read");
|
||||
}
|
||||
if(n == MAX_PASS_LEN-1) {
|
||||
fatal("Provided password longer than supported in command line utility");
|
||||
}
|
||||
|
||||
pwd[n] = '\0';
|
||||
if (pwd[n - 1] == '\n') {
|
||||
pwd[n - 1] = '\0';
|
||||
}
|
||||
|
||||
salt = argv[1];
|
||||
|
||||
/* parse options */
|
||||
for (i = 2; i < argc; i++) {
|
||||
const char *a = argv[i];
|
||||
unsigned long input = 0;
|
||||
if (!strcmp(a, "-h")) {
|
||||
usage(argv[0]);
|
||||
return 1;
|
||||
} else if (!strcmp(a, "-m")) {
|
||||
if (i < argc - 1) {
|
||||
i++;
|
||||
input = strtoul(argv[i], NULL, 10);
|
||||
if (input == 0 || input == ULONG_MAX ||
|
||||
input > ARGON2_MAX_MEMORY_BITS) {
|
||||
fatal("bad numeric input for -m");
|
||||
}
|
||||
m_cost = ARGON2_MIN(UINT64_C(1) << input, UINT32_C(0xFFFFFFFF));
|
||||
if (m_cost > ARGON2_MAX_MEMORY) {
|
||||
fatal("m_cost overflow");
|
||||
}
|
||||
continue;
|
||||
} else {
|
||||
fatal("missing -m argument");
|
||||
}
|
||||
} else if (!strcmp(a, "-t")) {
|
||||
if (i < argc - 1) {
|
||||
i++;
|
||||
input = strtoul(argv[i], NULL, 10);
|
||||
if (input == 0 || input == ULONG_MAX ||
|
||||
input > ARGON2_MAX_TIME) {
|
||||
fatal("bad numeric input for -t");
|
||||
}
|
||||
t_cost = input;
|
||||
continue;
|
||||
} else {
|
||||
fatal("missing -t argument");
|
||||
}
|
||||
} else if (!strcmp(a, "-p")) {
|
||||
if (i < argc - 1) {
|
||||
i++;
|
||||
input = strtoul(argv[i], NULL, 10);
|
||||
if (input == 0 || input == ULONG_MAX ||
|
||||
input > ARGON2_MAX_THREADS || input > ARGON2_MAX_LANES) {
|
||||
fatal("bad numeric input for -p");
|
||||
}
|
||||
threads = input;
|
||||
lanes = threads;
|
||||
continue;
|
||||
} else {
|
||||
fatal("missing -p argument");
|
||||
}
|
||||
} else if (!strcmp(a, "-l")) {
|
||||
if (i < argc - 1) {
|
||||
i++;
|
||||
input = strtoul(argv[i], NULL, 10);
|
||||
outlen = input;
|
||||
continue;
|
||||
} else {
|
||||
fatal("missing -l argument");
|
||||
}
|
||||
} else if (!strcmp(a, "-i")) {
|
||||
type = Argon2_i;
|
||||
++types_specified;
|
||||
} else if (!strcmp(a, "-d")) {
|
||||
type = Argon2_d;
|
||||
++types_specified;
|
||||
} else if (!strcmp(a, "-id")) {
|
||||
type = Argon2_id;
|
||||
++types_specified;
|
||||
} else if (!strcmp(a, "-e")) {
|
||||
encoded_only = 1;
|
||||
} else if (!strcmp(a, "-r")) {
|
||||
raw_only = 1;
|
||||
} else if (!strcmp(a, "-v")) {
|
||||
if (i < argc - 1) {
|
||||
i++;
|
||||
if (!strcmp(argv[i], "10")) {
|
||||
version = ARGON2_VERSION_10;
|
||||
} else if (!strcmp(argv[i], "13")) {
|
||||
version = ARGON2_VERSION_13;
|
||||
} else {
|
||||
fatal("invalid Argon2 version");
|
||||
}
|
||||
} else {
|
||||
fatal("missing -v argument");
|
||||
}
|
||||
} else {
|
||||
fatal("unknown argument");
|
||||
}
|
||||
}
|
||||
|
||||
if (types_specified > 1) {
|
||||
fatal("cannot specify multiple Argon2 types");
|
||||
}
|
||||
|
||||
if(encoded_only && raw_only)
|
||||
fatal("cannot provide both -e and -r");
|
||||
|
||||
if(!encoded_only && !raw_only) {
|
||||
printf("Type:\t\t%s\n", argon2_type2string(type, 1));
|
||||
printf("Iterations:\t%" PRIu32 " \n", t_cost);
|
||||
printf("Memory:\t\t%" PRIu32 " KiB\n", m_cost);
|
||||
printf("Parallelism:\t%" PRIu32 " \n", lanes);
|
||||
}
|
||||
|
||||
run(outlen, pwd, salt, t_cost, m_cost, lanes, threads, type,
|
||||
encoded_only, raw_only, version);
|
||||
|
||||
return ARGON2_OK;
|
||||
}
|
||||
|
41
src/3rdparty/argon2/src/timing.h
vendored
Normal file
41
src/3rdparty/argon2/src/timing.h
vendored
Normal file
|
@ -0,0 +1,41 @@
|
|||
#include <stdlib.h>
|
||||
|
||||
#ifdef _POSIX_SOURCE
|
||||
#include <time.h>
|
||||
|
||||
struct timestamp {
|
||||
struct timespec time;
|
||||
};
|
||||
|
||||
static inline void timestamp_store(struct timestamp *out)
|
||||
{
|
||||
clock_gettime(CLOCK_MONOTONIC, &out->time);
|
||||
}
|
||||
|
||||
static inline double timestamp_span_ms(const struct timestamp *start,
|
||||
const struct timestamp *end)
|
||||
{
|
||||
double res = 0.0;
|
||||
res += (end->time.tv_sec - start->time.tv_sec) * 1000.0;
|
||||
res += (end->time.tv_nsec - start->time.tv_nsec) / 1000000.0;
|
||||
return res;
|
||||
}
|
||||
#else
|
||||
#include <time.h>
|
||||
|
||||
struct timestamp {
|
||||
clock_t time;
|
||||
};
|
||||
|
||||
static inline void timestamp_store(struct timestamp *out)
|
||||
{
|
||||
out->time = clock();
|
||||
}
|
||||
|
||||
static inline double timestamp_span_ms(const struct timestamp *start,
|
||||
const struct timestamp *end)
|
||||
{
|
||||
double res = (end->time - start->time) * 1000;
|
||||
return res / CLOCKS_PER_SEC;
|
||||
}
|
||||
#endif
|
239
src/3rdparty/argon2/tests/test.c
vendored
Normal file
239
src/3rdparty/argon2/tests/test.c
vendored
Normal file
|
@ -0,0 +1,239 @@
|
|||
#include <stdio.h>
|
||||
#include <stdint.h>
|
||||
#include <inttypes.h>
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
#include <time.h>
|
||||
#include <assert.h>
|
||||
|
||||
#include "argon2.h"
|
||||
|
||||
#define OUT_LEN 32
|
||||
#define ENCODED_LEN 108
|
||||
|
||||
/* Test harness will assert:
|
||||
* argon2_hash() returns ARGON2_OK
|
||||
* HEX output matches expected
|
||||
* encoded output matches expected
|
||||
* argon2_verify() correctly verifies value
|
||||
*/
|
||||
|
||||
void hashtest(uint32_t version, uint32_t t, uint32_t m, uint32_t p, char *pwd,
|
||||
char *salt, char *hexref, char *mcfref) {
|
||||
unsigned char out[OUT_LEN];
|
||||
unsigned char hex_out[OUT_LEN * 2 + 4];
|
||||
char encoded[ENCODED_LEN];
|
||||
int ret, i;
|
||||
|
||||
printf("Hash test: $v=%d t=%d, m=%d, p=%d, pass=%s, salt=%s: ", version,
|
||||
t, m, p, pwd, salt);
|
||||
|
||||
ret = argon2_hash(t, 1 << m, p, pwd, strlen(pwd), salt, strlen(salt), out,
|
||||
OUT_LEN, encoded, ENCODED_LEN, Argon2_i, version);
|
||||
assert(ret == ARGON2_OK);
|
||||
|
||||
for (i = 0; i < OUT_LEN; ++i)
|
||||
sprintf((char *)(hex_out + i * 2), "%02x", out[i]);
|
||||
|
||||
assert(memcmp(hex_out, hexref, OUT_LEN * 2) == 0);
|
||||
|
||||
if (ARGON2_VERSION_NUMBER == version) {
|
||||
assert(memcmp(encoded, mcfref, strlen(mcfref)) == 0);
|
||||
}
|
||||
|
||||
ret = argon2_verify(encoded, pwd, strlen(pwd), Argon2_i);
|
||||
assert(ret == ARGON2_OK);
|
||||
ret = argon2_verify(mcfref, pwd, strlen(pwd), Argon2_i);
|
||||
assert(ret == ARGON2_OK);
|
||||
|
||||
printf("PASS\n");
|
||||
}
|
||||
|
||||
int main() {
|
||||
int ret;
|
||||
unsigned char out[OUT_LEN];
|
||||
char const *msg;
|
||||
int version;
|
||||
|
||||
argon2_select_impl(stderr, "[libargon2] ");
|
||||
|
||||
version = ARGON2_VERSION_10;
|
||||
printf("Test Argon2i version number: %02x\n", version);
|
||||
|
||||
/* Multiple test cases for various input values */
|
||||
hashtest(version, 2, 16, 1, "password", "somesalt",
|
||||
"f6c4db4a54e2a370627aff3db6176b94a2a209a62c8e36152711802f7b30c694",
|
||||
"$argon2i$m=65536,t=2,p=1$c29tZXNhbHQ"
|
||||
"$9sTbSlTio3Biev89thdrlKKiCaYsjjYVJxGAL3swxpQ");
|
||||
#ifdef TEST_LARGE_RAM
|
||||
hashtest(version, 2, 20, 1, "password", "somesalt",
|
||||
"9690ec55d28d3ed32562f2e73ea62b02b018757643a2ae6e79528459de8106e9",
|
||||
"$argon2i$m=1048576,t=2,p=1$c29tZXNhbHQ"
|
||||
"$lpDsVdKNPtMlYvLnPqYrArAYdXZDoq5ueVKEWd6BBuk");
|
||||
#endif
|
||||
hashtest(version, 2, 18, 1, "password", "somesalt",
|
||||
"3e689aaa3d28a77cf2bc72a51ac53166761751182f1ee292e3f677a7da4c2467",
|
||||
"$argon2i$m=262144,t=2,p=1$c29tZXNhbHQ"
|
||||
"$Pmiaqj0op3zyvHKlGsUxZnYXURgvHuKS4/Z3p9pMJGc");
|
||||
hashtest(version, 2, 8, 1, "password", "somesalt",
|
||||
"fd4dd83d762c49bdeaf57c47bdcd0c2f1babf863fdeb490df63ede9975fccf06",
|
||||
"$argon2i$m=256,t=2,p=1$c29tZXNhbHQ"
|
||||
"$/U3YPXYsSb3q9XxHvc0MLxur+GP960kN9j7emXX8zwY");
|
||||
hashtest(version, 2, 8, 2, "password", "somesalt",
|
||||
"b6c11560a6a9d61eac706b79a2f97d68b4463aa3ad87e00c07e2b01e90c564fb",
|
||||
"$argon2i$m=256,t=2,p=2$c29tZXNhbHQ"
|
||||
"$tsEVYKap1h6scGt5ovl9aLRGOqOth+AMB+KwHpDFZPs");
|
||||
hashtest(version, 1, 16, 1, "password", "somesalt",
|
||||
"81630552b8f3b1f48cdb1992c4c678643d490b2b5eb4ff6c4b3438b5621724b2",
|
||||
"$argon2i$m=65536,t=1,p=1$c29tZXNhbHQ"
|
||||
"$gWMFUrjzsfSM2xmSxMZ4ZD1JCytetP9sSzQ4tWIXJLI");
|
||||
hashtest(version, 4, 16, 1, "password", "somesalt",
|
||||
"f212f01615e6eb5d74734dc3ef40ade2d51d052468d8c69440a3a1f2c1c2847b",
|
||||
"$argon2i$m=65536,t=4,p=1$c29tZXNhbHQ"
|
||||
"$8hLwFhXm6110c03D70Ct4tUdBSRo2MaUQKOh8sHChHs");
|
||||
hashtest(version, 2, 16, 1, "differentpassword", "somesalt",
|
||||
"e9c902074b6754531a3a0be519e5baf404b30ce69b3f01ac3bf21229960109a3",
|
||||
"$argon2i$m=65536,t=2,p=1$c29tZXNhbHQ"
|
||||
"$6ckCB0tnVFMaOgvlGeW69ASzDOabPwGsO/ISKZYBCaM");
|
||||
hashtest(version, 2, 16, 1, "password", "diffsalt",
|
||||
"79a103b90fe8aef8570cb31fc8b22259778916f8336b7bdac3892569d4f1c497",
|
||||
"$argon2i$m=65536,t=2,p=1$ZGlmZnNhbHQ"
|
||||
"$eaEDuQ/orvhXDLMfyLIiWXeJFvgza3vaw4kladTxxJc");
|
||||
|
||||
/* Error state tests */
|
||||
|
||||
/* Handle an invalid encoding correctly (it is missing a $) */
|
||||
ret = argon2_verify("$argon2i$m=65536,t=2,p=1c29tZXNhbHQ"
|
||||
"$9sTbSlTio3Biev89thdrlKKiCaYsjjYVJxGAL3swxpQ",
|
||||
"password", strlen("password"), Argon2_i);
|
||||
assert(ret == ARGON2_DECODING_FAIL);
|
||||
printf("Recognise an invalid encoding: PASS\n");
|
||||
|
||||
/* Handle an invalid encoding correctly (it is missing a $) */
|
||||
ret = argon2_verify("$argon2i$m=65536,t=2,p=1$c29tZXNhbHQ"
|
||||
"9sTbSlTio3Biev89thdrlKKiCaYsjjYVJxGAL3swxpQ",
|
||||
"password", strlen("password"), Argon2_i);
|
||||
assert(ret == ARGON2_DECODING_FAIL);
|
||||
printf("Recognise an invalid encoding: PASS\n");
|
||||
|
||||
/* Handle an invalid encoding correctly (salt is too short) */
|
||||
ret = argon2_verify("$argon2i$m=65536,t=2,p=1$"
|
||||
"$9sTbSlTio3Biev89thdrlKKiCaYsjjYVJxGAL3swxpQ",
|
||||
"password", strlen("password"), Argon2_i);
|
||||
assert(ret == ARGON2_SALT_TOO_SHORT);
|
||||
printf("Recognise an invalid salt in encoding: PASS\n");
|
||||
|
||||
/* Handle an mismatching hash (the encoded password is "passwore") */
|
||||
ret = argon2_verify("$argon2i$m=65536,t=2,p=1$c29tZXNhbHQ"
|
||||
"$b2G3seW+uPzerwQQC+/E1K50CLLO7YXy0JRcaTuswRo",
|
||||
"password", strlen("password"), Argon2_i);
|
||||
assert(ret == ARGON2_VERIFY_MISMATCH);
|
||||
printf("Verify with mismatched password: PASS\n");
|
||||
|
||||
msg = argon2_error_message(ARGON2_DECODING_FAIL);
|
||||
assert(strcmp(msg, "Decoding failed") == 0);
|
||||
printf("Decode an error message: PASS\n");
|
||||
|
||||
printf("\n");
|
||||
|
||||
version = ARGON2_VERSION_NUMBER;
|
||||
printf("Test Argon2i version number: %02x\n", version);
|
||||
|
||||
/* Multiple test cases for various input values */
|
||||
hashtest(version, 2, 16, 1, "password", "somesalt",
|
||||
"c1628832147d9720c5bd1cfd61367078729f6dfb6f8fea9ff98158e0d7816ed0",
|
||||
"$argon2i$v=19$m=65536,t=2,p=1$c29tZXNhbHQ"
|
||||
"$wWKIMhR9lyDFvRz9YTZweHKfbftvj+qf+YFY4NeBbtA");
|
||||
#ifdef TEST_LARGE_RAM
|
||||
hashtest(version, 2, 20, 1, "password", "somesalt",
|
||||
"d1587aca0922c3b5d6a83edab31bee3c4ebaef342ed6127a55d19b2351ad1f41",
|
||||
"$argon2i$v=19$m=1048576,t=2,p=1$c29tZXNhbHQ"
|
||||
"$0Vh6ygkiw7XWqD7asxvuPE667zQu1hJ6VdGbI1GtH0E");
|
||||
#endif
|
||||
hashtest(version, 2, 18, 1, "password", "somesalt",
|
||||
"296dbae80b807cdceaad44ae741b506f14db0959267b183b118f9b24229bc7cb",
|
||||
"$argon2i$v=19$m=262144,t=2,p=1$c29tZXNhbHQ"
|
||||
"$KW266AuAfNzqrUSudBtQbxTbCVkmexg7EY+bJCKbx8s");
|
||||
hashtest(version, 2, 8, 1, "password", "somesalt",
|
||||
"89e9029f4637b295beb027056a7336c414fadd43f6b208645281cb214a56452f",
|
||||
"$argon2i$v=19$m=256,t=2,p=1$c29tZXNhbHQ"
|
||||
"$iekCn0Y3spW+sCcFanM2xBT63UP2sghkUoHLIUpWRS8");
|
||||
hashtest(version, 2, 8, 2, "password", "somesalt",
|
||||
"4ff5ce2769a1d7f4c8a491df09d41a9fbe90e5eb02155a13e4c01e20cd4eab61",
|
||||
"$argon2i$v=19$m=256,t=2,p=2$c29tZXNhbHQ"
|
||||
"$T/XOJ2mh1/TIpJHfCdQan76Q5esCFVoT5MAeIM1Oq2E");
|
||||
hashtest(version, 1, 16, 1, "password", "somesalt",
|
||||
"d168075c4d985e13ebeae560cf8b94c3b5d8a16c51916b6f4ac2da3ac11bbecf",
|
||||
"$argon2i$v=19$m=65536,t=1,p=1$c29tZXNhbHQ"
|
||||
"$0WgHXE2YXhPr6uVgz4uUw7XYoWxRkWtvSsLaOsEbvs8");
|
||||
hashtest(version, 4, 16, 1, "password", "somesalt",
|
||||
"aaa953d58af3706ce3df1aefd4a64a84e31d7f54175231f1285259f88174ce5b",
|
||||
"$argon2i$v=19$m=65536,t=4,p=1$c29tZXNhbHQ"
|
||||
"$qqlT1YrzcGzj3xrv1KZKhOMdf1QXUjHxKFJZ+IF0zls");
|
||||
hashtest(version, 2, 16, 1, "differentpassword", "somesalt",
|
||||
"14ae8da01afea8700c2358dcef7c5358d9021282bd88663a4562f59fb74d22ee",
|
||||
"$argon2i$v=19$m=65536,t=2,p=1$c29tZXNhbHQ"
|
||||
"$FK6NoBr+qHAMI1jc73xTWNkCEoK9iGY6RWL1n7dNIu4");
|
||||
hashtest(version, 2, 16, 1, "password", "diffsalt",
|
||||
"b0357cccfbef91f3860b0dba447b2348cbefecadaf990abfe9cc40726c521271",
|
||||
"$argon2i$v=19$m=65536,t=2,p=1$ZGlmZnNhbHQ"
|
||||
"$sDV8zPvvkfOGCw26RHsjSMvv7K2vmQq/6cxAcmxSEnE");
|
||||
|
||||
/* Error state tests */
|
||||
|
||||
/* Handle an invalid encoding correctly (it is missing a $) */
|
||||
ret = argon2_verify("$argon2i$v=19$m=65536,t=2,p=1c29tZXNhbHQ"
|
||||
"$wWKIMhR9lyDFvRz9YTZweHKfbftvj+qf+YFY4NeBbtA",
|
||||
"password", strlen("password"), Argon2_i);
|
||||
assert(ret == ARGON2_DECODING_FAIL);
|
||||
printf("Recognise an invalid encoding: PASS\n");
|
||||
|
||||
/* Handle an invalid encoding correctly (it is missing a $) */
|
||||
ret = argon2_verify("$argon2i$v=19$m=65536,t=2,p=1$c29tZXNhbHQ"
|
||||
"wWKIMhR9lyDFvRz9YTZweHKfbftvj+qf+YFY4NeBbtA",
|
||||
"password", strlen("password"), Argon2_i);
|
||||
assert(ret == ARGON2_DECODING_FAIL);
|
||||
printf("Recognise an invalid encoding: PASS\n");
|
||||
|
||||
/* Handle an invalid encoding correctly (salt is too short) */
|
||||
ret = argon2_verify("$argon2i$v=19$m=65536,t=2,p=1$"
|
||||
"$9sTbSlTio3Biev89thdrlKKiCaYsjjYVJxGAL3swxpQ",
|
||||
"password", strlen("password"), Argon2_i);
|
||||
assert(ret == ARGON2_SALT_TOO_SHORT);
|
||||
printf("Recognise an invalid salt in encoding: PASS\n");
|
||||
|
||||
/* Handle an mismatching hash (the encoded password is "passwore") */
|
||||
ret = argon2_verify("$argon2i$v=19$m=65536,t=2,p=1$c29tZXNhbHQ"
|
||||
"$8iIuixkI73Js3G1uMbezQXD0b8LG4SXGsOwoQkdAQIM",
|
||||
"password", strlen("password"), Argon2_i);
|
||||
assert(ret == ARGON2_VERIFY_MISMATCH);
|
||||
printf("Verify with mismatched password: PASS\n");
|
||||
|
||||
msg = argon2_error_message(ARGON2_DECODING_FAIL);
|
||||
assert(strcmp(msg, "Decoding failed") == 0);
|
||||
printf("Decode an error message: PASS\n");
|
||||
|
||||
/* Common error state tests */
|
||||
|
||||
printf("\n");
|
||||
printf("Common error state tests\n");
|
||||
|
||||
ret = argon2_hash(2, 1, 1, "password", strlen("password"),
|
||||
"diffsalt", strlen("diffsalt"),
|
||||
out, OUT_LEN, NULL, 0, Argon2_i, version);
|
||||
assert(ret == ARGON2_MEMORY_TOO_LITTLE);
|
||||
printf("Fail on invalid memory: PASS\n");
|
||||
|
||||
ret = argon2_hash(2, 1 << 12, 1, NULL, strlen("password"),
|
||||
"diffsalt", strlen("diffsalt"),
|
||||
out, OUT_LEN, NULL, 0, Argon2_i, version);
|
||||
assert(ret == ARGON2_PWD_PTR_MISMATCH);
|
||||
printf("Fail on invalid null pointer: PASS\n");
|
||||
|
||||
ret = argon2_hash(2, 1 << 12, 1, "password", strlen("password"), "s", 1,
|
||||
out, OUT_LEN, NULL, 0, Argon2_i, version);
|
||||
assert(ret == ARGON2_SALT_TOO_SHORT);
|
||||
printf("Fail on salt too short: PASS\n");
|
||||
|
||||
return 0;
|
||||
}
|
|
@ -92,6 +92,10 @@ static AlgoData const algorithms[] = {
|
|||
{ "cryptonight_turtle", "cn_turtle", xmrig::CRYPTONIGHT_PICO, xmrig::VARIANT_TRTL },
|
||||
# endif
|
||||
|
||||
# ifndef XMRIG_NO_ARGON2
|
||||
{ "chukwa", "trtl-chukwa", xmrig::ARGON2, xmrig::VARIANT_CHUKWA },
|
||||
# endif
|
||||
|
||||
# ifndef XMRIG_NO_CN_GPU
|
||||
{ "cryptonight/gpu", "cn/gpu", xmrig::CRYPTONIGHT, xmrig::VARIANT_GPU },
|
||||
# endif
|
||||
|
@ -138,7 +142,8 @@ static const char *variants[] = {
|
|||
"r",
|
||||
"rwz",
|
||||
"zls",
|
||||
"double"
|
||||
"double",
|
||||
"chukwa"
|
||||
};
|
||||
|
||||
|
||||
|
|
|
@ -36,6 +36,7 @@ enum Algo {
|
|||
CRYPTONIGHT_LITE, /* CryptoNight (1 MB) */
|
||||
CRYPTONIGHT_HEAVY, /* CryptoNight (4 MB) */
|
||||
CRYPTONIGHT_PICO, /* CryptoNight (256 KB) */
|
||||
ARGON2, /* Argon2 */
|
||||
ALGO_MAX
|
||||
};
|
||||
|
||||
|
@ -79,7 +80,8 @@ enum Variant {
|
|||
VARIANT_RWZ = 14, // CryptoNight variant 2 with 3/4 iterations and reversed shuffle operation (Graft)
|
||||
VARIANT_ZLS = 15, // CryptoNight variant 2 with 3/4 iterations (Zelerius)
|
||||
VARIANT_DOUBLE = 16, // CryptoNight variant 2 with double iterations (X-CASH)
|
||||
VARIANT_MAX
|
||||
VARIANT_CHUKWA = 17, // Argon2 Chukwa for TurtleCoin
|
||||
VARIANT_MAX
|
||||
};
|
||||
|
||||
|
||||
|
|
|
@ -34,6 +34,7 @@
|
|||
#include "core/ConfigCreator.h"
|
||||
#include "crypto/Asm.h"
|
||||
#include "crypto/CryptoNight_constants.h"
|
||||
#include "crypto/Argon2_constants.h"
|
||||
#include "rapidjson/document.h"
|
||||
#include "rapidjson/filewritestream.h"
|
||||
#include "rapidjson/prettywriter.h"
|
||||
|
@ -163,7 +164,16 @@ bool xmrig::Config::finalize()
|
|||
const AlgoVariant av = getAlgoVariant();
|
||||
m_threads.mode = m_threads.count ? Simple : Automatic;
|
||||
|
||||
const size_t size = CpuThread::multiway(av) * cn_select_memory(m_algorithm.algo()) / 1024;
|
||||
size_t size;
|
||||
|
||||
if (m_algorithm.algo() == xmrig::ARGON2)
|
||||
{
|
||||
size = CpuThread::multiway(av) * argon2_select_memory(m_algorithm.variant());
|
||||
}
|
||||
else
|
||||
{
|
||||
size = CpuThread::multiway(av) * cn_select_memory(m_algorithm.algo()) / 1024;
|
||||
}
|
||||
|
||||
if (!m_threads.count) {
|
||||
m_threads.count = Cpu::info()->optimalThreadsCount(size, m_maxCpuUsage);
|
||||
|
|
45
src/crypto/Argon2.h
Normal file
45
src/crypto/Argon2.h
Normal file
|
@ -0,0 +1,45 @@
|
|||
#ifndef XMRIG_ARGON2_H
|
||||
#define XMRIG_ARGON2_H
|
||||
|
||||
#include <argon2.h>
|
||||
|
||||
#include "crypto/Argon2_constants.h"
|
||||
|
||||
static bool argon_optimization_selected = false;
|
||||
|
||||
template<xmrig::Variant VARIANT>
|
||||
inline void argon2_hash_function(const uint8_t *__restrict__ input, size_t size, uint8_t *__restrict__ output, cryptonight_ctx **__restrict__ ctx, uint64_t height)
|
||||
{
|
||||
/* If this is the first time we've called this hash function then
|
||||
we need to have the Argon2 library check to see if any of the
|
||||
available CPU instruction sets are going to help us out */
|
||||
if (!argon_optimization_selected)
|
||||
{
|
||||
/* Call the library quick benchmark test to set which CPU
|
||||
instruction sets will be used */
|
||||
argon2_select_impl(NULL, NULL);
|
||||
|
||||
argon_optimization_selected = true;
|
||||
}
|
||||
|
||||
uint8_t salt[xmrig::ARGON2_SALTLEN];
|
||||
|
||||
memcpy(salt, input, sizeof(salt));
|
||||
|
||||
const uint32_t ITERS = xmrig::argon2_select_iters(VARIANT);
|
||||
const uint32_t MEMORY = xmrig::argon2_select_memory(VARIANT);
|
||||
const uint32_t PARALLELISM = xmrig::argon2_select_parallelism(VARIANT);
|
||||
const int ALGO = xmrig::argon2_select_algo(VARIANT);
|
||||
|
||||
switch (ALGO)
|
||||
{
|
||||
case xmrig::Argon2Algo::I:
|
||||
argon2i_hash_raw(ITERS, MEMORY, PARALLELISM, input, size, salt, xmrig::ARGON2_SALTLEN, output, xmrig::ARGON2_HASHLEN);
|
||||
case xmrig::Argon2Algo::D:
|
||||
argon2d_hash_raw(ITERS, MEMORY, PARALLELISM, input, size, salt, xmrig::ARGON2_SALTLEN, output, xmrig::ARGON2_HASHLEN);
|
||||
case xmrig::Argon2Algo::ID:
|
||||
argon2id_hash_raw(ITERS, MEMORY, PARALLELISM, input, size, salt, xmrig::ARGON2_SALTLEN, output, xmrig::ARGON2_HASHLEN);
|
||||
}
|
||||
}
|
||||
|
||||
#endif
|
72
src/crypto/Argon2_constants.h
Normal file
72
src/crypto/Argon2_constants.h
Normal file
|
@ -0,0 +1,72 @@
|
|||
#ifndef XMRIG_ARGON2_CONSTANTS_H
|
||||
#define XMRIG_ARGON2_CONSTANTS_H
|
||||
|
||||
|
||||
#include <stddef.h>
|
||||
#include <stdint.h>
|
||||
|
||||
|
||||
#include "common/xmrig.h"
|
||||
|
||||
namespace xmrig
|
||||
{
|
||||
enum Argon2Algo {
|
||||
I = 0,
|
||||
D = 1,
|
||||
ID = 2
|
||||
};
|
||||
|
||||
constexpr const size_t ARGON2_SALTLEN = 16;
|
||||
constexpr const size_t ARGON2_HASHLEN = 32;
|
||||
|
||||
constexpr const size_t ARGON2_MEMORY_CHUKWA = 512;
|
||||
constexpr const size_t ARGON2_ITERS_CHUKWA = 3;
|
||||
constexpr const size_t ARGON2_PARALLELISM_CHUKWA = 1;
|
||||
constexpr const int ARGON2_ALGO_CHUKWA = Argon2Algo::ID;
|
||||
|
||||
inline int argon2_select_algo(Variant variant)
|
||||
{
|
||||
switch (variant)
|
||||
{
|
||||
case VARIANT_CHUKWA:
|
||||
return ARGON2_ALGO_CHUKWA;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
inline uint32_t argon2_select_memory(Variant variant)
|
||||
{
|
||||
switch (variant)
|
||||
{
|
||||
case VARIANT_CHUKWA:
|
||||
return ARGON2_MEMORY_CHUKWA;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
inline uint32_t argon2_select_iters(Variant variant)
|
||||
{
|
||||
switch (variant)
|
||||
{
|
||||
case VARIANT_CHUKWA:
|
||||
return ARGON2_ITERS_CHUKWA;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
inline uint32_t argon2_select_parallelism(Variant variant)
|
||||
{
|
||||
switch (variant)
|
||||
{
|
||||
case VARIANT_CHUKWA:
|
||||
return ARGON2_PARALLELISM_CHUKWA;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
|
||||
#endif
|
0
src/crypto/Argon2_test.h
Normal file
0
src/crypto/Argon2_test.h
Normal file
|
@ -39,6 +39,9 @@
|
|||
# include "crypto/CryptoNight_x86.h"
|
||||
#endif
|
||||
|
||||
#ifndef XMRIG_NO_ARGON2
|
||||
# include "crypto/Argon2.h"
|
||||
#endif
|
||||
|
||||
xmrig::CpuThread::CpuThread(size_t index, Algo algorithm, AlgoVariant av, Multiway multiway, int64_t affinity, int priority, bool softAES, bool prefetch, Assembly assembly) :
|
||||
m_algorithm(algorithm),
|
||||
|
@ -389,6 +392,8 @@ xmrig::CpuThread::cn_hash_fun xmrig::CpuThread::fn(Algo algorithm, AlgoVariant a
|
|||
cryptonight_triple_hash<CRYPTONIGHT, true, VARIANT_DOUBLE>,
|
||||
cryptonight_quad_hash<CRYPTONIGHT, true, VARIANT_DOUBLE>,
|
||||
cryptonight_penta_hash<CRYPTONIGHT, true, VARIANT_DOUBLE>,
|
||||
|
||||
nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, // VARIANT_CHUKWA
|
||||
|
||||
# ifndef XMRIG_NO_AEON
|
||||
cryptonight_single_hash<CRYPTONIGHT_LITE, false, VARIANT_0>,
|
||||
|
@ -428,6 +433,7 @@ xmrig::CpuThread::cn_hash_fun xmrig::CpuThread::fn(Algo algorithm, AlgoVariant a
|
|||
nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, // VARIANT_RWZ
|
||||
nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, // VARIANT_ZLS
|
||||
nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, // VARIANT_DOUBLE
|
||||
nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, // VARIANT_CHUKWA
|
||||
# else
|
||||
nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, // VARIANT_0
|
||||
nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, // VARIANT_1
|
||||
|
@ -446,6 +452,7 @@ xmrig::CpuThread::cn_hash_fun xmrig::CpuThread::fn(Algo algorithm, AlgoVariant a
|
|||
nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, // VARIANT_RWZ
|
||||
nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, // VARIANT_ZLS
|
||||
nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, // VARIANT_DOUBLE
|
||||
nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, // VARIANT_CHUKWA
|
||||
# endif
|
||||
|
||||
# ifndef XMRIG_NO_SUMO
|
||||
|
@ -498,6 +505,7 @@ xmrig::CpuThread::cn_hash_fun xmrig::CpuThread::fn(Algo algorithm, AlgoVariant a
|
|||
nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, // VARIANT_RWZ
|
||||
nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, // VARIANT_ZLS
|
||||
nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, // VARIANT_DOUBLE
|
||||
nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, // VARIANT_CHUKWA
|
||||
# else
|
||||
nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, // VARIANT_0
|
||||
nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, // VARIANT_1
|
||||
|
@ -516,6 +524,7 @@ xmrig::CpuThread::cn_hash_fun xmrig::CpuThread::fn(Algo algorithm, AlgoVariant a
|
|||
nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, // VARIANT_RWZ
|
||||
nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, // VARIANT_ZLS
|
||||
nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, // VARIANT_DOUBLE
|
||||
nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, // VARIANT_CHUKWA
|
||||
# endif
|
||||
|
||||
# ifndef XMRIG_NO_CN_PICO
|
||||
|
@ -547,6 +556,7 @@ xmrig::CpuThread::cn_hash_fun xmrig::CpuThread::fn(Algo algorithm, AlgoVariant a
|
|||
nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, // VARIANT_RWZ
|
||||
nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, // VARIANT_ZLS
|
||||
nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, // VARIANT_DOUBLE
|
||||
nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, // VARIANT_CHUKWA
|
||||
# else
|
||||
nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, // VARIANT_0
|
||||
nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, // VARIANT_1
|
||||
|
@ -565,6 +575,57 @@ xmrig::CpuThread::cn_hash_fun xmrig::CpuThread::fn(Algo algorithm, AlgoVariant a
|
|||
nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, // VARIANT_RWZ
|
||||
nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, // VARIANT_ZLS
|
||||
nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, // VARIANT_DOUBLE
|
||||
nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, // VARIANT_CHUKWA
|
||||
# endif
|
||||
|
||||
# ifndef XMRIG_NO_ARGON2
|
||||
nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, // VARIANT_0
|
||||
nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, // VARIANT_1
|
||||
nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, // VARIANT_TUBE
|
||||
nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, // VARIANT_XTL
|
||||
nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, // VARIANT_MSR
|
||||
nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, // VARIANT_XHV
|
||||
nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, // VARIANT_XAO
|
||||
nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, // VARIANT_RTO
|
||||
nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, // VARIANT_2
|
||||
nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, // VARIANT_HALF
|
||||
nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, // VARIANT_TRTL
|
||||
nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, // VARIANT_GPU
|
||||
nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, // VARIANT_WOW
|
||||
nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, // VARIANT_4
|
||||
nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, // VARIANT_RWZ
|
||||
nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, // VARIANT_ZLS
|
||||
nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, // VARIANT_DOUBLE
|
||||
|
||||
argon2_hash_function<VARIANT_CHUKWA>,
|
||||
argon2_hash_function<VARIANT_CHUKWA>,
|
||||
argon2_hash_function<VARIANT_CHUKWA>,
|
||||
argon2_hash_function<VARIANT_CHUKWA>,
|
||||
argon2_hash_function<VARIANT_CHUKWA>,
|
||||
argon2_hash_function<VARIANT_CHUKWA>,
|
||||
argon2_hash_function<VARIANT_CHUKWA>,
|
||||
argon2_hash_function<VARIANT_CHUKWA>,
|
||||
argon2_hash_function<VARIANT_CHUKWA>,
|
||||
argon2_hash_function<VARIANT_CHUKWA>,
|
||||
# else
|
||||
nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, // VARIANT_0
|
||||
nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, // VARIANT_1
|
||||
nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, // VARIANT_TUBE
|
||||
nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, // VARIANT_XTL
|
||||
nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, // VARIANT_MSR
|
||||
nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, // VARIANT_XHV
|
||||
nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, // VARIANT_XAO
|
||||
nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, // VARIANT_RTO
|
||||
nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, // VARIANT_2
|
||||
nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, // VARIANT_HALF
|
||||
nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, // VARIANT_TRTL
|
||||
nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, // VARIANT_GPU
|
||||
nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, // VARIANT_WOW
|
||||
nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, // VARIANT_4
|
||||
nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, // VARIANT_RWZ
|
||||
nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, // VARIANT_ZLS
|
||||
nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, // VARIANT_DOUBLE
|
||||
nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, // VARIANT_CHUKWA
|
||||
# endif
|
||||
};
|
||||
|
||||
|
|
|
@ -101,6 +101,13 @@ bool MultiWorker<N>::selfTest()
|
|||
}
|
||||
# endif
|
||||
|
||||
# ifndef XMRIG_NO_ARGON2
|
||||
if (m_thread->algorithm() == ARGON2) {
|
||||
return true;
|
||||
// return verify(VARIANT_CHUKWA, test_output_pico_trtl);
|
||||
}
|
||||
# endif
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue