Added selection for optimized Argon2 implementation.

This commit is contained in:
XMRig 2019-08-17 01:42:03 +07:00
parent 1c00721de3
commit 3022f19eda
12 changed files with 258 additions and 77 deletions

View File

@ -2,7 +2,12 @@ if (WITH_ARGON2)
add_definitions(/DXMRIG_ALGO_ARGON2)
list(APPEND HEADERS_CRYPTO
src/crypto/argon2/Argon2.h
src/crypto/argon2/Hash.h
src/crypto/argon2/Impl.h
)
list(APPEND SOURCES_CRYPTO
src/crypto/argon2/Impl.cpp
)
add_subdirectory(src/3rdparty/argon2)

View File

@ -39,57 +39,54 @@ set_property(TARGET argon2 APPEND PROPERTY
COMPATIBLE_INTERFACE_STRING ARGON2_MAJOR_VERSION
)
#if (CMAKE_C_COMPILER_ID MATCHES MSVC)
if (CMAKE_C_COMPILER_ID MATCHES MSVC)
#elseif (NOT XMRIG_ARM AND CMAKE_SIZEOF_VOID_P EQUAL 8)
# function(add_feature_impl FEATURE GCC_FLAG DEF)
# add_library(argon2-${FEATURE} STATIC
# arch/x86_64/lib/argon2-${FEATURE}.c
# )
# target_link_libraries(argon2-${FEATURE} PRIVATE argon2-internal)
# set_target_properties(argon2-${FEATURE}
# PROPERTIES POSITION_INDEPENDENT_CODE True
# )
elseif (NOT XMRIG_ARM AND CMAKE_SIZEOF_VOID_P EQUAL 8)
function(add_feature_impl FEATURE GCC_FLAG DEF)
add_library(argon2-${FEATURE} STATIC arch/x86_64/lib/argon2-${FEATURE}.c)
target_link_libraries(argon2-${FEATURE} PRIVATE argon2-internal)
set_target_properties(argon2-${FEATURE} PROPERTIES POSITION_INDEPENDENT_CODE True)
# message("-- Detecting feature '${FEATURE}'...")
# file(READ arch/x86_64/src/test-feature-${FEATURE}.c SOURCE_CODE)
message("-- argon2: detecting feature '${FEATURE}'...")
file(READ arch/x86_64/src/test-feature-${FEATURE}.c SOURCE_CODE)
# # try without flag:
# check_c_source_compiles("${SOURCE_CODE}" FEATURE_${FEATURE}_NOFLAG)
# set(HAS_FEATURE ${FEATURE_${FEATURE}_NOFLAG})
# if(NOT "${HAS_FEATURE}")
# # try with -m<feature> flag:
# set(CMAKE_REQUIRED_FLAGS ${GCC_FLAG})
# check_c_source_compiles("${SOURCE_CODE}" FEATURE_${FEATURE}_FLAG)
# set(CMAKE_REQUIRED_FLAGS "")
# try without flag:
check_c_source_compiles("${SOURCE_CODE}" FEATURE_${FEATURE}_NOFLAG)
set(HAS_FEATURE ${FEATURE_${FEATURE}_NOFLAG})
if (NOT "${HAS_FEATURE}")
# try with -m<feature> flag:
set(CMAKE_REQUIRED_FLAGS ${GCC_FLAG})
check_c_source_compiles("${SOURCE_CODE}" FEATURE_${FEATURE}_FLAG)
set(CMAKE_REQUIRED_FLAGS "")
# set(HAS_FEATURE ${FEATURE_${FEATURE}_FLAG})
# if(${HAS_FEATURE})
# target_compile_options(argon2-${FEATURE} PRIVATE ${GCC_FLAG})
# endif()
# endif()
set(HAS_FEATURE ${FEATURE_${FEATURE}_FLAG})
if (${HAS_FEATURE})
target_compile_options(argon2-${FEATURE} PRIVATE ${GCC_FLAG})
endif()
endif()
# if(${HAS_FEATURE})
# message("-- Feature '${FEATURE}' detected!")
# target_compile_definitions(argon2-${FEATURE} PRIVATE ${DEF})
# endif()
# target_link_libraries(argon2 PUBLIC argon2-${FEATURE})
# endfunction()
if (${HAS_FEATURE})
message("-- argon2: feature '${FEATURE}' detected!")
target_compile_definitions(argon2-${FEATURE} PRIVATE ${DEF})
endif()
# target_include_directories(argon2-internal INTERFACE arch/x86_64/lib)
target_link_libraries(argon2 PUBLIC argon2-${FEATURE})
endfunction()
# add_feature_impl(sse2 -msse2 HAVE_SSE2)
# add_feature_impl(ssse3 -mssse3 HAVE_SSSE3)
# add_feature_impl(xop -mxop HAVE_XOP)
# add_feature_impl(avx2 -mavx2 HAVE_AVX2)
# add_feature_impl(avx512f -mavx512f HAVE_AVX512F)
target_include_directories(argon2-internal INTERFACE arch/x86_64/lib)
# target_sources(argon2 PRIVATE
# arch/x86_64/lib/argon2-arch.c
# arch/x86_64/lib/cpu-flags.c
# )
#else()
add_feature_impl(sse2 -msse2 HAVE_SSE2)
add_feature_impl(ssse3 -mssse3 HAVE_SSSE3)
add_feature_impl(xop -mxop HAVE_XOP)
add_feature_impl(avx2 -mavx2 HAVE_AVX2)
add_feature_impl(avx512f -mavx512f HAVE_AVX512F)
target_sources(argon2 PRIVATE
arch/x86_64/lib/argon2-arch.c
arch/x86_64/lib/cpu-flags.c
)
else()
target_sources(argon2 PRIVATE
arch/generic/lib/argon2-arch.c
)
#endif()
endif()

