Conversion to NinjaRig.

This commit is contained in:
Haifa Bogdan Adnan 2019-08-26 12:38:34 +03:00
parent 84f56f0a4e
commit 2845347881
280 changed files with 18971 additions and 32469 deletions

View file

@ -1,23 +1,26 @@
cmake_minimum_required(VERSION 2.8)
project(xmrig)
project(ninjarig)
option(WITH_LIBCPUID "Use Libcpuid" ON)
option(WITH_AEON "CryptoNight-Lite support" ON)
option(WITH_SUMO "CryptoNight-Heavy support" ON)
option(WITH_CN_PICO "CryptoNight-Pico support" ON)
option(WITH_CN_GPU "CryptoNight-GPU support" ON)
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)
option(WITH_CUDA "Enable CUDA support" ON)
option(WITH_OPENCL "Enable OpenCL support" ON)
include (CheckIncludeFile)
include (cmake/cpu.cmake)
include (cmake/TargetArch.cmake)
target_architecture (ARCH)
MESSAGE( STATUS "Target architecture is: " ${ARCH} )
SET(CMAKE_SKIP_BUILD_RPATH FALSE)
SET(CMAKE_BUILD_WITH_INSTALL_RPATH TRUE)
SET(CMAKE_INSTALL_RPATH "./")
SET(CMAKE_INSTALL_RPATH_USE_LINK_PATH TRUE)
set (CMAKE_MACOSX_RPATH 0)
set(HEADERS
src/api/NetworkState.h
@ -70,46 +73,24 @@ set(HEADERS
src/core/ConfigLoader_default.h
src/core/Controller.h
src/interfaces/IJobResultListener.h
src/interfaces/IThread.h
src/interfaces/IWorker.h
src/Mem.h
src/net/JobResult.h
src/net/Network.h
src/net/strategies/DonateStrategy.h
src/net/strategies/Http.h
src/Summary.h
src/version.h
src/workers/CpuThread.h
src/core/HasherConfig.h
src/workers/Handle.h
src/workers/Hashrate.h
src/workers/MultiWorker.h
src/workers/Worker.h
src/workers/Workers.h
)
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
src/crypto/c_skein.h
src/crypto/CryptoNight.h
src/crypto/CryptoNight_constants.h
src/crypto/CryptoNight_monero.h
src/crypto/CryptoNight_test.h
src/crypto/groestl_tables.h
src/crypto/hash.h
src/crypto/skein_port.h
src/crypto/soft_aes.h
src/crypto/asm/CryptonightR_template.h
)
if (XMRIG_ARM)
set(HEADERS_CRYPTO "${HEADERS_CRYPTO}" src/crypto/CryptoNight_arm.h)
else()
set(HEADERS_CRYPTO "${HEADERS_CRYPTO}" src/crypto/CryptoNight_x86.h)
endif()
set(SOURCES
src/api/NetworkState.cpp
src/App.cpp
@ -141,33 +122,71 @@ set(SOURCES
src/common/Platform.cpp
src/core/Config.cpp
src/core/Controller.cpp
src/Mem.cpp
src/net/Network.cpp
src/net/strategies/DonateStrategy.cpp
src/net/strategies/Http.cpp
src/net/strategies/http_parser/http_parser.c
src/Summary.cpp
src/workers/CpuThread.cpp
src/workers/Handle.cpp
src/workers/Hashrate.cpp
src/workers/MultiWorker.cpp
src/workers/Worker.cpp
src/workers/Workers.cpp
src/xmrig.cpp
)
set(SOURCES_CRYPTO
src/crypto/c_groestl.c
src/crypto/c_blake256.c
src/crypto/c_jh.c
src/crypto/c_skein.c
set(HEADERS_COMMON
src/crypto/argon2_hasher/common/common.h
src/crypto/argon2_hasher/common/DLLExport.h
src/crypto/argon2_hasher/common/DLLImport.h
src/crypto/argon2_hasher/crypt/base64.h
src/crypto/argon2_hasher/crypt/hex.h
src/crypto/argon2_hasher/crypt/random_generator.h
src/crypto/argon2_hasher/crypt/sha512.h
src/crypto/argon2_hasher/hash/argon2/blake2/blake2.h
src/crypto/argon2_hasher/hash/argon2/blake2/blake2-config.h
src/crypto/argon2_hasher/hash/argon2/blake2/blake2-impl.h
src/crypto/argon2_hasher/hash/argon2/blake2/blake2b-load-sse2.h
src/crypto/argon2_hasher/hash/argon2/blake2/blake2b-load-sse41.h
src/crypto/argon2_hasher/hash/argon2/blake2/blake2b-round.h
src/crypto/argon2_hasher/hash/argon2/Argon2.h
src/crypto/argon2_hasher/hash/argon2/Defs.h
src/crypto/argon2_hasher/hash/Hasher.h
)
set(SOURCES_COMMON
src/crypto/argon2_hasher/common/common.cpp
src/crypto/argon2_hasher/crypt/base64.cpp
src/crypto/argon2_hasher/crypt/hex.cpp
src/crypto/argon2_hasher/crypt/random_generator.cpp
src/crypto/argon2_hasher/crypt/sha512.cpp
src/crypto/argon2_hasher/hash/argon2/blake2/blake2b.c
src/crypto/argon2_hasher/hash/argon2/Argon2.cpp
src/crypto/argon2_hasher/hash/argon2/argon2profile_4_1_256.c
src/crypto/argon2_hasher/hash/argon2/argon2profile_3_1_512.c
src/crypto/argon2_hasher/hash/Hasher.cpp
src/core/HasherConfig.cpp)
set(SOURCE_CPU_HASHER src/crypto/argon2_hasher/hash/cpu/CpuHasher.cpp src/crypto/argon2_hasher/hash/cpu/CpuHasher.h)
set(SOURCE_OPENCL_HASHER src/crypto/argon2_hasher/hash/gpu/opencl/OpenCLHasher.cpp src/crypto/argon2_hasher/hash/gpu/opencl/OpenCLHasher.h
src/crypto/argon2_hasher/hash/gpu/opencl/OpenCLKernel.cpp src/crypto/argon2_hasher/hash/gpu/opencl/OpenCLKernel.h)
set(SOURCE_CUDA_HASHER src/crypto/argon2_hasher/hash/gpu/cuda/cuda_hasher.cpp src/crypto/argon2_hasher/hash/gpu/cuda/cuda_hasher.h
src/crypto/argon2_hasher/hash/gpu/cuda/cuda_kernel.cu)
set(ARGON2_FILL_BLOCKS_SRC
src/crypto/argon2_hasher/hash/cpu/argon2_opt/implementation.c
src/crypto/argon2_hasher/hash/cpu/argon2_opt/blamka-round-opt.h
src/crypto/argon2_hasher/hash/cpu/argon2_opt/blamka-round-ref.h
src/crypto/argon2_hasher/hash/argon2/Defs.h
src/crypto/argon2_hasher/hash/argon2/blake2/blake2-impl.h)
if (WIN32)
set(SOURCES_OS
res/app.rc
src/App_win.cpp
src/base/io/Json_win.cpp
src/common/Platform_win.cpp
src/Mem_win.cpp
)
add_definitions(/DWIN32)
@ -177,14 +196,12 @@ elseif (APPLE)
src/App_unix.cpp
src/base/io/Json_unix.cpp
src/common/Platform_mac.cpp
src/Mem_unix.cpp
)
else()
set(SOURCES_OS
src/App_unix.cpp
src/base/io/Json_unix.cpp
src/common/Platform_unix.cpp
src/Mem_unix.cpp
)
if (CMAKE_SYSTEM_NAME STREQUAL FreeBSD)
@ -228,8 +245,6 @@ else()
endif()
include(cmake/OpenSSL.cmake)
include(cmake/asm.cmake)
include(cmake/cn-gpu.cmake)
CHECK_INCLUDE_FILE (syslog.h HAVE_SYSLOG_H)
if (HAVE_SYSLOG_H)
@ -237,22 +252,6 @@ if (HAVE_SYSLOG_H)
set(SOURCES_SYSLOG src/common/log/SysLog.h src/common/log/SysLog.cpp)
endif()
if (NOT WITH_AEON)
add_definitions(/DXMRIG_NO_AEON)
endif()
if (NOT WITH_SUMO)
add_definitions(/DXMRIG_NO_SUMO)
endif()
if (NOT WITH_IPBC)
add_definitions(/DXMRIG_NO_IPBC)
endif()
if (NOT WITH_CN_PICO)
add_definitions(/DXMRIG_NO_CN_PICO)
endif()
if (WITH_EMBEDDED_CONFIG)
add_definitions(/DXMRIG_FEATURE_EMBEDDED_CONFIG)
endif()
@ -284,26 +283,118 @@ 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})
include_directories(src/crypto/argon2_hasher/hash/cpu/cpu_features/include)
if (BUILD_STATIC)
set(CMAKE_EXE_LINKER_FLAGS " -static")
endif()
add_subdirectory(src/crypto/argon2_hasher/hash/cpu/cpu_features)
set_property(TARGET cpu_features PROPERTY POSITION_INDEPENDENT_CODE ON)
if (WITH_DEBUG_LOG)
add_definitions(/DAPP_DEBUG)
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} ${ARGON2_LIBRARY})
add_library(argon2_common SHARED ${HEADERS_COMMON} ${SOURCES_COMMON})
target_link_libraries(argon2_common ${CMAKE_DL_LIBS})
add_executable(${CMAKE_PROJECT_NAME} ${HEADERS} ${SOURCES} ${SOURCES_OS} ${SOURCES_CPUID} ${HEADERS_CRYPTO} ${SOURCES_SYSLOG} ${HTTPD_SOURCES} ${TLS_SOURCES})
target_link_libraries(${CMAKE_PROJECT_NAME} ${OPENSSL_LIBRARIES} ${UV_LIBRARIES} ${MHD_LIBRARY} ${EXTRA_LIBS} ${CPUID_LIB} argon2_common)
add_library(cpu_hasher MODULE ${SOURCE_CPU_HASHER})
set_target_properties(cpu_hasher
PROPERTIES
PREFIX ""
SUFFIX ".hsh"
LIBRARY_OUTPUT_DIRECTORY modules
)
target_link_libraries(cpu_hasher argon2_common cpu_features)
add_dependencies(${CMAKE_PROJECT_NAME} cpu_hasher)
add_library(argon2_fill_blocks_REF MODULE ${ARGON2_FILL_BLOCKS_SRC})
set_target_properties(argon2_fill_blocks_REF
PROPERTIES
PREFIX ""
SUFFIX ".opt"
LIBRARY_OUTPUT_DIRECTORY modules
)
target_compile_definitions(argon2_fill_blocks_REF PRIVATE BUILD_REF=1)
add_dependencies(cpu_hasher argon2_fill_blocks_REF)
if(ARCH STREQUAL "x86_64")
add_library(argon2_fill_blocks_SSE2 MODULE ${ARGON2_FILL_BLOCKS_SRC})
add_library(argon2_fill_blocks_SSSE3 MODULE ${ARGON2_FILL_BLOCKS_SRC})
add_library(argon2_fill_blocks_AVX MODULE ${ARGON2_FILL_BLOCKS_SRC})
add_library(argon2_fill_blocks_AVX2 MODULE ${ARGON2_FILL_BLOCKS_SRC})
add_library(argon2_fill_blocks_AVX512F MODULE ${ARGON2_FILL_BLOCKS_SRC})
set_target_properties(argon2_fill_blocks_SSE2 argon2_fill_blocks_SSSE3 argon2_fill_blocks_AVX argon2_fill_blocks_AVX2 argon2_fill_blocks_AVX512F
PROPERTIES
PREFIX ""
SUFFIX ".opt"
LIBRARY_OUTPUT_DIRECTORY modules
)
target_compile_options(argon2_fill_blocks_SSE2 PRIVATE -msse2)
target_compile_options(argon2_fill_blocks_SSSE3 PRIVATE -mssse3)
target_compile_options(argon2_fill_blocks_AVX PRIVATE -mavx)
target_compile_options(argon2_fill_blocks_AVX2 PRIVATE -mavx2)
target_compile_options(argon2_fill_blocks_AVX512F PRIVATE -mavx512f)
add_dependencies(cpu_hasher argon2_fill_blocks_SSE2 argon2_fill_blocks_SSSE3 argon2_fill_blocks_AVX argon2_fill_blocks_AVX2 argon2_fill_blocks_AVX512F)
endif()
if(ARCH STREQUAL "arm" OR ARCH STREQUAL "aarch64")
add_library(argon2_fill_blocks_NEON MODULE ${ARGON2_FILL_BLOCKS_SRC})
set_target_properties(argon2_fill_blocks_NEON
PROPERTIES
PREFIX ""
SUFFIX ".opt"
LIBRARY_OUTPUT_DIRECTORY modules
)
target_compile_options(common PRIVATE -D__NEON__)
if(ARCH STREQUAL "arm")
target_compile_options(argon2_fill_blocks_NEON PRIVATE -D__NEON__ -mfpu=neon -funsafe-math-optimizations)
else()
target_compile_options(argon2_fill_blocks_NEON PRIVATE -D__NEON__)
endif(ARCH STREQUAL "arm")
add_dependencies(cpu_hasher argon2_fill_blocks_NEON)
endif(ARCH STREQUAL "arm" OR ARCH STREQUAL "aarch64")
if(WITH_OPENCL)
add_definitions(-DWITH_OPENCL)
find_package(OpenCL REQUIRED)
include_directories(${OpenCL_INCLUDE_DIR})
add_library(opencl_hasher MODULE ${SOURCE_OPENCL_HASHER})
set_target_properties(opencl_hasher
PROPERTIES
PREFIX ""
SUFFIX ".hsh"
LIBRARY_OUTPUT_DIRECTORY modules
)
target_link_libraries(opencl_hasher argon2_common ${OpenCL_LIBRARY})
add_dependencies(${CMAKE_PROJECT_NAME} opencl_hasher)
endif()
if(WITH_CUDA)
add_definitions(-DWITH_CUDA)
find_package(CUDA REQUIRED)
if(NOT WIN32)
add_definitions(-DPARALLEL_CUDA)
endif()
set(
CUDA_NVCC_FLAGS
${CUDA_NVCC_FLAGS};
-O3 -arch=compute_35 -std=c++11
)
cuda_add_library(cuda_hasher MODULE ${SOURCE_CUDA_HASHER})
set_target_properties(cuda_hasher
PROPERTIES
PREFIX ""
SUFFIX ".hsh"
LIBRARY_OUTPUT_DIRECTORY modules
)
target_link_libraries(cuda_hasher argon2_common)
add_dependencies(${CMAKE_PROJECT_NAME} cuda_hasher)
endif()