View File

@ -431,6 +431,8 @@ ARGON2_PUBLIC size_t argon2_encodedlen(uint32_t t_cost, uint32_t m_cost,
* string
*/
ARGON2_PUBLIC void argon2_select_impl(FILE *out, const char *prefix);
ARGON2_PUBLIC const char *argon2_get_impl_name();
ARGON2_PUBLIC int argon2_select_impl_by_name(const char *name);
/* signals support for passing preallocated memory: */
#define ARGON2_PREALLOCATED_MEMORY

View File

@ -16,7 +16,7 @@
#define BENCH_MEM_BLOCKS 512
static argon2_impl selected_argon_impl = {
"(default)", NULL, fill_segment_default
"default", NULL, fill_segment_default
};
/* the benchmark routine is not thread-safe, so we can use a global var here: */
@ -118,3 +118,29 @@ void argon2_select_impl(FILE *out, const char *prefix)
}
select_impl(out, prefix);
}
const char *argon2_get_impl_name()
{
return selected_argon_impl.name;
}
int argon2_select_impl_by_name(const char *name)
{
argon2_impl_list impls;
unsigned int i;
argon2_get_impl_list(&impls);
for (i = 0; i < impls.count; i++) {
const argon2_impl *impl = &impls.entries[i];
if (strcmp(impl->name, name) == 0) {
selected_argon_impl = *impl;
return 1;
}
}
return 0;
}

View File

@ -43,6 +43,11 @@
#include "rapidjson/document.h"
#ifdef XMRIG_ALGO_ARGON2
# include "crypto/argon2/Impl.h"
#endif
namespace xmrig {
@ -192,8 +197,17 @@ const xmrig::String &xmrig::CpuBackend::type() const
}
void xmrig::CpuBackend::prepare(const Job &)
void xmrig::CpuBackend::prepare(const Job &nextJob)
{
# ifdef XMRIG_ALGO_ARGON2
if (nextJob.algorithm().family() == Algorithm::ARGON2 && argon2::Impl::select(d_ptr->controller->config()->cpu().argon2Impl())) {
LOG_INFO("%s use " WHITE_BOLD("argon2") " implementation " CSI "1;%dm" "%s",
tag,
argon2::Impl::name() == "default" ? 33 : 32,
argon2::Impl::name().data()
);
}
# endif
}

View File

@ -62,6 +62,11 @@ static const char *kRx = "rx";
static const char *kRxWOW = "rx/wow";
#endif
#ifdef XMRIG_ALGO_ARGON2
static const char *kArgon2 = "argon2";
static const char *kArgon2Impl = "argon2-impl";
#endif
extern template class Threads<CpuThreads>;
}
@ -94,6 +99,10 @@ rapidjson::Value xmrig::CpuConfig::toJSON(rapidjson::Document &doc) const
obj.AddMember(StringRef(kAsm), m_assembly.toJSON(), allocator);
# endif
# ifdef XMRIG_ALGO_ARGON2
obj.AddMember(StringRef(kArgon2Impl), m_argon2Impl.toJSON(), allocator);
# endif
m_threads.toJSON(obj, doc);
return obj;
@ -132,6 +141,10 @@ void xmrig::CpuConfig::read(const rapidjson::Value &value)
m_assembly = Json::getValue(value, kAsm);
# endif
# ifdef XMRIG_ALGO_ARGON2
m_argon2Impl = Json::getString(value, kArgon2Impl);
# endif
if (!m_threads.read(value)) {
generate();
}

View File

@ -55,6 +55,7 @@ public:
inline bool isHugePages() const { return m_hugePages; }
inline bool isShouldSave() const { return m_shouldSave; }
inline const Assembly &assembly() const { return m_assembly; }
inline const String &argon2Impl() const { return m_argon2Impl; }
inline const Threads<CpuThreads> &threads() const { return m_threads; }
inline int priority() const { return m_priority; }
@ -70,6 +71,7 @@ private:
bool m_hugePages = true;
bool m_shouldSave = false;
int m_priority = -1;
String m_argon2Impl;
Threads<CpuThreads> m_threads;
};

View File

@ -22,9 +22,8 @@
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
#ifndef XMRIG_ARGON2_H
#define XMRIG_ARGON2_H
#ifndef XMRIG_ARGON2_HASH_H
#define XMRIG_ARGON2_HASH_H
#include "3rdparty/argon2.h"
@ -34,34 +33,22 @@
struct cryptonight_ctx;
namespace xmrig {
namespace xmrig { namespace argon2 {
template<Algorithm::Id ALGO>
inline void argon2_single_hash(const uint8_t *__restrict__ input, size_t size, uint8_t *__restrict__ output, cryptonight_ctx **__restrict__, uint64_t)
inline void single_hash(const uint8_t *__restrict__ input, size_t size, uint8_t *__restrict__ output, cryptonight_ctx **__restrict__, uint64_t)
{
// static bool argon_optimization_selected = false;
// if (!argon_optimization_selected) {
// argon2_select_impl(stdout, nullptr);
// argon_optimization_selected = true;
// }
uint8_t salt[16];
memcpy(salt, input, sizeof(salt));
if (ALGO == Algorithm::AR2_CHUKWA) {
argon2id_hash_raw(3, 512, 1, input, size, salt, 16, output, 32);
argon2id_hash_raw(3, 512, 1, input, size, input, 16, output, 32);
}
else if (ALGO == Algorithm::AR2_WRKZ) {
argon2id_hash_raw(4, 256, 1, input, size, salt, 16, output, 32);
argon2id_hash_raw(4, 256, 1, input, size, input, 16, output, 32);
}
}
} // namespace xmrig
}} // namespace xmrig::argon2
#endif /* XMRIG_ARGON2_H */
#endif /* XMRIG_ARGON2_HASH_H */

View File

@ -0,0 +1,62 @@
/* 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 "3rdparty/argon2.h"
#include "base/tools/String.h"
#include "crypto/argon2/Impl.h"
namespace xmrig {
static bool selected = false;
static String implName;
} // namespace xmrig
bool xmrig::argon2::Impl::select(const String &nameHint)
{
if (!selected) {
if (nameHint.isEmpty() || argon2_select_impl_by_name(nameHint) == 0) {
argon2_select_impl(nullptr, nullptr);
}
selected = true;
implName = argon2_get_impl_name();
return true;
}
return false;
}
const xmrig::String &xmrig::argon2::Impl::name()
{
return implName;
}

49
src/crypto/argon2/Impl.h Normal file
View File

@ -0,0 +1,49 @@
/* 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_ARGON2_IMPL_H
#define XMRIG_ARGON2_IMPL_H
namespace xmrig {
class String;
namespace argon2 {
class Impl
{
public:
static bool select(const String &nameHint);
static const String &name();
};
}} // namespace xmrig::argon2
#endif /* XMRIG_ARGON2_IMPL_H */

View File