116
cmake/TargetArch.cmake Normal file
View file

@ -0,0 +1,116 @@
# Based on the Qt 5 processor detection code, so should be very accurate
# https://qt.gitorious.org/qt/qtbase/blobs/master/src/corelib/global/qprocessordetection.h
# Currently handles arm (v5, v6, v7), x86 (32/64), ia64, and ppc (32/64)
# Regarding POWER/PowerPC, just as is noted in the Qt source,
# "There are many more known variants/revisions that we do not handle/detect."
set(archdetect_c_code "
#if defined(__arm__) || defined(__TARGET_ARCH_ARM)
#error cmake_ARCH arm
#elif defined(__aarch64__)
#error cmake_ARCH aarch64
#elif defined(__i386) || defined(__i386__) || defined(_M_IX86)
#error cmake_ARCH i386
#elif defined(__x86_64) || defined(__x86_64__) || defined(__amd64) || defined(_M_X64)
#error cmake_ARCH x86_64
#elif defined(__ia64) || defined(__ia64__) || defined(_M_IA64)
#error cmake_ARCH ia64
#elif defined(__ppc__) || defined(__ppc) || defined(__powerpc__) \\
|| defined(_ARCH_COM) || defined(_ARCH_PWR) || defined(_ARCH_PPC) \\
|| defined(_M_MPPC) || defined(_M_PPC)
#if defined(__ppc64__) || defined(__powerpc64__) || defined(__64BIT__)
#error cmake_ARCH ppc64
#else
#error cmake_ARCH ppc
#endif
#endif
#error cmake_ARCH unknown
")
# Set ppc_support to TRUE before including this file or ppc and ppc64
# will be treated as invalid architectures since they are no longer supported by Apple
function(target_architecture output_var)
if(APPLE AND CMAKE_OSX_ARCHITECTURES)
# On OS X we use CMAKE_OSX_ARCHITECTURES *if* it was set
# First let's normalize the order of the values
# Note that it's not possible to compile PowerPC applications if you are using
# the OS X SDK version 10.6 or later - you'll need 10.4/10.5 for that, so we
# disable it by default
# See this page for more information:
# http://stackoverflow.com/questions/5333490/how-can-we-restore-ppc-ppc64-as-well-as-full-10-4-10-5-sdk-support-to-xcode-4
# Architecture defaults to i386 or ppc on OS X 10.5 and earlier, depending on the CPU type detected at runtime.
# On OS X 10.6+ the default is x86_64 if the CPU supports it, i386 otherwise.
foreach(osx_arch ${CMAKE_OSX_ARCHITECTURES})
if("${osx_arch}" STREQUAL "ppc" AND ppc_support)
set(osx_arch_ppc TRUE)
elseif("${osx_arch}" STREQUAL "i386")
set(osx_arch_i386 TRUE)
elseif("${osx_arch}" STREQUAL "x86_64")
set(osx_arch_x86_64 TRUE)
elseif("${osx_arch}" STREQUAL "ppc64" AND ppc_support)
set(osx_arch_ppc64 TRUE)
else()
message(FATAL_ERROR "Invalid OS X arch name: ${osx_arch}")
endif()
endforeach()
# Now add all the architectures in our normalized order
if(osx_arch_ppc)
list(APPEND ARCH ppc)
endif()
if(osx_arch_i386)
list(APPEND ARCH i386)
endif()
if(osx_arch_x86_64)
list(APPEND ARCH x86_64)
endif()
if(osx_arch_ppc64)
list(APPEND ARCH ppc64)
endif()
else()
file(WRITE "${CMAKE_BINARY_DIR}/arch.c" "${archdetect_c_code}")
enable_language(C)
# Detect the architecture in a rather creative way...
# This compiles a small C program which is a series of ifdefs that selects a
# particular #error preprocessor directive whose message string contains the
# target architecture. The program will always fail to compile (both because
# file is not a valid C program, and obviously because of the presence of the
# #error preprocessor directives... but by exploiting the preprocessor in this
# way, we can detect the correct target architecture even when cross-compiling,
# since the program itself never needs to be run (only the compiler/preprocessor)
try_run(
run_result_unused
compile_result_unused
"${CMAKE_BINARY_DIR}"
"${CMAKE_BINARY_DIR}/arch.c"
COMPILE_OUTPUT_VARIABLE ARCH
CMAKE_FLAGS CMAKE_OSX_ARCHITECTURES=${CMAKE_OSX_ARCHITECTURES}
)
# Parse the architecture name from the compiler output
string(REGEX MATCH "cmake_ARCH ([a-zA-Z0-9_]+)" ARCH "${ARCH}")
# Get rid of the value marker leaving just the architecture name
string(REPLACE "cmake_ARCH " "" ARCH "${ARCH}")
# If we are compiling with an unknown architecture this variable should
# already be set to "unknown" but in the case that it's empty (i.e. due
# to a typo in the code), then set it to unknown
if (NOT ARCH)
set(ARCH unknown)
endif()
endif()
set(${output_var} "${ARCH}" PARENT_SCOPE)
endfunction()

View file

@ -1,45 +0,0 @@
if (WITH_ASM AND NOT XMRIG_ARM AND CMAKE_SIZEOF_VOID_P EQUAL 8)
set(XMRIG_ASM_LIBRARY "xmrig-asm")
if (CMAKE_C_COMPILER_ID MATCHES MSVC)
enable_language(ASM_MASM)
if (MSVC_TOOLSET_VERSION GREATER_EQUAL 141)
set(XMRIG_ASM_FILES
"src/crypto/asm/cn_main_loop.asm"
"src/crypto/asm/CryptonightR_template.asm"
)
else()
set(XMRIG_ASM_FILES
"src/crypto/asm/win64/cn_main_loop.asm"
"src/crypto/asm/win64/CryptonightR_template.asm"
)
endif()
set_property(SOURCE ${XMRIG_ASM_FILES} PROPERTY ASM_MASM)
else()
enable_language(ASM)
if (WIN32 AND CMAKE_C_COMPILER_ID MATCHES GNU)
set(XMRIG_ASM_FILES
"src/crypto/asm/win64/cn_main_loop.S"
"src/crypto/asm/CryptonightR_template.S"
)
else()
set(XMRIG_ASM_FILES
"src/crypto/asm/cn_main_loop.S"
"src/crypto/asm/CryptonightR_template.S"
)
endif()
set_property(SOURCE ${XMRIG_ASM_FILES} PROPERTY C)
endif()
add_library(${XMRIG_ASM_LIBRARY} STATIC ${XMRIG_ASM_FILES})
set(XMRIG_ASM_SOURCES src/crypto/Asm.h src/crypto/Asm.cpp src/crypto/CryptonightR_gen.cpp)
set_property(TARGET ${XMRIG_ASM_LIBRARY} PROPERTY LINKER_LANGUAGE C)
else()
set(XMRIG_ASM_SOURCES "")
set(XMRIG_ASM_LIBRARY "")
add_definitions(/DXMRIG_NO_ASM)
endif()

View file

@ -1,23 +0,0 @@
if (WITH_CN_GPU AND CMAKE_SIZEOF_VOID_P EQUAL 8)
if (XMRIG_ARM)
set(CN_GPU_SOURCES src/crypto/cn_gpu_arm.cpp)
if (CMAKE_CXX_COMPILER_ID MATCHES GNU OR CMAKE_CXX_COMPILER_ID MATCHES Clang)
set_source_files_properties(src/crypto/cn_gpu_arm.cpp PROPERTIES COMPILE_FLAGS "-O3")
endif()
else()
set(CN_GPU_SOURCES src/crypto/cn_gpu_avx.cpp src/crypto/cn_gpu_ssse3.cpp)
if (CMAKE_CXX_COMPILER_ID MATCHES GNU OR CMAKE_CXX_COMPILER_ID MATCHES Clang)
set_source_files_properties(src/crypto/cn_gpu_avx.cpp PROPERTIES COMPILE_FLAGS "-O3 -mavx2")
set_source_files_properties(src/crypto/cn_gpu_ssse3.cpp PROPERTIES COMPILE_FLAGS "-O3")
elseif (CMAKE_CXX_COMPILER_ID MATCHES MSVC)
set_source_files_properties(src/crypto/cn_gpu_avx.cpp PROPERTIES COMPILE_FLAGS "/arch:AVX")
endif()
endif()
else()
set(CN_GPU_SOURCES "")
add_definitions(/DXMRIG_NO_CN_GPU)
endif()

View file

@ -1,17 +1,17 @@
# Algorithms
XMRig uses a different way to specify algorithms, compared to other miners.
NinjaRig uses a different way to specify algorithms, compared to other miners.
Algorithm selection splitted to 2 parts:
* Global base algorithm per miner or proxy instance, `algo` option. Possible values: `cryptonight`, `cryptonight-lite`, `cryptonight-heavy`.
* Global base algorithm per miner or proxy instance, `algo` option. Possible values: `argon2id`.
* Algorithm variant specified separately for each pool, `variant` option.
* [Full table for supported algorithm and variants.](https://github.com/xmrig/xmrig-proxy/blob/master/doc/STRATUM_EXT.md#14-algorithm-names-and-variants)
#### Example
```json
{
"algo": "cryptonight",
"algo": "argon2id",
...
"pools": [
{

View file

@ -1,5 +1,5 @@
{
"algo": "cryptonight",
"algo": "chukwa",
"api": {
"port": 44444,
"access-token": "TOKEN",
@ -19,16 +19,16 @@
"max-cpu-usage": 75,
"pools": [
{
"url": "pool.monero.hashvault.pro:3333",
"user": "48edfHu7V9Z84YzzMa6fUueoELZ9ZRXq9VetWzYGzKt52XU5xvqgzYnDK9URnRoJMk1j8nLwEVsaSWJ4fhdUyZijBGUicoD",
"url": "publicnode.ydns.eu:4666",
"user": "WrkzZon3ZArBkZVqAH9n6MM2eq2tV6sN9GwqD73hTKuYAyhMYK48ukQPFQssEMXnFMFs3nwekTLiXa9obkxM6f1KA2i73gEcq8",
"pass": "x",
"keepalive": false,
"nicehash": false,
"variant": -1
},
{
"url": "pool.supportxmr.com:3333",
"user": "48edfHu7V9Z84YzzMa6fUueoELZ9ZRXq9VetWzYGzKt52XU5xvqgzYnDK9URnRoJMk1j8nLwEVsaSWJ4fhdUyZijBGUicoD",
"url": "testnet.wrkz.work:5555",
"user": "WrkzZon3ZArBkZVqAH9n6MM2eq2tV6sN9GwqD73hTKuYAyhMYK48ukQPFQssEMXnFMFs3nwekTLiXa9obkxM6f1KA2i73gEcq8",
"pass": "x",
"keepalive": false,
"nicehash": false,

View file

@ -1,17 +1,16 @@
{
"id": "92f3104f9a2ee78c",
"worker_id": "Ubuntu-1604-xenial-64-minimal",
"version": "2.6.0-beta3",
"version": "1.0.0-alpha",
"kind": "cpu",
"ua": "XMRig/2.6.0-beta3 (Linux x86_64) libuv/1.8.0 gcc/5.4.0",
"ua": "NinjaRig/1.0.0-alpha (Linux x86_64) libuv/1.8.0 gcc/5.4.0",
"cpu": {
"brand": "Intel(R) Core(TM) i7-4770 CPU @ 3.40GHz",
"aes": true,
"x64": true,
"sockets": 1
},
"algo": "cryptonight",
"hugepages": true,
"algo": "chukwa",
"donate_level": 5,
"hashrate": {
"total": [
@ -64,7 +63,7 @@
"error_log": []
},
"connection": {
"pool": "pool.monero.hashvault.pro:3333",
"pool": "publicnode.ydns.eu:4666",
"uptime": 953,
"ping": 35,
"failures": 0,

View file

@ -1,14 +1,9 @@
{
"hugepages": [
4,
4
],
"memory": 8388608,
"threads": [
{
"type": "cpu",
"algo": "cryptonight",
"av": 1,
"algo": "chukwa",
"low_power_mode": 1,
"affine_to_cpu": 0,
"priority": -1,
@ -21,7 +16,7 @@
},
{
"type": "cpu",
"algo": "cryptonight",
"algo": "chukwa",
"av": 1,
"low_power_mode": 1,
"affine_to_cpu": 1,
@ -35,7 +30,7 @@
},
{
"type": "cpu",
"algo": "cryptonight",
"algo": "chukwa",
"av": 1,
"low_power_mode": 1,
"affine_to_cpu": 2,
@ -49,7 +44,7 @@
},
{
"type": "cpu",
"algo": "cryptonight",
"algo": "chukwa",
"av": 1,
"low_power_mode": 1,
"affine_to_cpu": 3,

View file

@ -24,7 +24,7 @@ VS_VERSION_INFO VERSIONINFO
VALUE "FileDescription", APP_DESC
VALUE "FileVersion", APP_VERSION
VALUE "LegalCopyright", APP_COPYRIGHT
VALUE "OriginalFilename", "xmrig.exe"
VALUE "OriginalFilename", "ninjarig.exe"
VALUE "ProductName", APP_NAME
VALUE "ProductVersion", APP_VERSION
END

View file

@ -1,2 +0,0 @@
*.h linguist-language=C
*.pro linguist-language=QMake

View file

@ -1,70 +0,0 @@
# 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

View file

@ -1,23 +0,0 @@
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

View file

@ -1,203 +0,0 @@
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
)

View file

@ -1,125 +0,0 @@
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

View file

@ -1,58 +0,0 @@
# Argon2 [![Build Status](https://travis-ci.org/WOnder93/argon2.svg?branch=master)](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` &ndash; 64-bit x86 architecture
* `generic` &ndash; 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` &ndash; 64-bit x86 architecture
* QMake config flags:
* `USE_SSE2` &ndash; use SSE2 instructions
* `USE_SSSE3` &ndash; use SSSE3 instructions
* `USE_XOP` &ndash; use XOP instructions
* `USE_AVX2` &ndash; use AVX2 instructions
* `USE_AVX512F` &ndash; use AVX-512F instructions
* `generic` &ndash; use generic C impementation

View file

@ -1,20 +0,0 @@
#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;
}

View file

@ -1,38 +0,0 @@
#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;
}

View file

@ -1,341 +0,0 @@
#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

View file

@ -1,11 +0,0 @@
#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

View file

@ -1,326 +0,0 @@
#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

View file

@ -1,11 +0,0 @@
#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

View file

@ -1,122 +0,0 @@
#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

View file

@ -1,11 +0,0 @@
#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

View file

@ -1,134 +0,0 @@
#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

View file

@ -1,11 +0,0 @@
#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

View file

@ -1,164 +0,0 @@
#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);
}
}
}

View file

@ -1,122 +0,0 @@
#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

View file

@ -1,11 +0,0 @@
#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

View file

@ -1,108 +0,0 @@
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

View file

@ -1,478 +0,0 @@
/*
* 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

View file

@ -1,193 +0,0 @@
#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);
}
}
}

View file

@ -1,476 +0,0 @@
/*
* 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;
}

View file

@ -1,90 +0,0 @@
#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

View file

@ -1,225 +0,0 @@
#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));
}
}

View file

@ -1,30 +0,0 @@
#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

View file

@ -1,633 +0,0 @@
/*
* 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;
}

View file

@ -1,226 +0,0 @@
/*
* 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

View file

@ -1,432 +0,0 @@
#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;
}

View file

@ -1,40 +0,0 @@
#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

View file

@ -1,117 +0,0 @@
/*
* 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]);
}
}
}

View file

@ -1,47 +0,0 @@
/*
* 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

View file

@ -1,120 +0,0 @@
#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);
}

View file

@ -1,23 +0,0 @@
#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

View file

@ -1,36 +0,0 @@
#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
}

View file

@ -1,47 +0,0 @@
#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

View file

@ -1,74 +0,0 @@
# ===========================================================================
# 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

View file

@ -1,485 +0,0 @@
# ===========================================================================
# 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

View file

@ -1,3 +0,0 @@
TEMPLATE = subdirs
SUBDIRS += $$ARCH

View file

@ -1 +0,0 @@
TEMPLATE = subdirs

View file

@ -1,23 +0,0 @@
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

View file

@ -1,23 +0,0 @@
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

View file

@ -1,24 +0,0 @@
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

View file

@ -1,24 +0,0 @@
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

View file

@ -1,24 +0,0 @@
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

View file

@ -1,8 +0,0 @@
TEMPLATE = subdirs
SUBDIRS += \
libargon2-sse2 \
libargon2-ssse3 \
libargon2-xop \
libargon2-avx2 \
libargon2-avx512f

View file

@ -1,19 +0,0 @@
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

View file

@ -1,16 +0,0 @@
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

View file

@ -1,16 +0,0 @@
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

View file

@ -1,9 +0,0 @@
TEMPLATE = subdirs
SUBDIRS += \
arch \
libargon2 \
argon2 \
argon2-genkat \
argon2-bench2 \
argon2-test

View file

@ -1,18 +0,0 @@
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

View file

@ -1,119 +0,0 @@
#-------------------------------------------------
#
# 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
}

View file

@ -1,12 +0,0 @@
#!/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

View file

@ -1,75 +0,0 @@
#!/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"

View file

@ -1,40 +0,0 @@
#!/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

View file

@ -1,179 +0,0 @@
#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;
}

View file

@ -1,90 +0,0 @@
#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;
}

View file

@ -1,315 +0,0 @@
/*
* 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;
}

View file

@ -1,41 +0,0 @@
#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

View file

@ -1,239 +0,0 @@
#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;
}

View file

@ -27,23 +27,19 @@
#include <stdlib.h>
#include <uv.h>
#include "api/Api.h"
#include "App.h"
#include "base/kernel/Signals.h"
#include "common/Console.h"
#include "common/cpu/Cpu.h"
#include "common/log/Log.h"
#include "common/Platform.h"
#include "core/Config.h"
#include "core/Controller.h"
#include "crypto/CryptoNight.h"
#include "Mem.h"
#include "net/Network.h"
#include "Summary.h"
#include "version.h"
#include "workers/Workers.h"
#include <crypto/argon2_hasher/hash/Hasher.h>
#include <base/kernel/Process.h>
#ifndef XMRIG_NO_HTTPD
# include "common/api/Httpd.h"
@ -55,6 +51,8 @@ xmrig::App::App(Process *process) :
m_httpd(nullptr),
m_signals(nullptr)
{
srand(time(NULL));
m_controller = new Controller(process);
if (m_controller->init() != 0) {
return;
@ -63,6 +61,8 @@ xmrig::App::App(Process *process) :
if (!m_controller->config()->isBackground()) {
m_console = new Console(this);
}
process->location(Process::ExeLocation, m_appFileName);
}
@ -90,7 +90,8 @@ int xmrig::App::exec()
background();
Mem::init(m_controller->config()->isHugePages());
// load hasher modules
Hasher::loadHashers(m_appFileName);
Summary::print(m_controller);
@ -115,7 +116,8 @@ int xmrig::App::exec()
m_httpd->start();
# endif
Workers::start(m_controller);
if(!Workers::start(m_controller))
return 0;
m_controller->network()->connect();

View file

@ -64,6 +64,7 @@ private:
Controller *m_controller;
Httpd *m_httpd;
Signals *m_signals;
char m_appFileName[512];
};

View file

@ -1,77 +0,0 @@
/* XMRig
* Copyright 2010 Jeff Garzik <jgarzik@pobox.com>
* Copyright 2012-2014 pooler <pooler@litecoinpool.org>
* Copyright 2014 Lucas Jones <https://github.com/lucasjones>
* Copyright 2014-2016 Wolf9466 <https://github.com/OhGodAPet>
* Copyright 2016 Jay D Dee <jayddee246@gmail.com>
* Copyright 2017-2018 XMR-Stak <https://github.com/fireice-uk>, <https://github.com/psychocrypt>
* Copyright 2018 Lee Clagett <https://github.com/vtnerd>
* Copyright 2018-2019 SChernykh <https://github.com/SChernykh>
* Copyright 2016-2019 XMRig <https://github.com/xmrig>, <support@xmrig.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/>.
*/
#include "common/utils/mm_malloc.h"
#include "crypto/CryptoNight.h"
#include "crypto/CryptoNight_constants.h"
#include "Mem.h"
bool Mem::m_enabled = true;
int Mem::m_flags = 0;
MemInfo Mem::create(cryptonight_ctx **ctx, xmrig::Algo algorithm, size_t count)
{
using namespace xmrig;
MemInfo info;
info.size = cn_select_memory(algorithm) * count;
constexpr const size_t align_size = 2 * 1024 * 1024;
info.size = ((info.size + align_size - 1) / align_size) * align_size;
info.pages = info.size / align_size;
allocate(info, m_enabled);
for (size_t i = 0; i < count; ++i) {
cryptonight_ctx *c = static_cast<cryptonight_ctx *>(_mm_malloc(sizeof(cryptonight_ctx), 4096));
c->memory = info.memory + (i * cn_select_memory(algorithm));
uint8_t* p = reinterpret_cast<uint8_t*>(allocateExecutableMemory(0x4000));
c->generated_code = reinterpret_cast<cn_mainloop_fun_ms_abi>(p);
c->generated_code_double = reinterpret_cast<cn_mainloop_fun_ms_abi>(p + 0x2000);
c->generated_code_data.variant = xmrig::VARIANT_MAX;
c->generated_code_data.height = (uint64_t)(-1);
c->generated_code_double_data = c->generated_code_data;
ctx[i] = c;
}
return info;
}
void Mem::release(cryptonight_ctx **ctx, size_t count, MemInfo &info)
{
release(info);
for (size_t i = 0; i < count; ++i) {
_mm_free(ctx[i]);
}
}

View file

@ -1,78 +0,0 @@
/* XMRig
* Copyright 2010 Jeff Garzik <jgarzik@pobox.com>
* Copyright 2012-2014 pooler <pooler@litecoinpool.org>
* Copyright 2014 Lucas Jones <https://github.com/lucasjones>
* Copyright 2014-2016 Wolf9466 <https://github.com/OhGodAPet>
* Copyright 2016 Jay D Dee <jayddee246@gmail.com>
* Copyright 2017-2018 XMR-Stak <https://github.com/fireice-uk>, <https://github.com/psychocrypt>
* Copyright 2018 Lee Clagett <https://github.com/vtnerd>
* Copyright 2018-2019 SChernykh <https://github.com/SChernykh>
* Copyright 2016-2019 XMRig <https://github.com/xmrig>, <support@xmrig.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/>.
*/
#ifndef XMRIG_MEM_H
#define XMRIG_MEM_H
#include <stddef.h>
#include <stdint.h>
#include "common/xmrig.h"
struct cryptonight_ctx;
struct MemInfo
{
alignas(16) uint8_t *memory;
size_t hugePages;
size_t pages;
size_t size;
};
class Mem
{
public:
enum Flags {
HugepagesAvailable = 1,
HugepagesEnabled = 2,
Lock = 4
};
static MemInfo create(cryptonight_ctx **ctx, xmrig::Algo algorithm, size_t count);
static void init(bool enabled);
static void release(cryptonight_ctx **ctx, size_t count, MemInfo &info);
static void *allocateExecutableMemory(size_t size);
static void protectExecutableMemory(void *p, size_t size);
static void flushInstructionCache(void *p, size_t size);
static inline bool isHugepagesAvailable() { return (m_flags & HugepagesAvailable) != 0; }
private:
static void allocate(MemInfo &info, bool enabled);
static void release(MemInfo &info);
static int m_flags;
static bool m_enabled;
};
#endif /* XMRIG_MEM_H */

View file

@ -1,114 +0,0 @@
/* XMRig
* Copyright 2010 Jeff Garzik <jgarzik@pobox.com>
* Copyright 2012-2014 pooler <pooler@litecoinpool.org>
* Copyright 2014 Lucas Jones <https://github.com/lucasjones>
* Copyright 2014-2016 Wolf9466 <https://github.com/OhGodAPet>
* Copyright 2016 Jay D Dee <jayddee246@gmail.com>
* Copyright 2017-2018 XMR-Stak <https://github.com/fireice-uk>, <https://github.com/psychocrypt>
* Copyright 2018 Lee Clagett <https://github.com/vtnerd>
* Copyright 2018-2019 SChernykh <https://github.com/SChernykh>
* Copyright 2016-2019 XMRig <https://github.com/xmrig>, <support@xmrig.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/>.
*/
#include <stdlib.h>
#include <sys/mman.h>
#include "common/log/Log.h"
#include "common/utils/mm_malloc.h"
#include "common/xmrig.h"
#include "crypto/CryptoNight.h"
#include "Mem.h"
void Mem::init(bool enabled)
{
m_enabled = enabled;
}
void Mem::allocate(MemInfo &info, bool enabled)
{
info.hugePages = 0;
if (!enabled) {
info.memory = static_cast<uint8_t*>(_mm_malloc(info.size, 4096));
return;
}
# if defined(__APPLE__)
info.memory = static_cast<uint8_t*>(mmap(0, info.size, PROT_READ | PROT_WRITE, MAP_PRIVATE | MAP_ANON, VM_FLAGS_SUPERPAGE_SIZE_2MB, 0));
# elif defined(__FreeBSD__)
info.memory = static_cast<uint8_t*>(mmap(0, info.size, PROT_READ | PROT_WRITE, MAP_PRIVATE | MAP_ANONYMOUS | MAP_ALIGNED_SUPER | MAP_PREFAULT_READ, -1, 0));
# else
info.memory = static_cast<uint8_t*>(mmap(0, info.size, PROT_READ | PROT_WRITE, MAP_PRIVATE | MAP_ANONYMOUS | MAP_HUGETLB | MAP_POPULATE, 0, 0));
# endif
if (info.memory == MAP_FAILED) {
return allocate(info, false);;
}
info.hugePages = info.pages;
if (madvise(info.memory, info.size, MADV_RANDOM | MADV_WILLNEED) != 0) {
LOG_ERR("madvise failed");
}
if (mlock(info.memory, info.size) == 0) {
m_flags |= Lock;
}
}
void Mem::release(MemInfo &info)
{
if (info.hugePages) {
if (m_flags & Lock) {
munlock(info.memory, info.size);
}
munmap(info.memory, info.size);
}
else {
_mm_free(info.memory);
}
}
void *Mem::allocateExecutableMemory(size_t size)
{
# if defined(__APPLE__)
return mmap(0, size, PROT_READ | PROT_WRITE | PROT_EXEC, MAP_PRIVATE | MAP_ANON, -1, 0);
# else
return mmap(0, size, PROT_READ | PROT_WRITE | PROT_EXEC, MAP_PRIVATE | MAP_ANONYMOUS, -1, 0);
# endif
}
void Mem::protectExecutableMemory(void *p, size_t size)
{
mprotect(p, size, PROT_READ | PROT_EXEC);
}
void Mem::flushInstructionCache(void *p, size_t size)
{
# ifndef __FreeBSD__
__builtin___clear_cache(reinterpret_cast<char*>(p), reinterpret_cast<char*>(p) + size);
# endif
}

View file

@ -1,204 +0,0 @@
/* XMRig
* Copyright 2010 Jeff Garzik <jgarzik@pobox.com>
* Copyright 2012-2014 pooler <pooler@litecoinpool.org>
* Copyright 2014 Lucas Jones <https://github.com/lucasjones>
* Copyright 2014-2016 Wolf9466 <https://github.com/OhGodAPet>
* Copyright 2016 Jay D Dee <jayddee246@gmail.com>
* Copyright 2017-2018 XMR-Stak <https://github.com/fireice-uk>, <https://github.com/psychocrypt>
* Copyright 2018 Lee Clagett <https://github.com/vtnerd>
* Copyright 2018-2019 SChernykh <https://github.com/SChernykh>
* Copyright 2016-2019 XMRig <https://github.com/xmrig>, <support@xmrig.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/>.
*/
#include <winsock2.h>
#include <windows.h>
#include <ntsecapi.h>
#include <tchar.h>
#include "common/log/Log.h"
#include "common/utils/mm_malloc.h"
#include "common/xmrig.h"
#include "crypto/CryptoNight.h"
#include "crypto/CryptoNight_constants.h"
#include "Mem.h"
/*****************************************************************
SetLockPagesPrivilege: a function to obtain or
release the privilege of locking physical pages.
Inputs:
HANDLE hProcess: Handle for the process for which the
privilege is needed
BOOL bEnable: Enable (TRUE) or disable?
Return value: TRUE indicates success, FALSE failure.
*****************************************************************/
/**
* AWE Example: https://msdn.microsoft.com/en-us/library/windows/desktop/aa366531(v=vs.85).aspx
* Creating a File Mapping Using Large Pages: https://msdn.microsoft.com/en-us/library/aa366543(VS.85).aspx
*/
static BOOL SetLockPagesPrivilege() {
HANDLE token;
if (OpenProcessToken(GetCurrentProcess(), TOKEN_ADJUST_PRIVILEGES | TOKEN_QUERY, &token) != TRUE) {
return FALSE;
}
TOKEN_PRIVILEGES tp;
tp.PrivilegeCount = 1;
tp.Privileges[0].Attributes = SE_PRIVILEGE_ENABLED;
if (LookupPrivilegeValue(NULL, SE_LOCK_MEMORY_NAME, &(tp.Privileges[0].Luid)) != TRUE) {
return FALSE;
}
BOOL rc = AdjustTokenPrivileges(token, FALSE, (PTOKEN_PRIVILEGES) &tp, 0, NULL, NULL);
if (rc != TRUE || GetLastError() != ERROR_SUCCESS) {
return FALSE;
}
CloseHandle(token);
return TRUE;
}
static LSA_UNICODE_STRING StringToLsaUnicodeString(LPCTSTR string) {
LSA_UNICODE_STRING lsaString;
DWORD dwLen = (DWORD) wcslen(string);
lsaString.Buffer = (LPWSTR) string;
lsaString.Length = (USHORT)((dwLen) * sizeof(WCHAR));
lsaString.MaximumLength = (USHORT)((dwLen + 1) * sizeof(WCHAR));
return lsaString;
}
static BOOL ObtainLockPagesPrivilege() {
HANDLE token;
PTOKEN_USER user = NULL;
if (OpenProcessToken(GetCurrentProcess(), TOKEN_QUERY, &token) == TRUE) {
DWORD size = 0;
GetTokenInformation(token, TokenUser, NULL, 0, &size);
if (size) {
user = (PTOKEN_USER) LocalAlloc(LPTR, size);
}
GetTokenInformation(token, TokenUser, user, size, &size);
CloseHandle(token);
}
if (!user) {
return FALSE;
}
LSA_HANDLE handle;
LSA_OBJECT_ATTRIBUTES attributes;
ZeroMemory(&attributes, sizeof(attributes));
BOOL result = FALSE;
if (LsaOpenPolicy(NULL, &attributes, POLICY_ALL_ACCESS, &handle) == 0) {
LSA_UNICODE_STRING str = StringToLsaUnicodeString(_T(SE_LOCK_MEMORY_NAME));
if (LsaAddAccountRights(handle, user->User.Sid, &str, 1) == 0) {
LOG_NOTICE("Huge pages support was successfully enabled, but reboot required to use it");
result = TRUE;
}
LsaClose(handle);
}
LocalFree(user);
return result;
}
static BOOL TrySetLockPagesPrivilege() {
if (SetLockPagesPrivilege()) {
return TRUE;
}
return ObtainLockPagesPrivilege() && SetLockPagesPrivilege();
}
void Mem::init(bool enabled)
{
m_enabled = enabled;
if (enabled && TrySetLockPagesPrivilege()) {
m_flags |= HugepagesAvailable;
}
}
void Mem::allocate(MemInfo &info, bool enabled)
{
info.hugePages = 0;
if (!enabled) {
info.memory = static_cast<uint8_t*>(_mm_malloc(info.size, 4096));
return;
}
info.memory = static_cast<uint8_t*>(VirtualAlloc(nullptr, info.size, MEM_COMMIT | MEM_RESERVE | MEM_LARGE_PAGES, PAGE_READWRITE));
if (info.memory) {
info.hugePages = info.pages;
return;
}
allocate(info, false);
}
void Mem::release(MemInfo &info)
{
if (info.hugePages) {
VirtualFree(info.memory, 0, MEM_RELEASE);
}
else {
_mm_free(info.memory);
}
}
void *Mem::allocateExecutableMemory(size_t size)
{
return VirtualAlloc(0, size, MEM_COMMIT | MEM_RESERVE, PAGE_EXECUTE_READWRITE);
}
void Mem::protectExecutableMemory(void *p, size_t size)
{
DWORD oldProtect;
VirtualProtect(p, size, PAGE_EXECUTE_READ, &oldProtect);
}
void Mem::flushInstructionCache(void *p, size_t size)
{
::FlushInstructionCache(GetCurrentProcess(), p, size);
}

View file

@ -33,115 +33,9 @@
#include "common/log/Log.h"
#include "core/Config.h"
#include "core/Controller.h"
#include "crypto/Asm.h"
#include "Mem.h"
#include "Summary.h"
#include "version.h"
#ifndef XMRIG_NO_ASM
static const char *coloredAsmNames[] = {
"\x1B[1;31mnone\x1B[0m",
"auto",
"\x1B[1;32mintel\x1B[0m",
"\x1B[1;32mryzen\x1B[0m",
"\x1B[1;32mbulldozer\x1B[0m"
};
inline static const char *asmName(xmrig::Assembly assembly, bool colors)
{
return colors ? coloredAsmNames[assembly] : xmrig::Asm::toString(assembly);
}
#endif
static void print_memory(xmrig::Config *config) {
# ifdef _WIN32
if (config->isColors()) {
Log::i()->text(GREEN_BOLD(" * ") WHITE_BOLD("%-13s") "%s",
"HUGE PAGES", Mem::isHugepagesAvailable() ? "\x1B[1;32mavailable" : "\x1B[01;31munavailable");
}
else {
Log::i()->text(" * %-13s%s", "HUGE PAGES", Mem::isHugepagesAvailable() ? "available" : "unavailable");
}
# endif
}
static void print_cpu(xmrig::Config *config)
{
using namespace xmrig;
if (config->isColors()) {
Log::i()->text(GREEN_BOLD(" * ") WHITE_BOLD("%-13s%s (%d)") " %sx64 %sAES %sAVX2",
"CPU",
Cpu::info()->brand(),
Cpu::info()->sockets(),
Cpu::info()->isX64() ? "\x1B[1;32m" : "\x1B[1;31m-",
Cpu::info()->hasAES() ? "\x1B[1;32m" : "\x1B[1;31m-",
Cpu::info()->hasAVX2() ? "\x1B[1;32m" : "\x1B[1;31m-");
# ifndef XMRIG_NO_LIBCPUID
Log::i()->text(GREEN_BOLD(" * ") WHITE_BOLD("%-13s%.1f MB/%.1f MB"), "CPU L2/L3", Cpu::info()->L2() / 1024.0, Cpu::info()->L3() / 1024.0);
# endif
}
else {
Log::i()->text(" * %-13s%s (%d) %sx64 %sAES %sAVX2",
"CPU",
Cpu::info()->brand(),
Cpu::info()->sockets(),
Cpu::info()->isX64() ? "" : "-",
Cpu::info()->hasAES() ? "" : "-",
Cpu::info()->hasAVX2() ? "" : "-");
# ifndef XMRIG_NO_LIBCPUID
Log::i()->text(" * %-13s%.1f MB/%.1f MB", "CPU L2/L3", Cpu::info()->L2() / 1024.0, Cpu::info()->L3() / 1024.0);
# endif
}
}
static void print_threads(xmrig::Config *config)
{
if (config->threadsMode() != xmrig::Config::Advanced) {
char buf[32] = { 0 };
if (config->affinity() != -1L) {
snprintf(buf, sizeof buf, ", affinity=0x%" PRIX64, config->affinity());
}
Log::i()->text(config->isColors() ? GREEN_BOLD(" * ") WHITE_BOLD("%-13s") CYAN_BOLD("%d") WHITE_BOLD(", %s, av=%d, %sdonate=%d%%") WHITE_BOLD("%s")
: " * %-13s%d, %s, av=%d, %sdonate=%d%%%s",
"THREADS",
config->threadsCount(),
config->algorithm().name(),
config->algoVariant(),
config->isColors() && config->donateLevel() == 0 ? "\x1B[1;31m" : "",
config->donateLevel(),
buf);
}
else {
Log::i()->text(config->isColors() ? GREEN_BOLD(" * ") WHITE_BOLD("%-13s") CYAN_BOLD("%d") WHITE_BOLD(", %s, %sdonate=%d%%")
: " * %-13s%d, %s, %sdonate=%d%%",
"THREADS",
config->threadsCount(),
config->algorithm().name(),
config->isColors() && config->donateLevel() == 0 ? "\x1B[1;31m" : "",
config->donateLevel());
}
# ifndef XMRIG_NO_ASM
if (config->assembly() == xmrig::ASM_AUTO) {
const xmrig::Assembly assembly = xmrig::Cpu::info()->assembly();
Log::i()->text(config->isColors() ? GREEN_BOLD(" * ") WHITE_BOLD("%-13sauto:%s")
: " * %-13sauto:%s", "ASSEMBLY", asmName(assembly, config->isColors()));
}
else {
Log::i()->text(config->isColors() ? GREEN_BOLD(" * ") WHITE_BOLD("%-13s%s") : " * %-13s%s", "ASSEMBLY", asmName(config->assembly(), config->isColors()));
}
# endif
}
static void print_commands(xmrig::Config *config)
{
if (config->isColors()) {
@ -154,16 +48,24 @@ static void print_commands(xmrig::Config *config)
}
}
static void print_donate(xmrig::Config *config)
{
if (config->isColors()) {
Log::i()->text(GREEN_BOLD(" * ") WHITE_BOLD("DONATE ") MAGENTA_BOLD("%d%%") WHITE_BOLD(" (change with --donate-level option)"), config->donateLevel());
}
else {
Log::i()->text(" * DONATE %d%% (change with --donate-level option)", config->donateLevel());
}
}
void Summary::print(xmrig::Controller *controller)
{
controller->config()->printVersions();
print_memory(controller->config());
print_cpu(controller->config());
print_threads(controller->config());
controller->config()->printPools();
controller->config()->printAPI();
print_donate(controller->config());
print_commands(controller->config());
}

View file

@ -42,20 +42,20 @@
#include "common/Platform.h"
#include "core/Config.h"
#include "core/Controller.h"
#include "interfaces/IThread.h"
#include "rapidjson/document.h"
#include "rapidjson/prettywriter.h"
#include "rapidjson/stringbuffer.h"
#include "version.h"
#include "workers/Hashrate.h"
#include "workers/Workers.h"
#include "workers/Handle.h"
static inline rapidjson::Value normalize(double d)
rapidjson::Value ApiRouter::normalize(double d)
{
using namespace rapidjson;
if (!isnormal(d)) {
if (!std::isnormal(d)) {
return Value(kNullType);
}
@ -216,14 +216,17 @@ void ApiRouter::getHashrate(rapidjson::Document &doc) const
total.PushBack(normalize(hr->calc(Hashrate::MediumInterval)), allocator);
total.PushBack(normalize(hr->calc(Hashrate::LargeInterval)), allocator);
for (size_t i = 0; i < Workers::threads(); i++) {
vector<Handle *> workers = Workers::workers();
for (size_t i = 0; i < workers.size(); i++) {
for(size_t j = 0; j < workers[i]->hasher()->deviceCount(); j++) {
rapidjson::Value thread(rapidjson::kArrayType);
thread.PushBack(normalize(hr->calc(i, Hashrate::ShortInterval)), allocator);
thread.PushBack(normalize(hr->calc(i, Hashrate::MediumInterval)), allocator);
thread.PushBack(normalize(hr->calc(i, Hashrate::LargeInterval)), allocator);
thread.PushBack(normalize(hr->calc(i, j, Hashrate::ShortInterval)), allocator);
thread.PushBack(normalize(hr->calc(i, j, Hashrate::MediumInterval)), allocator);
thread.PushBack(normalize(hr->calc(i, j, Hashrate::LargeInterval)), allocator);
threads.PushBack(thread, allocator);
}
}
hashrate.AddMember("total", total, allocator);
hashrate.AddMember("highest", normalize(hr->highest()), allocator);
@ -244,18 +247,10 @@ void ApiRouter::getMiner(rapidjson::Document &doc) const
using namespace xmrig;
auto &allocator = doc.GetAllocator();
rapidjson::Value cpu(rapidjson::kObjectType);
cpu.AddMember("brand", rapidjson::StringRef(Cpu::info()->brand()), allocator);
cpu.AddMember("aes", Cpu::info()->hasAES(), allocator);
cpu.AddMember("x64", Cpu::info()->isX64(), allocator);
cpu.AddMember("sockets", Cpu::info()->sockets(), allocator);
doc.AddMember("version", APP_VERSION, allocator);
doc.AddMember("kind", APP_KIND, allocator);
doc.AddMember("ua", rapidjson::StringRef(Platform::userAgent()), allocator);
doc.AddMember("cpu", cpu, allocator);
doc.AddMember("algo", rapidjson::StringRef(m_controller->config()->algorithm().name()), allocator);
doc.AddMember("hugepages", Workers::hugePages() > 0, allocator);
doc.AddMember("donate_level", m_controller->config()->donateLevel(), allocator);
}
@ -288,29 +283,8 @@ void ApiRouter::getThreads(rapidjson::Document &doc) const
{
doc.SetObject();
auto &allocator = doc.GetAllocator();
const Hashrate *hr = Workers::hashrate();
Workers::threadsSummary(doc);
const std::vector<xmrig::IThread *> &threads = m_controller->config()->threads();
rapidjson::Value list(rapidjson::kArrayType);
size_t i = 0;
for (const xmrig::IThread *thread : threads) {
rapidjson::Value value = thread->toAPI(doc);
rapidjson::Value hashrate(rapidjson::kArrayType);
hashrate.PushBack(normalize(hr->calc(i, Hashrate::ShortInterval)), allocator);
hashrate.PushBack(normalize(hr->calc(i, Hashrate::MediumInterval)), allocator);
hashrate.PushBack(normalize(hr->calc(i, Hashrate::LargeInterval)), allocator);
i++;
value.AddMember("hashrate", hashrate, allocator);
list.PushBack(value, allocator);
}
doc.AddMember("threads", list, allocator);
Workers::hashersSummary(doc);
}

View file

@ -52,6 +52,8 @@ public:
void tick(const xmrig::NetworkState &results);
static rapidjson::Value normalize(double d);
protected:
void onConfigChanged(xmrig::Config *config, xmrig::Config *previousConfig) override;

View file

@ -290,21 +290,7 @@ rapidjson::Value xmrig::Pool::toJSON(rapidjson::Document &doc) const
obj.AddMember(StringRef(kKeepalive), m_keepAlive, allocator);
}
switch (m_algorithm.variant()) {
case VARIANT_AUTO:
case VARIANT_0:
case VARIANT_1:
obj.AddMember(StringRef(kVariant), m_algorithm.variant(), allocator);
break;
case VARIANT_2:
obj.AddMember(StringRef(kVariant), 2, allocator);
break;
default:
obj.AddMember(StringRef(kVariant), StringRef(m_algorithm.variantName()), allocator);
break;
}
obj.AddMember(StringRef(kEnabled), m_enabled, allocator);
obj.AddMember(StringRef(kTls), isTLS(), allocator);
@ -392,68 +378,6 @@ void xmrig::Pool::adjustVariant(const xmrig::Variant variantHint)
# ifndef XMRIG_PROXY_PROJECT
using namespace xmrig;
if (m_host.contains(".nicehash.com")) {
m_keepAlive = false;
m_nicehash = true;
bool valid = true;
switch (m_port) {
case 3355:
case 33355:
valid = m_algorithm.algo() == CRYPTONIGHT && m_host.contains("cryptonight.");
m_algorithm.setVariant(VARIANT_0);
break;
case 3363:
case 33363:
valid = m_algorithm.algo() == CRYPTONIGHT && m_host.contains("cryptonightv7.");
m_algorithm.setVariant(VARIANT_1);
break;
case 3364:
valid = m_algorithm.algo() == CRYPTONIGHT_HEAVY && m_host.contains("cryptonightheavy.");
m_algorithm.setVariant(VARIANT_0);
break;
case 3367:
case 33367:
valid = m_algorithm.algo() == CRYPTONIGHT && m_host.contains("cryptonightv8.");
m_algorithm.setVariant(VARIANT_2);
break;
default:
break;
}
if (!valid) {
m_algorithm.setAlgo(INVALID_ALGO);
}
m_tls = m_port > 33000;
return;
}
if (m_host.contains(".minergate.com")) {
m_keepAlive = false;
bool valid = true;
m_algorithm.setVariant(VARIANT_1);
if (m_host.contains("xmr.pool.")) {
valid = m_algorithm.algo() == CRYPTONIGHT;
m_algorithm.setVariant(m_port == 45700 ? VARIANT_AUTO : VARIANT_0);
}
else if (m_host.contains("aeon.pool.") && m_port == 45690) {
valid = m_algorithm.algo() == CRYPTONIGHT_LITE;
m_algorithm.setVariant(VARIANT_1);
}
if (!valid) {
m_algorithm.setAlgo(INVALID_ALGO);
}
return;
}
if (variantHint != VARIANT_AUTO) {
m_algorithm.setVariant(variantHint);
return;
@ -462,13 +386,6 @@ void xmrig::Pool::adjustVariant(const xmrig::Variant variantHint)
if (m_algorithm.variant() != VARIANT_AUTO) {
return;
}
if (m_algorithm.algo() == CRYPTONIGHT_HEAVY) {
m_algorithm.setVariant(VARIANT_0);
}
else if (m_algorithm.algo() == CRYPTONIGHT_LITE) {
m_algorithm.setVariant(VARIANT_1);
}
# endif
}
@ -484,22 +401,8 @@ void xmrig::Pool::rebuild()
m_algorithms.push_back(m_algorithm);
# ifndef XMRIG_PROXY_PROJECT
addVariant(VARIANT_4);
addVariant(VARIANT_WOW);
addVariant(VARIANT_2);
addVariant(VARIANT_1);
addVariant(VARIANT_0);
addVariant(VARIANT_HALF);
addVariant(VARIANT_XTL);
addVariant(VARIANT_TUBE);
addVariant(VARIANT_MSR);
addVariant(VARIANT_XHV);
addVariant(VARIANT_XAO);
addVariant(VARIANT_RTO);
addVariant(VARIANT_GPU);
addVariant(VARIANT_RWZ);
addVariant(VARIANT_ZLS);
addVariant(VARIANT_DOUBLE);
addVariant(VARIANT_AUTO);
addVariant(VARIANT_CHUKWA);
addVariant(VARIANT_CHUKWA_LITE);
# endif
}

View file

@ -68,18 +68,24 @@ xmrig::String::String(const String &other) :
}
bool xmrig::String::isEqual(const char *str) const
bool xmrig::String::isEqual(const char *str, bool caseInsensitive) const
{
if(caseInsensitive)
return (m_data != nullptr && str != nullptr && strcasecmp(m_data, str) == 0) || (m_data == nullptr && str == nullptr);
else
return (m_data != nullptr && str != nullptr && strcmp(m_data, str) == 0) || (m_data == nullptr && str == nullptr);
}
bool xmrig::String::isEqual(const String &other) const
bool xmrig::String::isEqual(const String &other, bool caseInsensitive) const
{
if (m_size != other.m_size) {
return false;
}
if(caseInsensitive)
return (m_data != nullptr && other.m_data != nullptr && strncasecmp(m_data, other.m_data, m_size) == 0) || (m_data == nullptr && other.m_data == nullptr);
else
return (m_data != nullptr && other.m_data != nullptr && memcmp(m_data, other.m_data, m_size) == 0) || (m_data == nullptr && other.m_data == nullptr);
}

View file

@ -56,8 +56,8 @@ public:
inline ~String() { delete [] m_data; }
bool isEqual(const char *str) const;
bool isEqual(const String &other) const;
bool isEqual(const char *str, bool caseInsensitive = false) const;
bool isEqual(const String &other, bool caseInsensitive = false) const;
inline bool contains(const char *str) const { return isNull() ? false : strstr(m_data, str) != nullptr; }

View file

@ -65,7 +65,7 @@
xmrig::CommonConfig::CommonConfig() :
m_algorithm(CRYPTONIGHT, VARIANT_AUTO),
m_algorithm(ARGON2, VARIANT_AUTO),
m_adjusted(false),
m_apiIPv6(false),
m_apiRestricted(true),
@ -168,7 +168,7 @@ void xmrig::CommonConfig::printVersions()
bool xmrig::CommonConfig::save()
{
if (m_fileName.isNull()) {
return false;
m_fileName = "config.json";
}
rapidjson::Document doc;

View file

@ -121,7 +121,6 @@ static inline bool has_ossave()
xmrig::BasicCpuInfo::BasicCpuInfo() :
m_assembly(ASM_NONE),
m_aes(has_aes_ni()),
m_avx2(has_avx2() && has_ossave()),
m_brand(),
@ -129,7 +128,6 @@ xmrig::BasicCpuInfo::BasicCpuInfo() :
{
cpu_brand_string(m_brand);
# ifndef XMRIG_NO_ASM
if (hasAES()) {
char vendor[13] = { 0 };
int32_t data[4] = { 0 };
@ -139,19 +137,11 @@ xmrig::BasicCpuInfo::BasicCpuInfo() :
memcpy(vendor + 0, &data[1], 4);
memcpy(vendor + 4, &data[3], 4);
memcpy(vendor + 8, &data[2], 4);
if (memcmp(vendor, "GenuineIntel", 12) == 0) {
m_assembly = ASM_INTEL;
}
else if (memcmp(vendor, "AuthenticAMD", 12) == 0) {
m_assembly = ASM_RYZEN;
}
}
# endif
}
size_t xmrig::BasicCpuInfo::optimalThreadsCount(size_t memSize, int maxCpuUsage) const
size_t xmrig::BasicCpuInfo::optimalThreadsCount(size_t memSize) const
{
const size_t count = threads() / 2;

View file

@ -38,9 +38,8 @@ public:
BasicCpuInfo();
protected:
size_t optimalThreadsCount(size_t memSize, int maxCpuUsage) const override;
size_t optimalThreadsCount(size_t memSize) const override;
inline Assembly assembly() const override { return m_assembly; }
inline bool hasAES() const override { return m_aes; }
inline bool hasAVX2() const override { return m_avx2; }
inline bool isSupported() const override { return true; }
@ -59,7 +58,6 @@ protected:
# endif
private:
Assembly m_assembly;
bool m_aes;
bool m_avx2;
char m_brand[64];

View file

@ -52,7 +52,7 @@ xmrig::BasicCpuInfo::BasicCpuInfo() :
}
size_t xmrig::BasicCpuInfo::optimalThreadsCount(size_t memSize, int maxCpuUsage) const
size_t xmrig::BasicCpuInfo::optimalThreadsCount(size_t memSize) const
{
return threads();
}

View file

@ -26,8 +26,6 @@
#include <assert.h>
#include <string.h>
#include <stdlib.h>
#include <stdio.h>
#include "common/crypto/Algorithm.h"
@ -54,52 +52,10 @@ struct AlgoData
static AlgoData const algorithms[] = {
{ "cryptonight", "cn", xmrig::CRYPTONIGHT, xmrig::VARIANT_AUTO },
{ "cryptonight/0", "cn/0", xmrig::CRYPTONIGHT, xmrig::VARIANT_0 },
{ "cryptonight/1", "cn/1", xmrig::CRYPTONIGHT, xmrig::VARIANT_1 },
{ "cryptonight/xtl", "cn/xtl", xmrig::CRYPTONIGHT, xmrig::VARIANT_XTL },
{ "cryptonight/msr", "cn/msr", xmrig::CRYPTONIGHT, xmrig::VARIANT_MSR },
{ "cryptonight/xao", "cn/xao", xmrig::CRYPTONIGHT, xmrig::VARIANT_XAO },
{ "cryptonight/rto", "cn/rto", xmrig::CRYPTONIGHT, xmrig::VARIANT_RTO },
{ "cryptonight/2", "cn/2", xmrig::CRYPTONIGHT, xmrig::VARIANT_2 },
{ "cryptonight/half", "cn/half", xmrig::CRYPTONIGHT, xmrig::VARIANT_HALF },
{ "cryptonight/xtlv9", "cn/xtlv9", xmrig::CRYPTONIGHT, xmrig::VARIANT_HALF },
{ "cryptonight/wow", "cn/wow", xmrig::CRYPTONIGHT, xmrig::VARIANT_WOW },
{ "cryptonight/r", "cn/r", xmrig::CRYPTONIGHT, xmrig::VARIANT_4 },
{ "cryptonight/rwz", "cn/rwz", xmrig::CRYPTONIGHT, xmrig::VARIANT_RWZ },
{ "cryptonight/zls", "cn/zls", xmrig::CRYPTONIGHT, xmrig::VARIANT_ZLS },
{ "cryptonight/double", "cn/double", xmrig::CRYPTONIGHT, xmrig::VARIANT_DOUBLE },
# ifndef XMRIG_NO_AEON
{ "cryptonight-lite", "cn-lite", xmrig::CRYPTONIGHT_LITE, xmrig::VARIANT_AUTO },
{ "cryptonight-light", "cn-light", xmrig::CRYPTONIGHT_LITE, xmrig::VARIANT_AUTO },
{ "cryptonight-lite/0", "cn-lite/0", xmrig::CRYPTONIGHT_LITE, xmrig::VARIANT_0 },
{ "cryptonight-lite/1", "cn-lite/1", xmrig::CRYPTONIGHT_LITE, xmrig::VARIANT_1 },
# endif
# ifndef XMRIG_NO_SUMO
{ "cryptonight-heavy", "cn-heavy", xmrig::CRYPTONIGHT_HEAVY, xmrig::VARIANT_AUTO },
{ "cryptonight-heavy/0", "cn-heavy/0", xmrig::CRYPTONIGHT_HEAVY, xmrig::VARIANT_0 },
{ "cryptonight-heavy/xhv", "cn-heavy/xhv", xmrig::CRYPTONIGHT_HEAVY, xmrig::VARIANT_XHV },
{ "cryptonight-heavy/tube", "cn-heavy/tube", xmrig::CRYPTONIGHT_HEAVY, xmrig::VARIANT_TUBE },
# endif
# ifndef XMRIG_NO_CN_PICO
{ "cryptonight-pico/trtl", "cn-pico/trtl", xmrig::CRYPTONIGHT_PICO, xmrig::VARIANT_TRTL },
{ "cryptonight-pico", "cn-pico", xmrig::CRYPTONIGHT_PICO, xmrig::VARIANT_TRTL },
{ "cryptonight-turtle", "cn-trtl", xmrig::CRYPTONIGHT_PICO, xmrig::VARIANT_TRTL },
{ "cryptonight-ultralite", "cn-ultralite", xmrig::CRYPTONIGHT_PICO, xmrig::VARIANT_TRTL },
{ "cryptonight_turtle", "cn_turtle", xmrig::CRYPTONIGHT_PICO, xmrig::VARIANT_TRTL },
# endif
# ifndef XMRIG_NO_ARGON2
{ "chukwa", "trtl-chukwa", xmrig::ARGON2, xmrig::VARIANT_CHUKWA },
// { "argon2/trtl", "trtl-chukwa", xmrig::ARGON2, xmrig::VARIANT_CHUKWA },
{ "chukwa/wrkz", "wrkz-chukwa", xmrig::ARGON2, xmrig::VARIANT_CHUKWA_LITE },
# endif
# ifndef XMRIG_NO_CN_GPU
{ "cryptonight/gpu", "cn/gpu", xmrig::CRYPTONIGHT, xmrig::VARIANT_GPU },
# endif
{ "argon2/wrkz", "wrkz-chukwa", xmrig::ARGON2, xmrig::VARIANT_CHUKWA_LITE },
};
@ -127,23 +83,6 @@ static AlgoData const xmrStakAlgorithms[] = {
static const char *variants[] = {
"0",
"1",
"tube",
"xtl",
"msr",
"xhv",
"xao",
"rto",
"2",
"half",
"trtl",
"gpu",
"wow",
"r",
"rwz",
"zls",
"double",
"chukwa",
"wrkz",
};
@ -177,7 +116,6 @@ const char *xmrig::Algorithm::variantName() const
return variants[m_variant];
}
void xmrig::Algorithm::parseAlgorithm(const char *algo)
{
m_algo = INVALID_ALGO;
@ -228,41 +166,20 @@ void xmrig::Algorithm::parseVariant(const char *variant)
return;
}
}
if (strcasecmp(variant, "xtlv9") == 0) {
m_variant = VARIANT_HALF;
}
}
void xmrig::Algorithm::parseVariant(int variant)
{
assert(variant >= -1 && variant <= 2);
assert(variant >= VARIANT_AUTO && variant < VARIANT_MAX);
switch (variant) {
case -1:
case 0:
case 1:
m_variant = static_cast<Variant>(variant);
break;
case 2:
m_variant = VARIANT_2;
break;
default:
break;
}
}
void xmrig::Algorithm::setAlgo(Algo algo)
{
m_algo = algo;
if (m_algo == CRYPTONIGHT_PICO && m_variant == VARIANT_AUTO) {
m_variant = xmrig::VARIANT_TRTL;
}
}

View file

@ -71,33 +71,20 @@ public:
AutoSaveKey = 1016,
// xmrig common
CPUPriorityKey = 1021,
PriorityKey = 1021,
NicehashKey = 1006,
PrintTimeKey = 1007,
// xmrig cpu
AVKey = 'v',
CPUThreadsKey = 't',
CPUOptimizationKey = 5004,
CPUAffinityKey = 1020,
DryRunKey = 5000,
HugePagesKey = 1009,
MaxCPUUsageKey = 1004,
SafeKey = 1005,
ThreadsKey = 't',
HardwareAESKey = 1011,
AssemblyKey = 1015,
// xmrig amd
OclPlatformKey = 1400,
OclAffinityKey = 1401,
OclDevicesKey = 1402,
OclLaunchKey = 1403,
OclCacheKey = 1404,
OclPrintKey = 1405,
OclLoaderKey = 1406,
OclSridedIndexKey = 1407,
OclMemChunkKey = 1408,
OclUnrollKey = 1409,
OclCompModeKey = 1410,
// ninjarig gpu
UseGPUKey = 5001,
GPUIntensityKey = 5002,
GPUFilterKey = 5003,
// xmrig-proxy
AccessLogFileKey = 'A',
@ -117,15 +104,6 @@ public:
TlsCiphersKey = 1112,
TlsCipherSuitesKey = 1113,
TlsProtocolsKey = 1114,
// xmrig nvidia
CudaMaxThreadsKey = 1200,
CudaBFactorKey = 1201,
CudaBSleepKey = 1202,
CudaDevicesKey = 1203,
CudaLaunchKey = 1204,
CudaAffinityKey = 1205,
CudaMaxUsageKey = 1206,
};
virtual ~IConfig() = default;

View file

@ -52,8 +52,7 @@ public:
virtual int32_t nodes() const = 0;
virtual int32_t sockets() const = 0;
virtual int32_t threads() const = 0;
virtual size_t optimalThreadsCount(size_t memSize, int maxCpuUsage) const = 0;
virtual xmrig::Assembly assembly() const = 0;
virtual size_t optimalThreadsCount(size_t memSize) const = 0;
};

View file

@ -230,19 +230,5 @@ char *xmrig::Job::toHex(const unsigned char* in, unsigned int len)
xmrig::Variant xmrig::Job::variant() const
{
switch (m_algorithm.algo()) {
case CRYPTONIGHT:
return (m_blob[0] >= 10) ? VARIANT_4 : ((m_blob[0] >= 8) ? VARIANT_2 : VARIANT_1);
case CRYPTONIGHT_LITE:
return VARIANT_1;
case CRYPTONIGHT_HEAVY:
return VARIANT_0;
default:
break;
}
return m_algorithm.variant();
}

View file

@ -25,100 +25,22 @@
#ifndef XMRIG_XMRIG_H
#define XMRIG_XMRIG_H
namespace xmrig
{
enum Algo {
INVALID_ALGO = -1,
CRYPTONIGHT, /* CryptoNight (2 MB) */
CRYPTONIGHT_LITE, /* CryptoNight (1 MB) */
CRYPTONIGHT_HEAVY, /* CryptoNight (4 MB) */
CRYPTONIGHT_PICO, /* CryptoNight (256 KB) */
ARGON2, /* Argon2 */
ALGO_MAX
};
//--av=1 For CPUs with hardware AES.
//--av=2 Lower power mode (double hash) of 1.
//--av=3 Software AES implementation.
//--av=4 Lower power mode (double hash) of 3.
enum AlgoVariant {
AV_AUTO, // --av=0 Automatic mode.
AV_SINGLE, // --av=1 Single hash mode
AV_DOUBLE, // --av=2 Double hash mode
AV_SINGLE_SOFT, // --av=3 Single hash mode (Software AES)
AV_DOUBLE_SOFT, // --av=4 Double hash mode (Software AES)
AV_TRIPLE, // --av=5 Triple hash mode
AV_QUAD, // --av=6 Quard hash mode
AV_PENTA, // --av=7 Penta hash mode
AV_TRIPLE_SOFT, // --av=8 Triple hash mode (Software AES)
AV_QUAD_SOFT, // --av=9 Quard hash mode (Software AES)
AV_PENTA_SOFT, // --av=10 Penta hash mode (Software AES)
AV_MAX
};
enum Variant {
VARIANT_AUTO = -1, // Autodetect
VARIANT_0 = 0, // Original CryptoNight or CryptoNight-Heavy
VARIANT_1 = 1, // CryptoNight variant 1 also known as Monero7 and CryptoNightV7
VARIANT_TUBE = 2, // Modified CryptoNight-Heavy (TUBE only)
VARIANT_XTL = 3, // Modified CryptoNight variant 1 (Stellite only)
VARIANT_MSR = 4, // Modified CryptoNight variant 1 (Masari only)
VARIANT_XHV = 5, // Modified CryptoNight-Heavy (Haven Protocol only)
VARIANT_XAO = 6, // Modified CryptoNight variant 0 (Alloy only)
VARIANT_RTO = 7, // Modified CryptoNight variant 1 (Arto only)
VARIANT_2 = 8, // CryptoNight variant 2
VARIANT_HALF = 9, // CryptoNight variant 2 with half iterations (Masari/Stellite)
VARIANT_TRTL = 10, // CryptoNight Turtle (TRTL)
VARIANT_GPU = 11, // CryptoNight-GPU (Ryo)
VARIANT_WOW = 12, // CryptoNightR (Wownero)
VARIANT_4 = 13, // CryptoNightR (Monero's variant 4)
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_CHUKWA = 17, // Argon2 Chukwa for TurtleCoin
VARIANT_CHUKWA_LITE = 18, // Argon2 Chukwa Lite for WrkzCoin
VARIANT_CHUKWA = 0, // Argon2 Chukwa for TurtleCoin
VARIANT_CHUKWA_LITE = 1, // Argon2 Chukwa Lite for WrkzCoin
VARIANT_MAX
};
enum AlgoVerify {
VERIFY_HW_AES = 1,
VERIFY_SOFT_AES = 2
};
enum AesMode {
AES_AUTO,
AES_HW,
AES_SOFT
};
enum OclVendor {
OCL_VENDOR_UNKNOWN = -2,
OCL_VENDOR_MANUAL = -1,
OCL_VENDOR_AMD = 0,
OCL_VENDOR_NVIDIA = 1,
OCL_VENDOR_INTEL = 2
};
enum Assembly {
ASM_NONE,
ASM_AUTO,
ASM_INTEL,
ASM_RYZEN,
ASM_BULLDOZER,
ASM_MAX
};
} /* namespace xmrig */
#endif /* XMRIG_XMRIG_H */

View file

@ -8,18 +8,16 @@
"ipv6": false,
"restricted": true
},
"asm": true,
"autosave": true,
"av": 0,
"background": false,
"colors": true,
"threads": "all",
"cpu-affinity": null,
"cpu-priority": null,
"use-gpu": "CUDA",
"gpu-intensity": 50,
"donate-level": 1,
"huge-pages": true,
"hw-aes": null,
"log-file": "./log.txt",
"max-cpu-usage": 95,
"pools": [
{
"url": "testnet.wrkz.work:5555",
@ -38,8 +36,6 @@
"retries": 5,
"retry-pause": 5,
"safe": false,
"threads": [
],
"user-agent": null,
"watch": true
}

View file

@ -27,32 +27,24 @@
#include <uv.h>
#include <inttypes.h>
#include "common/config/ConfigLoader.h"
#include "common/cpu/Cpu.h"
#include "core/Config.h"
#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"
#include "workers/CpuThread.h"
#include "HasherConfig.h"
static char affinity_tmp[20] = { 0 };
xmrig::Config::Config() : xmrig::CommonConfig(),
m_aesMode(AES_AUTO),
m_algoVariant(AV_AUTO),
m_assembly(ASM_AUTO),
m_hugePages(true),
m_safe(false),
m_shouldSave(false),
m_maxCpuUsage(100),
m_priority(-1)
m_priority(-1),
m_mask(-1)
{
}
@ -82,47 +74,31 @@ void xmrig::Config::getJSON(rapidjson::Document &doc) const
api.AddMember("restricted", isApiRestricted(), allocator);
doc.AddMember("api", api, allocator);
# ifndef XMRIG_NO_ASM
doc.AddMember("asm", Asm::toJSON(m_assembly), allocator);
# endif
doc.AddMember("autosave", isAutoSave(), allocator);
doc.AddMember("av", algoVariant(), allocator);
doc.AddMember("background", isBackground(), allocator);
doc.AddMember("colors", isColors(), allocator);
if (affinity() != -1L) {
snprintf(affinity_tmp, sizeof(affinity_tmp) - 1, "0x%" PRIX64, affinity());
doc.AddMember("cpu-threads", cpuThreads(), allocator);
if(cpuOptimization().isNull() || cpuOptimization().isEmpty())
doc.AddMember("cpu-optimization", kNullType, allocator);
else
doc.AddMember("cpu-optimization", StringRef(cpuOptimization().data()), allocator);
if (cpuAffinity() != -1L) {
snprintf(affinity_tmp, sizeof(affinity_tmp) - 1, "0x%" PRIX64, cpuAffinity());
doc.AddMember("cpu-affinity", StringRef(affinity_tmp), allocator);
}
else {
doc.AddMember("cpu-affinity", kNullType, allocator);
}
doc.AddMember("cpu-priority", priority() != -1 ? Value(priority()) : Value(kNullType), allocator);
doc.AddMember("priority", priority() != -1 ? Value(priority()) : Value(kNullType), allocator);
doc.AddMember("donate-level", donateLevel(), allocator);
doc.AddMember("huge-pages", isHugePages(), allocator);
doc.AddMember("hw-aes", m_aesMode == AES_AUTO ? Value(kNullType) : Value(m_aesMode == AES_HW), allocator);
doc.AddMember("log-file", logFile() ? Value(StringRef(logFile())).Move() : Value(kNullType).Move(), allocator);
doc.AddMember("max-cpu-usage", m_maxCpuUsage, allocator);
doc.AddMember("pools", m_pools.toJSON(doc), allocator);
doc.AddMember("print-time", printTime(), allocator);
doc.AddMember("retries", m_pools.retries(), allocator);
doc.AddMember("retry-pause", m_pools.retryPause(), allocator);
doc.AddMember("safe", m_safe, allocator);
if (threadsMode() != Simple) {
Value threads(kArrayType);
for (const IThread *thread : m_threads.list) {
threads.PushBack(thread->toConfig(doc), allocator);
}
doc.AddMember("threads", threads, allocator);
}
else {
doc.AddMember("threads", threadsCount(), allocator);
}
doc.AddMember("user-agent", userAgent() ? Value(StringRef(userAgent())).Move() : Value(kNullType).Move(), allocator);
@ -131,6 +107,30 @@ void xmrig::Config::getJSON(rapidjson::Document &doc) const
# endif
doc.AddMember("watch", m_watch, allocator);
Value gpuEngines(kArrayType);
for (const String gpuEngine : m_gpuEngine) {
gpuEngines.PushBack(gpuEngine.toJSON(doc), allocator);
}
doc.AddMember("use-gpu", gpuEngines, allocator);
Value gpuIntensities(kArrayType);
for (const double gpuIntensity : m_gpuIntensity) {
gpuIntensities.PushBack(gpuIntensity, allocator);
}
doc.AddMember("gpu-intensity", gpuIntensities, allocator);
Value gpuFilters(kArrayType);
for (const GPUFilter gpuFilter : m_gpuFilter) {
gpuFilters.PushBack(toGPUFilterConfig(gpuFilter, doc), allocator);
}
doc.AddMember("gpu-filter", gpuFilters, allocator);
}
@ -150,46 +150,20 @@ bool xmrig::Config::finalize()
return false;
}
if (!m_threads.cpu.empty()) {
m_threads.mode = Advanced;
const bool softAES = (m_aesMode == AES_AUTO ? (Cpu::info()->hasAES() ? AES_HW : AES_SOFT) : m_aesMode) == AES_SOFT;
if(m_gpuIntensity.size() == 0)
m_gpuIntensity.push_back(50);
for (size_t i = 0; i < m_threads.cpu.size(); ++i) {
m_threads.list.push_back(CpuThread::createFromData(i, m_algorithm.algo(), m_threads.cpu[i], m_priority, softAES));
}
HasherConfig hasherConfig(m_algorithm.algo(), m_algorithm.variant(), m_priority, m_cpuThreads, m_mask, m_cpuOptimization.isNull() ? "" : m_cpuOptimization.data(), m_gpuIntensity, m_gpuFilter);
return true;
}
if(m_cpuThreads > 0)
m_hashers.push_back(hasherConfig.clone(m_hashers.size(), "CPU"));
const AlgoVariant av = getAlgoVariant();
m_threads.mode = m_threads.count ? Simple : Automatic;
if(m_gpuEngine.size() > 0)
for(String gpuEngine : m_gpuEngine)
m_hashers.push_back(hasherConfig.clone(m_hashers.size(), gpuEngine.data()));
size_t size;
m_shouldSave = true;
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);
}
else if (m_safe) {
const size_t count = Cpu::info()->optimalThreadsCount(size, m_maxCpuUsage);
if (m_threads.count > count) {
m_threads.count = count;
}
}
for (size_t i = 0; i < m_threads.count; ++i) {
m_threads.list.push_back(CpuThread::createFromAV(i, m_algorithm.algo(), av, m_threads.mask, m_priority, m_assembly));
}
m_shouldSave = m_threads.mode == Automatic;
return true;
}
@ -200,29 +174,6 @@ bool xmrig::Config::parseBoolean(int key, bool enable)
return false;
}
switch (key) {
case SafeKey: /* --safe */
m_safe = enable;
break;
case HugePagesKey: /* --no-huge-pages */
m_hugePages = enable;
break;
case HardwareAESKey: /* hw-aes config only */
m_aesMode = enable ? AES_HW : AES_SOFT;
break;
# ifndef XMRIG_NO_ASM
case AssemblyKey:
m_assembly = Asm::parse(enable);
break;
# endif
default:
break;
}
return true;
}
@ -234,36 +185,92 @@ bool xmrig::Config::parseString(int key, const char *arg)
}
switch (key) {
case AVKey: /* --av */
case MaxCPUUsageKey: /* --max-cpu-usage */
case CPUPriorityKey: /* --cpu-priority */
case PriorityKey: /* --cpu-priority */
return parseUint64(key, strtol(arg, nullptr, 10));
case SafeKey: /* --safe */
return parseBoolean(key, true);
case HugePagesKey: /* --no-huge-pages */
return parseBoolean(key, false);
case ThreadsKey: /* --threads */
case CPUThreadsKey: /* --threads */
if (strncmp(arg, "all", 3) == 0) {
m_threads.count = Cpu::info()->threads();
m_cpuThreads = Cpu::info()->threads();
return true;
}
return parseUint64(key, strtol(arg, nullptr, 10));
case CPUOptimizationKey:
{
String value = arg;
if(value.isEqual("REF", true))
value = "REF";
else if(value.isEqual("SSE2", true))
value = "SSE2";
else if(value.isEqual("SSSE3", true))
value = "SSSE3";
else if(value.isEqual("AVX", true))
value = "AVX";
else if(value.isEqual("AVX2", true))
value = "AVX2";
else if(value.isEqual("AVX512F", true))
value = "AVX512F";
else if(value.isEqual("NEON", true))
value = "NEON";
else {
printf("Invalid CPU optimization %s.\n", arg);
return false;
}
m_cpuOptimization = value;
return true;
}
case CPUAffinityKey: /* --cpu-affinity */
{
const char *p = strstr(arg, "0x");
return parseUint64(key, p ? strtoull(p, nullptr, 16) : strtoull(arg, nullptr, 10));
}
# ifndef XMRIG_NO_ASM
case AssemblyKey: /* --asm */
m_assembly = Asm::parse(arg);
break;
# endif
case UseGPUKey:
{
String strArg = arg;
std::vector<String> gpuEngines = strArg.split(',');
m_gpuEngine.clear();
for(String engine : gpuEngines) {
if(engine.isEqual("OPENCL", true))
m_gpuEngine.push_back("OPENCL");
else if(engine.isEqual("CUDA", true))
m_gpuEngine.push_back("CUDA");
else {
printf("Invalid GPU hasher %s, ignoring.\n", engine.data());
}
}
return m_gpuEngine.size() > 0;
}
case GPUIntensityKey:
{
String strArg = arg;
std::vector<String> gpuIntensities = strArg.split(',');
for (const String intensity : gpuIntensities) {
double value = strtod(intensity.data(), NULL);
if(value > 100) value = 100;
if(value < 0) value = 0;
m_gpuIntensity.push_back(value);
}
return true;
}
case GPUFilterKey:
{
String strArg = arg;
std::vector<String> gpuFilters = strArg.split(',');
for (const String filter : gpuFilters) {
std::vector<String> explodedFilter = filter.split(':');
if(explodedFilter.size() == 1)
m_gpuFilter.push_back(GPUFilter("", explodedFilter[0].data()));
else if(explodedFilter.size() >= 2)
m_gpuFilter.push_back(GPUFilter(explodedFilter[0].data(), explodedFilter[1].data()));
}
return true;
}
default:
break;
@ -282,7 +289,7 @@ bool xmrig::Config::parseUint64(int key, uint64_t arg)
switch (key) {
case CPUAffinityKey: /* --cpu-affinity */
if (arg) {
m_threads.mask = arg;
m_mask = arg;
}
break;
@ -298,22 +305,91 @@ void xmrig::Config::parseJSON(const rapidjson::Document &doc)
{
CommonConfig::parseJSON(doc);
const rapidjson::Value &threads = doc["threads"];
const rapidjson::Value &threads = doc["cpu-threads"];
if (threads.IsArray()) {
for (const rapidjson::Value &value : threads.GetArray()) {
if (!value.IsObject()) {
if (threads.IsUint())
m_cpuThreads = threads.GetUint();
else if(threads.IsString() && strcasecmp(threads.GetString(), "all") == 0)
m_cpuThreads = Cpu::info()->threads();
const rapidjson::Value &cpuOptimization = doc["cpu-optimization"];
if (cpuOptimization.IsString()) {
String value = cpuOptimization.GetString();
if(value.isEqual("REF", true))
value = "REF";
else if(value.isEqual("SSE2", true))
value = "SSE2";
else if(value.isEqual("SSSE3", true))
value = "SSSE3";
else if(value.isEqual("AVX", true))
value = "AVX";
else if(value.isEqual("AVX2", true))
value = "AVX2";
else if(value.isEqual("AVX512F", true))
value = "AVX512F";
else if(value.isEqual("NEON", true))
value = "NEON";
else {
printf("Invalid CPU optimization %s, ignoring.\n", value.data());
value = "";
}
if(!value.isEqual(""))
m_cpuOptimization = value;
}
const rapidjson::Value &gpuEngines = doc["use-gpu"];
if(gpuEngines.IsArray()) {
m_gpuEngine.clear();
for(const rapidjson::Value &value : gpuEngines.GetArray()) {
if(!value.IsString()) {
continue;
}
if (value.HasMember("low_power_mode")) {
auto data = CpuThread::parse(value);
if (data.valid) {
m_threads.cpu.push_back(std::move(data));
String engine = value.GetString();
if(engine.isEqual("OPENCL", true))
m_gpuEngine.push_back("OPENCL");
else if(engine.isEqual("CUDA", true))
m_gpuEngine.push_back("CUDA");
else {
printf("Invalid GPU hasher %s, ignoring.\n", engine.data());
}
}
}
const rapidjson::Value &gpuIntensities = doc["gpu-intensity"];
if(gpuIntensities.IsArray()) {
for(const rapidjson::Value &value : gpuIntensities.GetArray()) {
if(!value.IsDouble()) {
continue;
}
double intensity = value.GetDouble();
if(intensity > 100) intensity = 100;
if(intensity < 0) intensity = 0;
m_gpuIntensity.push_back(intensity);
}
}
const rapidjson::Value &gpuFilters = doc["gpu-filter"];
if(gpuFilters.IsArray()) {
for(const rapidjson::Value &value : gpuFilters.GetArray()) {
if(!value.IsObject()) {
continue;
}
if(value.HasMember("filter")) {
auto data = parseGPUFilterConfig(value);
m_gpuFilter.push_back(data);
}
}
}
}
@ -321,25 +397,13 @@ void xmrig::Config::parseJSON(const rapidjson::Document &doc)
bool xmrig::Config::parseInt(int key, int arg)
{
switch (key) {
case ThreadsKey: /* --threads */
case CPUThreadsKey: /* --threads */
if (arg >= 0 && arg < 1024) {
m_threads.count = arg;
m_cpuThreads = arg;
}
break;
case AVKey: /* --av */
if (arg >= AV_AUTO && arg < AV_MAX) {
m_algoVariant = static_cast<AlgoVariant>(arg);
}
break;
case MaxCPUUsageKey: /* --max-cpu-usage */
if (m_maxCpuUsage > 0 && arg <= 100) {
m_maxCpuUsage = arg;
}
break;
case CPUPriorityKey: /* --cpu-priority */
case PriorityKey: /* --cpu-priority */
if (arg >= 0 && arg <= 5) {
m_priority = arg;
}
@ -351,39 +415,3 @@ bool xmrig::Config::parseInt(int key, int arg)
return true;
}
xmrig::AlgoVariant xmrig::Config::getAlgoVariant() const
{
# ifndef XMRIG_NO_AEON
if (m_algorithm.algo() == xmrig::CRYPTONIGHT_LITE) {
return getAlgoVariantLite();
}
# endif
if (m_algoVariant <= AV_AUTO || m_algoVariant >= AV_MAX) {
return Cpu::info()->hasAES() ? AV_SINGLE : AV_SINGLE_SOFT;
}
if (m_safe && !Cpu::info()->hasAES() && m_algoVariant <= AV_DOUBLE) {
return static_cast<AlgoVariant>(m_algoVariant + 2);
}
return m_algoVariant;
}
#ifndef XMRIG_NO_AEON
xmrig::AlgoVariant xmrig::Config::getAlgoVariantLite() const
{
if (m_algoVariant <= AV_AUTO || m_algoVariant >= AV_MAX) {
return Cpu::info()->hasAES() ? AV_DOUBLE : AV_DOUBLE_SOFT;
}
if (m_safe && !Cpu::info()->hasAES() && m_algoVariant <= AV_DOUBLE) {
return static_cast<AlgoVariant>(m_algoVariant + 2);
}
return m_algoVariant;
}
#endif

View file

@ -28,18 +28,16 @@
#include <stdint.h>
#include <vector>
#include "common/config/CommonConfig.h"
#include "common/xmrig.h"
#include "rapidjson/fwd.h"
#include "workers/CpuThread.h"
#include "rapidjson/schema.h"
#include "HasherConfig.h"
namespace xmrig {
class ConfigLoader;
class IThread;
class IConfigListener;
class Process;
@ -58,29 +56,22 @@ class Process;
class Config : public CommonConfig
{
public:
enum ThreadsMode {
Automatic,
Simple,
Advanced
};
Config();
bool reload(const char *json);
void getJSON(rapidjson::Document &doc) const override;
inline AesMode aesMode() const { return m_aesMode; }
inline AlgoVariant algoVariant() const { return m_algoVariant; }
inline Assembly assembly() const { return m_assembly; }
inline bool isHugePages() const { return m_hugePages; }
inline bool isShouldSave() const { return m_shouldSave && isAutoSave(); }
inline const std::vector<IThread *> &threads() const { return m_threads.list; }
inline const std::vector<HasherConfig *> &hasherConfigs() const { return m_hashers; }
inline int priority() const { return m_priority; }
inline int threadsCount() const { return m_threads.list.size(); }
inline int64_t affinity() const { return m_threads.mask; }
inline ThreadsMode threadsMode() const { return m_threads.mode; }
inline int hashersCount() const { return m_hashers.size(); }
inline int cpuThreads() const { return m_cpuThreads; }
inline String cpuOptimization() const { return m_cpuOptimization; }
inline int64_t cpuAffinity() const { return m_mask; }
inline std::vector<String> gpuEngine() const { return m_gpuEngine; }
inline std::vector<double> gpuIntensity() const { return m_gpuIntensity; }
inline std::vector<GPUFilter> gpuFilter() const { return m_gpuFilter; }
static Config *load(Process *process, IConfigListener *listener);
@ -94,36 +85,42 @@ protected:
private:
bool parseInt(int key, int arg);
AlgoVariant getAlgoVariant() const;
# ifndef XMRIG_NO_AEON
AlgoVariant getAlgoVariantLite() const;
# endif
static rapidjson::Value toGPUFilterConfig(const GPUFilter &filter, rapidjson::Document &doc) {
using namespace rapidjson;
Value obj(kObjectType);
auto &allocator = doc.GetAllocator();
if(!filter.engine.empty() && filter.engine != "*")
obj.AddMember("engine", Value(filter.engine.data(), doc.GetAllocator()), allocator);
obj.AddMember("filter", Value(filter.filter.data(), doc.GetAllocator()), allocator);
return obj;
}
struct Threads
{
inline Threads() : mask(-1L), count(0), mode(Automatic) {}
static GPUFilter parseGPUFilterConfig(const rapidjson::Value &object) {
std::string engineInfo;
std::string filterInfo;
const auto &filter = object["filter"];
if (filter.IsString()) {
filterInfo = filter.GetString();
}
const auto &engine = object["engine"];
if (engine.IsString()) {
engineInfo = engine.GetString();
}
int64_t mask;
size_t count;
std::vector<CpuThread::Data> cpu;
std::vector<IThread *> list;
ThreadsMode mode;
};
AesMode m_aesMode;
AlgoVariant m_algoVariant;
Assembly m_assembly;
bool m_hugePages;
bool m_safe;
return GPUFilter(engineInfo, filterInfo);
}
bool m_shouldSave;
int m_maxCpuUsage;
int m_priority;
Threads m_threads;
int64_t m_mask;
int m_cpuThreads;
String m_cpuOptimization;
std::vector<String> m_gpuEngine;
std::vector<double> m_gpuIntensity;
std::vector<GPUFilter> m_gpuFilter;
std::vector<HasherConfig *> m_hashers;
};
} /* namespace xmrig */
#endif /* XMRIG_CONFIG_H */

View file

@ -33,7 +33,7 @@ namespace xmrig {
const static char *default_config =
R"===(
{
"algo": "cryptonight",
"algo": "argon2",
"api": {
"port": 0,
"access-token": null,
@ -42,16 +42,13 @@ R"===(
"ipv6": false,
"restricted": true
},
"asm": true,
"autosave": true,
"av": 0,
"background": false,
"colors": true,
"cpu-affinity": null,
"cpu-priority": null,
"donate-level": 5,
"huge-pages": true,
"hw-aes": null,
"log-file": null,
"max-cpu-usage": 100,
"pools": [

View file

@ -40,7 +40,7 @@
namespace xmrig {
static char const short_options[] = "a:c:kBp:Px:r:R:s:t:T:o:u:O:v:l:S";
static char const short_options[] = "a:c:Bp:Px:r:R:s:t:T:o:u:O:v:l:S";
static struct option const options[] = {
@ -51,28 +51,28 @@ static struct option const options[] = {
{ "api-id", 1, nullptr, xmrig::IConfig::ApiIdKey },
{ "api-ipv6", 0, nullptr, xmrig::IConfig::ApiIPv6Key },
{ "api-no-restricted", 0, nullptr, xmrig::IConfig::ApiRestrictedKey },
{ "av", 1, nullptr, xmrig::IConfig::AVKey },
{ "background", 0, nullptr, xmrig::IConfig::BackgroundKey },
{ "config", 1, nullptr, xmrig::IConfig::ConfigKey },
{ "cpu-threads", 1, nullptr, xmrig::IConfig::CPUThreadsKey },
{ "cpu-optimization", 1, nullptr, xmrig::IConfig::CPUOptimizationKey},
{ "cpu-affinity", 1, nullptr, xmrig::IConfig::CPUAffinityKey },
{ "cpu-priority", 1, nullptr, xmrig::IConfig::CPUPriorityKey },
{ "use-gpu", 1, nullptr, xmrig::IConfig::UseGPUKey },
{ "gpu-intensity", 1, nullptr, xmrig::IConfig::GPUIntensityKey },
{ "gpu-filter", 1, nullptr, xmrig::IConfig::GPUFilterKey },
{ "priority", 1, nullptr, xmrig::IConfig::PriorityKey },
{ "donate-level", 1, nullptr, xmrig::IConfig::DonateLevelKey },
{ "dry-run", 0, nullptr, xmrig::IConfig::DryRunKey },
{ "keepalive", 0, nullptr, xmrig::IConfig::KeepAliveKey },
{ "log-file", 1, nullptr, xmrig::IConfig::LogFileKey },
{ "max-cpu-usage", 1, nullptr, xmrig::IConfig::MaxCPUUsageKey },
{ "nicehash", 0, nullptr, xmrig::IConfig::NicehashKey },
{ "no-color", 0, nullptr, xmrig::IConfig::ColorKey },
{ "no-watch", 0, nullptr, xmrig::IConfig::WatchKey },
{ "no-huge-pages", 0, nullptr, xmrig::IConfig::HugePagesKey },
{ "variant", 1, nullptr, xmrig::IConfig::VariantKey },
{ "pass", 1, nullptr, xmrig::IConfig::PasswordKey },
{ "print-time", 1, nullptr, xmrig::IConfig::PrintTimeKey },
{ "retries", 1, nullptr, xmrig::IConfig::RetriesKey },
{ "retry-pause", 1, nullptr, xmrig::IConfig::RetryPauseKey },
{ "safe", 0, nullptr, xmrig::IConfig::SafeKey },
{ "syslog", 0, nullptr, xmrig::IConfig::SyslogKey },
{ "threads", 1, nullptr, xmrig::IConfig::ThreadsKey },
{ "url", 1, nullptr, xmrig::IConfig::UrlKey },
{ "user", 1, nullptr, xmrig::IConfig::UserKey },
{ "user-agent", 1, nullptr, xmrig::IConfig::UserAgentKey },
@ -80,33 +80,30 @@ static struct option const options[] = {
{ "rig-id", 1, nullptr, xmrig::IConfig::RigIdKey },
{ "tls", 0, nullptr, xmrig::IConfig::TlsKey },
{ "tls-fingerprint", 1, nullptr, xmrig::IConfig::FingerprintKey },
{ "asm", 1, nullptr, xmrig::IConfig::AssemblyKey },
{ nullptr, 0, nullptr, 0 }
};
static struct option const config_options[] = {
{ "algo", 1, nullptr, xmrig::IConfig::AlgorithmKey },
{ "av", 1, nullptr, xmrig::IConfig::AVKey },
{ "background", 0, nullptr, xmrig::IConfig::BackgroundKey },
{ "colors", 0, nullptr, xmrig::IConfig::ColorKey },
{ "cpu-threads", 1, nullptr, xmrig::IConfig::CPUThreadsKey },
{ "cpu-optimization",1, nullptr, xmrig::IConfig::CPUOptimizationKey },
{ "cpu-affinity", 1, nullptr, xmrig::IConfig::CPUAffinityKey },
{ "cpu-priority", 1, nullptr, xmrig::IConfig::CPUPriorityKey },
{ "use-gpu", 1, nullptr, xmrig::IConfig::UseGPUKey },
{ "gpu-intensity", 1, nullptr, xmrig::IConfig::GPUIntensityKey},
{ "gpu-filter", 1, nullptr, xmrig::IConfig::GPUFilterKey },
{ "priority", 1, nullptr, xmrig::IConfig::PriorityKey },
{ "donate-level", 1, nullptr, xmrig::IConfig::DonateLevelKey },
{ "dry-run", 0, nullptr, xmrig::IConfig::DryRunKey },
{ "huge-pages", 0, nullptr, xmrig::IConfig::HugePagesKey },
{ "log-file", 1, nullptr, xmrig::IConfig::LogFileKey },
{ "max-cpu-usage", 1, nullptr, xmrig::IConfig::MaxCPUUsageKey },
{ "print-time", 1, nullptr, xmrig::IConfig::PrintTimeKey },
{ "retries", 1, nullptr, xmrig::IConfig::RetriesKey },
{ "retry-pause", 1, nullptr, xmrig::IConfig::RetryPauseKey },
{ "safe", 0, nullptr, xmrig::IConfig::SafeKey },
{ "syslog", 0, nullptr, xmrig::IConfig::SyslogKey },
{ "threads", 1, nullptr, xmrig::IConfig::ThreadsKey },
{ "user-agent", 1, nullptr, xmrig::IConfig::UserAgentKey },
{ "watch", 0, nullptr, xmrig::IConfig::WatchKey },
{ "hw-aes", 0, nullptr, xmrig::IConfig::HardwareAESKey },
{ "asm", 1, nullptr, xmrig::IConfig::AssemblyKey },
{ "autosave", 0, nullptr, xmrig::IConfig::AutoSaveKey },
{ nullptr, 0, nullptr, 0 }
};

112
src/core/HasherConfig.cpp Normal file
View file

@ -0,0 +1,112 @@
/* XMRig
* Copyright 2010 Jeff Garzik <jgarzik@pobox.com>
* Copyright 2012-2014 pooler <pooler@litecoinpool.org>
* Copyright 2014 Lucas Jones <https://github.com/lucasjones>
* Copyright 2014-2016 Wolf9466 <https://github.com/OhGodAPet>
* Copyright 2016 Jay D Dee <jayddee246@gmail.com>
* Copyright 2017-2018 XMR-Stak <https://github.com/fireice-uk>, <https://github.com/psychocrypt>
* Copyright 2018-2019 SChernykh <https://github.com/SChernykh>
* Copyright 2016-2019 XMRig <https://github.com/xmrig>, <support@xmrig.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/>.
*/
#include <assert.h>
#include <string>
#include <vector>
#include <cstdint>
#include "crypto/argon2_hasher/common/DLLExport.h"
#include "HasherConfig.h"
int xmrig::HasherConfig::m_gpuCardsCount = 0;
xmrig::HasherConfig::HasherConfig(xmrig::Algo algorithm, xmrig::Variant variant, int priority, int cpuThreads,
int64_t cpuAffinity, std::string cpuOptimization,
std::vector<double> &gpuIntensity, std::vector<GPUFilter> &gpuFilter) :
m_index(-1),
m_type(""),
m_algorithm(algorithm),
m_variant(variant),
m_priority(priority),
m_cpuThreads(cpuThreads),
m_cpuAffinity(cpuAffinity),
m_cpuOptimization(cpuOptimization),
m_gpuIntensity(gpuIntensity),
m_gpuFilter(gpuFilter){
}
xmrig::HasherConfig::HasherConfig(int index, std::string type, xmrig::Algo algorithm, xmrig::Variant variant, int priority, int cpuThreads,
int64_t cpuAffinity, std::string cpuOptimization,
std::vector<double> &gpuIntensity, std::vector<GPUFilter> &gpuFilter) :
m_index(index),
m_type(type),
m_algorithm(algorithm),
m_variant(variant),
m_priority(priority),
m_cpuThreads(cpuThreads),
m_cpuAffinity(cpuAffinity),
m_cpuOptimization(cpuOptimization),
m_gpuIntensity(gpuIntensity) {
for(GPUFilter filter : gpuFilter) {
if(filter.engine.empty() || filter.engine == "*" || filter.engine == type) {
m_gpuFilter.push_back(filter);
}
}
}
double xmrig::HasherConfig::getGPUIntensity(int cardIndex) {
if(cardIndex < m_gpuIntensity.size())
return m_gpuIntensity[cardIndex];
else if(m_gpuIntensity.size() > 0)
return m_gpuIntensity[0];
else
return 50;
}
int64_t xmrig::HasherConfig::getCPUAffinity(int cpuIndex) {
int64_t cpuId = -1L;
if (m_cpuAffinity != -1L) {
size_t idx = 0;
for (size_t i = 0; i < 64; i++) {
if (!(m_cpuAffinity & (1ULL << i))) {
continue;
}
if (idx == cpuIndex) {
cpuId = i;
break;
}
idx++;
}
}
return cpuId;
}
xmrig::HasherConfig *xmrig::HasherConfig::clone(int index, std::string hasherType) {
return new HasherConfig(index, hasherType, m_algorithm, m_variant, m_priority, m_cpuThreads, m_cpuAffinity, m_cpuOptimization, m_gpuIntensity, m_gpuFilter);
}
double xmrig::HasherConfig::getAverageGPUIntensity() {
double result = 0;
for(double intensity : m_gpuIntensity) result += intensity;
return result / (m_gpuIntensity.size() > 0 ? m_gpuIntensity.size() : 1);
}

98
src/core/HasherConfig.h Normal file
View file

@ -0,0 +1,98 @@
/* XMRig
* Copyright 2010 Jeff Garzik <jgarzik@pobox.com>
* Copyright 2012-2014 pooler <pooler@litecoinpool.org>
* Copyright 2014 Lucas Jones <https://github.com/lucasjones>
* Copyright 2014-2016 Wolf9466 <https://github.com/OhGodAPet>
* Copyright 2016 Jay D Dee <jayddee246@gmail.com>
* Copyright 2017-2018 XMR-Stak <https://github.com/fireice-uk>, <https://github.com/psychocrypt>
* Copyright 2018-2019 SChernykh <https://github.com/SChernykh>
* Copyright 2016-2019 XMRig <https://github.com/xmrig>, <support@xmrig.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/>.
*/
#ifndef XMRIG_HASHERCONFIG_H
#define XMRIG_HASHERCONFIG_H
#include "common/xmrig.h"
#include "crypto/argon2_hasher/common/common.h"
namespace xmrig {
struct GPUFilter {
GPUFilter(std::string engine, std::string filter) : engine(engine), filter(filter) {}
std::string engine;
std::string filter;
};
class DLLEXPORT HasherConfig
{
public:
HasherConfig(Algo algorithm,
Variant variant,
int priority,
int cpuThreads,
int64_t cpuAffinity,
std::string cpuOptimization,
std::vector<double> &gpuIntensity,
std::vector<GPUFilter> &gpuFilter);
HasherConfig *clone(int index, std::string hasherType);
inline size_t index() const { return m_index; }
inline std::string type() const { return m_type; }
inline Algo algorithm() const { return m_algorithm; }
inline Variant variant() const { return m_variant; }
inline int priority() const { return m_priority; }
inline int cpuThreads() const { return m_cpuThreads; }
inline std::string cpuOptimization() const { return m_cpuOptimization; }
inline std::vector<GPUFilter> &gpuFilter() { return m_gpuFilter; }
double getAverageGPUIntensity();
double getGPUIntensity(int cardIndex);
int64_t getCPUAffinity(int cpuIndex);
inline void addGPUCardsCount(int count) { m_gpuCardsCount += count; }
inline int getGPUCardsCount() { return m_gpuCardsCount; }
private:
HasherConfig(int index,
std::string type,
Algo algorithm,
Variant variant,
int priority,
int cpuThreads,
int64_t cpuAffinity,
std::string cpuOptimization,
std::vector<double> &gpuIntensity,
std::vector<GPUFilter> &gpuFilter);
const size_t m_index;
const std::string m_type;
const Algo m_algorithm;
const Variant m_variant;
const int m_priority;
const int m_cpuThreads;
const int64_t m_cpuAffinity;
const std::string m_cpuOptimization;
std::vector<double> m_gpuIntensity;
std::vector<GPUFilter> m_gpuFilter;
static int m_gpuCardsCount;
};
} /* namespace xmrig */
#endif /*XMRIG_HASHERCONFIG_H*/

View file

@ -31,7 +31,6 @@
xmrig::AdvancedCpuInfo::AdvancedCpuInfo() :
m_assembly(ASM_NONE),
m_aes(false),
m_avx2(false),
m_L2_exclusive(false),
@ -76,20 +75,13 @@ xmrig::AdvancedCpuInfo::AdvancedCpuInfo() :
if (data.flags[CPU_FEATURE_AES]) {
m_aes = true;
if (data.vendor == VENDOR_AMD) {
m_assembly = (data.ext_family >= 23) ? ASM_RYZEN : ASM_BULLDOZER;
}
else if (data.vendor == VENDOR_INTEL) {
m_assembly = ASM_INTEL;
}
}
m_avx2 = data.flags[CPU_FEATURE_AVX2] && data.flags[CPU_FEATURE_OSXSAVE];
}
size_t xmrig::AdvancedCpuInfo::optimalThreadsCount(size_t memSize, int maxCpuUsage) const
size_t xmrig::AdvancedCpuInfo::optimalThreadsCount(size_t memSize) const
{
if (threads() == 1) {
return 1;
@ -120,9 +112,5 @@ size_t xmrig::AdvancedCpuInfo::optimalThreadsCount(size_t memSize, int maxCpuUsa
count = threads();
}
if (((float) count / threads() * 100) > maxCpuUsage) {
count = (int) ceil((float) threads() * (maxCpuUsage / 100.0));
}
return count < 1 ? 1 : count;
}

View file

@ -38,9 +38,8 @@ public:
AdvancedCpuInfo();
protected:
size_t optimalThreadsCount(size_t memSize, int maxCpuUsage) const override;
size_t optimalThreadsCount(size_t memSize) const override;
inline Assembly assembly() const override { return m_assembly; }
inline bool hasAES() const override { return m_aes; }
inline bool hasAVX2() const override { return m_avx2; }
inline bool isSupported() const override { return true; }
@ -59,7 +58,6 @@ protected:
# endif
private:
Assembly m_assembly;
bool m_aes;
bool m_avx2;
bool m_L2_exclusive;

View file

@ -36,32 +36,26 @@ static char const usage[] = "\
Usage: " APP_ID " [OPTIONS]\n\
Options:\n\
-a, --algo=ALGO specify the algorithm to use\n\
cryptonight\n"
#ifndef XMRIG_NO_AEON
"\
cryptonight-lite\n"
#endif
#ifndef XMRIG_NO_SUMO
"\
cryptonight-heavy\n"
#endif
"\
chukwa\n\
chukwa/wrkz\n\
-o, --url=URL URL of mining server\n\
-O, --userpass=U:P username:password pair for mining server\n\
-u, --user=USERNAME username for mining server\n\
-p, --pass=PASSWORD password for mining server\n\
--rig-id=ID rig identifier for pool-side statistics (needs pool support)\n\
-t, --threads=N number of miner threads\n\
-v, --av=N algorithm variation, 0 auto select\n\
-t, --cpu-threads=N number of cpu miner threads - use 0 to disable\n\
--cpu-affinity set process affinity to CPU core(s), mask 0x3 for cores 0 and 1\n\
--cpu-optimization=REF|SSE2|SSSE3|AVX|AVX2|AVX512F|NEON force specific optimization for cpu mining\n\
--use-gpu=CUDA,OPENCL gpu engine to use, ignore this param to disable gpu support\n\
--gpu-intensity=v1,v2... percent of gpu memory to use - you can have different values for each card (default 50)\n\
--gpu-filter=<filter1>,CUDA:<filter2>,OPENCL:<filter3> gpu filters to select cards\n\
-k, --keepalive send keepalived packet for prevent timeout (needs pool support)\n\
--nicehash enable nicehash.com support\n\
--tls enable SSL/TLS support (needs pool support)\n\
--tls-fingerprint=F pool TLS certificate fingerprint, if set enable strict certificate pinning\n\
-r, --retries=N number of times to retry before switch to backup server (default: 5)\n\
-R, --retry-pause=N time to pause between retries (default: 5)\n\
--cpu-affinity set process affinity to CPU core(s), mask 0x3 for cores 0 and 1\n\
--cpu-priority set process priority (0 idle, 2 normal to 5 highest)\n\
--no-huge-pages disable huge pages support\n\
--priority set process priority (0 idle, 2 normal to 5 highest)\n\
--no-color disable colored output\n\
--variant algorithm PoW variant\n\
--donate-level=N donate level, default 5%% (5 minutes in 100 minutes)\n\
@ -74,9 +68,6 @@ Options:\n\
-S, --syslog use system log for output messages\n"
# endif
"\
--max-cpu-usage=N maximum CPU usage for automatic threads mode (default 75)\n\
--safe safe adjust threads and av settings for current CPU\n\
--asm=ASM ASM code for cn/2, possible values: auto, none, intel, ryzen, bulldozer.\n\
--print-time=N print hashrate report every N seconds\n\
--api-port=N port for the miner API\n\
--api-access-token=T access token for API\n\

Some files were not shown because too many files have changed in this diff Show more