@ -39,7 +39,7 @@
#ifdef XMRIG_ALGO_ARGON2
# include "crypto/argon2/Argon2.h"
# include "crypto/argon2/Hash.h"
#endif
@ -255,10 +255,10 @@ xmrig::CnHash::CnHash()
# endif
# ifdef XMRIG_ALGO_ARGON2
m_map[Algorithm::AR2_CHUKWA][AV_SINGLE][Assembly::NONE] = argon2_single_hash<Algorithm::AR2_CHUKWA>;
m_map[Algorithm::AR2_CHUKWA][AV_SINGLE_SOFT][Assembly::NONE] = argon2_single_hash<Algorithm::AR2_CHUKWA>;
m_map[Algorithm::AR2_WRKZ][AV_SINGLE][Assembly::NONE] = argon2_single_hash<Algorithm::AR2_WRKZ>;
m_map[Algorithm::AR2_WRKZ][AV_SINGLE_SOFT][Assembly::NONE] = argon2_single_hash<Algorithm::AR2_WRKZ>;
m_map[Algorithm::AR2_CHUKWA][AV_SINGLE][Assembly::NONE] = argon2::single_hash<Algorithm::AR2_CHUKWA>;
m_map[Algorithm::AR2_CHUKWA][AV_SINGLE_SOFT][Assembly::NONE] = argon2::single_hash<Algorithm::AR2_CHUKWA>;
m_map[Algorithm::AR2_WRKZ][AV_SINGLE][Assembly::NONE] = argon2::single_hash<Algorithm::AR2_WRKZ>;
m_map[Algorithm::AR2_WRKZ][AV_SINGLE_SOFT][Assembly::NONE] = argon2::single_hash<Algorithm::AR2_WRKZ>;
# endif
# ifdef XMRIG_FEATURE_ASM

View File

@ -358,24 +358,48 @@ const static uint8_t test_output_pico_trtl[160] = {
#ifdef XMRIG_ALGO_CN_GPU
// "cn/gpu"
const static uint8_t test_output_gpu[32] = {
const static uint8_t test_output_gpu[160] = {
0xE5, 0x5C, 0xB2, 0x3E, 0x51, 0x64, 0x9A, 0x59, 0xB1, 0x27, 0xB9, 0x6B, 0x51, 0x5F, 0x2B, 0xF7,
0xBF, 0xEA, 0x19, 0x97, 0x41, 0xA0, 0x21, 0x6C, 0xF8, 0x38, 0xDE, 0xD0, 0x6E, 0xFF, 0x82, 0xDF
0xBF, 0xEA, 0x19, 0x97, 0x41, 0xA0, 0x21, 0x6C, 0xF8, 0x38, 0xDE, 0xD0, 0x6E, 0xFF, 0x82, 0xDF,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
};
#endif
#ifdef XMRIG_ALGO_ARGON2
// "argon2/chukwa"
const static uint8_t argon2_chukwa_test_out[32] = {
const static uint8_t argon2_chukwa_test_out[160] = {
0xC1, 0x58, 0xA1, 0x05, 0xAE, 0x75, 0xC7, 0x56, 0x1C, 0xFD, 0x02, 0x90, 0x83, 0xA4, 0x7A, 0x87,
0x65, 0x3D, 0x51, 0xF9, 0x14, 0x12, 0x8E, 0x21, 0xC1, 0x97, 0x1D, 0x8B, 0x10, 0xC4, 0x90, 0x34
0x65, 0x3D, 0x51, 0xF9, 0x14, 0x12, 0x8E, 0x21, 0xC1, 0x97, 0x1D, 0x8B, 0x10, 0xC4, 0x90, 0x34,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
};
// "argon2/wrkz"
const static uint8_t argon2_wrkz_test_out[32] = {
const static uint8_t argon2_wrkz_test_out[160] = {
0x35, 0xE0, 0x83, 0xD4, 0xB9, 0xC6, 0x4C, 0x2A, 0x68, 0x82, 0x0A, 0x43, 0x1F, 0x61, 0x31, 0x19,
0x98, 0xA8, 0xCD, 0x18, 0x64, 0xDB, 0xA4, 0x07, 0x7E, 0x25, 0xB7, 0xF1, 0x21, 0xD5, 0x4B, 0xD1,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
};
#endif