XMRigCC 2.1.0 (#270)

* New XMRigCCServer without dependencies and now with full TLS support on Windows
* Dashboard
    * Added all columns to the dashboard
    * Dynamic table view (column visibility)
    * Grouping by Algo
    * GZIP compression for the whole traffic
* Full Rebase on XMRig 3.2.0 
    * Final randomX/0 (XMR)
    * Coin config
    * Bugfixes
This commit is contained in:
Ben Gräf 2019-10-24 19:44:38 +02:00 committed by GitHub
parent b395fe94f6
commit f7c3dd88ee
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
90 changed files with 9477 additions and 7371 deletions

View file

@ -1,23 +1,23 @@
cmake_minimum_required(VERSION 2.6)
cmake_minimum_required(VERSION 2.8)
project(Argon2 C)
set(ARGON2_VERSION 1.0)
project(argon2 C)
set(CMAKE_C_STANDARD 99)
set(CMAKE_C_STANDARD_REQUIRED ON)
include(CheckCSourceCompiles)
add_library(argon2 STATIC
set(ARGON2_SOURCES
lib/argon2.c
lib/core.c
lib/encoding.c
lib/genkat.c
lib/impl-select.c
lib/blake2/blake2.c
)
)
target_include_directories(argon2 PUBLIC ${CMAKE_CURRENT_SOURCE_DIR}/include)
target_include_directories(argon2 PRIVATE ${CMAKE_CURRENT_SOURCE_DIR}/lib)
set(ARGON2_X86_64_ENABLED ON)
set(ARGON2_X86_64_LIBS argon2-sse2 argon2-ssse3 argon2-xop argon2-avx2 argon2-avx512f)
set(ARGON2_X86_64_SOURCES arch/x86_64/lib/argon2-arch.c arch/x86_64/lib/cpu-flags.c)
if (CMAKE_C_COMPILER_ID MATCHES MSVC)
function(add_feature_impl FEATURE MSVC_FLAG DEF)
@ -28,7 +28,6 @@ if (CMAKE_C_COMPILER_ID MATCHES MSVC)
target_compile_options(argon2-${FEATURE} PRIVATE ${MSVC_FLAG})
target_compile_definitions(argon2-${FEATURE} PRIVATE ${DEF})
target_link_libraries(argon2 PUBLIC argon2-${FEATURE})
endfunction()
add_feature_impl(sse2 "" HAVE_SSE2)
@ -36,8 +35,6 @@ if (CMAKE_C_COMPILER_ID MATCHES MSVC)
add_feature_impl(xop "" HAVE_XOP)
add_feature_impl(avx2 "/arch:AVX2" HAVE_AVX2)
add_feature_impl(avx512f "/arch:AVX512F" HAVE_AVX512F)
target_sources(argon2 PRIVATE arch/x86_64/lib/argon2-arch.c arch/x86_64/lib/cpu-flags.c)
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)
@ -67,8 +64,6 @@ elseif (NOT XMRIG_ARM AND CMAKE_SIZEOF_VOID_P EQUAL 8)
message("-- argon2: feature '${FEATURE}' detected!")
target_compile_definitions(argon2-${FEATURE} PRIVATE ${DEF})
endif()
target_link_libraries(argon2 PUBLIC argon2-${FEATURE})
endfunction()
add_feature_impl(sse2 -msse2 HAVE_SSE2)
@ -76,8 +71,18 @@ elseif (NOT XMRIG_ARM AND CMAKE_SIZEOF_VOID_P EQUAL 8)
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)
set(ARGON2_X86_64_ENABLED OFF)
list(APPEND ARGON2_SOURCES arch/generic/lib/argon2-arch.c)
endif()
if (ARGON2_X86_64_ENABLED)
set(ARGON2_LIBS ${ARGON2_X86_64_LIBS})
list(APPEND ARGON2_SOURCES ${ARGON2_X86_64_SOURCES})
endif()
add_library(argon2 STATIC ${ARGON2_SOURCES})
target_link_libraries(argon2 ${ARGON2_LIBS})
target_include_directories(argon2 PRIVATE ${CMAKE_CURRENT_SOURCE_DIR}/include)
target_include_directories(argon2 PRIVATE ${CMAKE_CURRENT_SOURCE_DIR}/lib)

132
src/3rdparty/base64/base64.h vendored Normal file
View file

@ -0,0 +1,132 @@
#ifndef _BASE64_H_
#define _BASE64_H_
/**
* The MIT License (MIT)
* Copyright (c) 2016 tomykaira
*
* Permission is hereby granted, free of charge, to any person obtaining
* a copy of this software and associated documentation files (the
* "Software"), to deal in the Software without restriction, including
* without limitation the rights to use, copy, modify, merge, publish,
* distribute, sublicense, and/or sell copies of the Software, and to
* permit persons to whom the Software is furnished to do so, subject to
* the following conditions:
*
* The above copyright notice and this permission notice shall be
* included in all copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
* NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
* LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
* OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
* WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
*/
#include <string>
class Base64
{
public:
static std::string Encode(const std::string data)
{
static constexpr char sEncodingTable[] = {
'A', 'B', 'C', 'D', 'E', 'F', 'G', 'H',
'I', 'J', 'K', 'L', 'M', 'N', 'O', 'P',
'Q', 'R', 'S', 'T', 'U', 'V', 'W', 'X',
'Y', 'Z', 'a', 'b', 'c', 'd', 'e', 'f',
'g', 'h', 'i', 'j', 'k', 'l', 'm', 'n',
'o', 'p', 'q', 'r', 's', 't', 'u', 'v',
'w', 'x', 'y', 'z', '0', '1', '2', '3',
'4', '5', '6', '7', '8', '9', '+', '/'
};
size_t in_len = data.size();
size_t out_len = 4 * ((in_len + 2) / 3);
std::string ret(out_len, '\0');
size_t i;
char* p = const_cast<char*>(ret.c_str());
for (i = 0; i < in_len - 2; i += 3)
{
*p++ = sEncodingTable[(data[i] >> 2) & 0x3F];
*p++ = sEncodingTable[((data[i] & 0x3) << 4) | ((int) (data[i + 1] & 0xF0) >> 4)];
*p++ = sEncodingTable[((data[i + 1] & 0xF) << 2) | ((int) (data[i + 2] & 0xC0) >> 6)];
*p++ = sEncodingTable[data[i + 2] & 0x3F];
}
if (i < in_len)
{
*p++ = sEncodingTable[(data[i] >> 2) & 0x3F];
if (i == (in_len - 1))
{
*p++ = sEncodingTable[((data[i] & 0x3) << 4)];
*p++ = '=';
}
else
{
*p++ = sEncodingTable[((data[i] & 0x3) << 4) | ((int) (data[i + 1] & 0xF0) >> 4)];
*p++ = sEncodingTable[((data[i + 1] & 0xF) << 2)];
}
*p++ = '=';
}
return ret;
}
static std::string Decode(const std::string& input, std::string& out)
{
static constexpr unsigned char kDecodingTable[] = {
64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64,
64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64,
64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 62, 64, 64, 64, 63,
52, 53, 54, 55, 56, 57, 58, 59, 60, 61, 64, 64, 64, 64, 64, 64,
64, 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14,
15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 64, 64, 64, 64, 64,
64, 26, 27, 28, 29, 30, 31, 32, 33, 34, 35, 36, 37, 38, 39, 40,
41, 42, 43, 44, 45, 46, 47, 48, 49, 50, 51, 64, 64, 64, 64, 64,
64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64,
64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64,
64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64,
64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64,
64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64,
64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64,
64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64,
64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64
};
size_t in_len = input.size();
if (in_len % 4 != 0)
{ return "Input data size is not a multiple of 4"; }
size_t out_len = in_len / 4 * 3;
if (input[in_len - 1] == '=')
{ out_len--; }
if (input[in_len - 2] == '=')
{ out_len--; }
out.resize(out_len);
for (size_t i = 0, j = 0; i < in_len;)
{
uint32_t a = input[i] == '=' ? 0 & i++ : kDecodingTable[static_cast<int>(input[i++])];
uint32_t b = input[i] == '=' ? 0 & i++ : kDecodingTable[static_cast<int>(input[i++])];
uint32_t c = input[i] == '=' ? 0 & i++ : kDecodingTable[static_cast<int>(input[i++])];
uint32_t d = input[i] == '=' ? 0 & i++ : kDecodingTable[static_cast<int>(input[i++])];
uint32_t triple = (a << 3 * 6) + (b << 2 * 6) + (c << 1 * 6) + (d << 0 * 6);
if (j < out_len)
{ out[j++] = (triple >> 2 * 8) & 0xFF; }
if (j < out_len)
{ out[j++] = (triple >> 1 * 8) & 0xFF; }
if (j < out_len)
{ out[j++] = (triple >> 0 * 8) & 0xFF; }
}
return "";
}
};
#endif /* _BASE64_H_ */

File diff suppressed because it is too large Load diff

97
src/3rdparty/cxxopts/CHANGELOG.md vendored Normal file
View file

@ -0,0 +1,97 @@
# Changelog
This is the changelog for `cxxopts`, a C++11 library for parsing command line
options. The project adheres to semantic versioning.
## Next version
### Changed
* Only search for a C++ compiler in CMakeLists.txt.
* Allow for exceptions to be disabled.
* Fix duplicate default options when there is a short and long option.
* Add `CXXOPTS_NO_EXCEPTIONS` to disable exceptions.
* Fix char parsing for space and check for length.
## 2.2
### Changed
* Allow integers to have leading zeroes.
* Build the tests by default.
* Don't check for container when showing positional help.
### Added
* Iterator inputs to `parse_positional`.
* Throw an exception if the option in `parse_positional` doesn't exist.
* Parse a delimited list in a single argument for vector options.
* Add an option to disable implicit value on booleans.
### Bug Fixes
* Fix a warning about possible loss of data.
* Fix version numbering in CMakeLists.txt
* Remove unused declaration of the undefined `ParseResult::get_option`.
* Throw on invalid option syntax when beginning with a `-`.
* Throw in `as` when option wasn't present.
* Fix catching exceptions by reference.
* Fix out of bounds errors parsing integers.
## 2.1.1
### Bug Fixes
* Revert the change adding `const` type for `argv`, because most users expect
to pass a non-const `argv` from `main`.
## 2.1
### Changed
* Options with implicit arguments now require the `--option=value` form if
they are to be specified with an option. This is to remove the ambiguity
when a positional argument could follow an option with an implicit value.
For example, `--foo value`, where `foo` has an implicit value, will be
parsed as `--foo=implicit` and a positional argument `value`.
* Boolean values are no longer special, but are just an option with a default
and implicit value.
### Added
* Added support for `std::optional` as a storage type.
* Allow the help string to be customised.
* Use `const` for the type in the `argv` parameter, since the contents of the
arguments is never modified.
### Bug Fixes
* Building against GCC 4.9 was broken due to overly strict shadow warnings.
* Fixed an ambiguous overload in the `parse_positional` function when an
`initializer_list` was directly passed.
* Fixed precedence in the Boolean value regex.
## 2.0
### Changed
* `Options::parse` returns a ParseResult rather than storing the parse
result internally.
* Options with default values now get counted as appearing once if they
were not specified by the user.
### Added
* A new `ParseResult` object that is the immutable result of parsing. It
responds to the same `count` and `operator[]` as `Options` of 1.x did.
* The function `ParseResult::arguments` returns a vector of the parsed
arguments to iterate through in the order they were provided.
* The symbol `cxxopts::version` for the version of the library.
* Booleans can be specified with various strings and explicitly set false.
## 1.x
The 1.x series was the first major version of the library, with release numbers
starting to follow semantic versioning, after 0.x being unstable. It never had
a changelog maintained for it. Releases mostly contained bug fixes, with the
occasional feature added.

19
src/3rdparty/cxxopts/LICENSE vendored Normal file
View file

@ -0,0 +1,19 @@
Copyright (c) 2014 Jarryd Beck
Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal
in the Software without restriction, including without limitation the rights
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
copies of the Software, and to permit persons to whom the Software is
furnished to do so, subject to the following conditions:
The above copyright notice and this permission notice shall be included in
all copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
THE SOFTWARE.

157
src/3rdparty/cxxopts/README.md vendored Normal file
View file

@ -0,0 +1,157 @@
[![Build Status](https://travis-ci.org/jarro2783/cxxopts.svg?branch=master)](https://travis-ci.org/jarro2783/cxxopts)
# Release versions
Note that `master` is generally a work in progress, and you probably want to use a
tagged release version.
# Quick start
This is a lightweight C++ option parser library, supporting the standard GNU
style syntax for options.
Options can be given as:
--long
--long=argument
--long argument
-a
-ab
-abc argument
where c takes an argument, but a and b do not.
Additionally, anything after `--` will be parsed as a positional argument.
## Basics
#include <cxxopts.hpp>
Create a cxxopts::Options instance.
cxxopts::Options options("MyProgram", "One line description of MyProgram");
Then use `add_options`.
options.add_options()
("d,debug", "Enable debugging")
("f,file", "File name", cxxopts::value<std::string>())
;
Options are declared with a long and an optional short option. A description
must be provided. The third argument is the value, if omitted it is boolean.
Any type can be given as long as it can be parsed, with operator>>.
To parse the command line do:
auto result = options.parse(argc, argv);
To retrieve an option use `result.count("option")` to get the number of times
it appeared, and
result["opt"].as<type>()
to get its value. If "opt" doesn't exist, or isn't of the right type, then an
exception will be thrown.
Note that the result of `options.parse` should only be used as long as the
`options` object that created it is in scope.
## Exceptions
Exceptional situations throw C++ exceptions. There are two types of
exceptions: errors defining the options, and errors when parsing a list of
arguments. All exceptions derive from `cxxopts::OptionException`. Errors
defining options derive from `cxxopts::OptionSpecException` and errors
parsing arguments derive from `cxxopts::OptionParseException`.
All exceptions define a `what()` function to get a printable string
explaining the error.
## Help groups
Options can be placed into groups for the purposes of displaying help messages.
To place options in a group, pass the group as a string to `add_options`. Then,
when displaying the help, pass the groups that you would like displayed as a
vector to the `help` function.
## Positional Arguments
Positional arguments can be optionally parsed into one or more options.
To set up positional arguments, call
options.parse_positional({"first", "second", "last"})
where "last" should be the name of an option with a container type, and the
others should have a single value.
## Default and implicit values
An option can be declared with a default or an implicit value, or both.
A default value is the value that an option takes when it is not specified
on the command line. The following specifies a default value for an option:
cxxopts::value<std::string>()->default_value("value")
An implicit value is the value that an option takes when it is given on the
command line without an argument. The following specifies an implicit value:
cxxopts::value<std::string>()->implicit_value("implicit")
If an option had both, then not specifying it would give the value `"value"`,
writing it on the command line as `--option` would give the value `"implicit"`,
and writing `--option=another` would give it the value `"another"`.
Note that the default and implicit value is always stored as a string,
regardless of the type that you want to store it in. It will be parsed as
though it was given on the command line.
## Boolean values
Boolean options have a default implicit value of `"true"`, which can be
overridden. The effect is that writing `-o` by itself will set option `o` to
`true`. However, they can also be written with various strings using `=value`.
There is no way to disambiguate positional arguments from the value following
a boolean, so we have chosen that they will be positional arguments, and
therefore, `-o false` does not work.
## `std::vector<T>` values
Parsing of list of values in form of an `std::vector<T>` is also supported, as long as `T`
can be parsed. To separate single values in a list the definition `CXXOPTS_VECTOR_DELIMITER`
is used, which is ',' by default. Ensure that you use no whitespaces between values because
those would be interpreted as the next command line option. Example for a command line option
that can be parsed as a `std::vector<double>`:
~~~
--my_list=1,-2.1,3,4.5
~~~
## Custom help
The string after the program name on the first line of the help can be
completely replaced by calling `options.custom_help`. Note that you might
also want to override the positional help by calling `options.positional_help`.
# Linking
This is a header only library.
# Requirements
The only build requirement is a C++ compiler that supports C++11 features such as:
* regex
* constexpr
* default constructors
GCC >= 4.9 or clang >= 3.1 with libc++ are known to work.
The following compilers are known not to work:
* MSVC 2013
# TODO list
* Allow unrecognised options.

2214
src/3rdparty/cxxopts/cxxopts.hpp vendored Normal file

File diff suppressed because it is too large Load diff

View file

@ -30,6 +30,7 @@
#include "App.h"
#include "backend/cpu/Cpu.h"
#include "base/io/Console.h"
#include "base/io/log/Log.h"
#include "base/kernel/Signals.h"
@ -178,7 +179,11 @@ void xmrig::App::close(bool restart)
m_restart = restart;
m_signals->stop();
m_console->stop();
if (m_console) {
m_console->stop();
}
m_controller->stop();
Log::destroy();

View file

@ -26,10 +26,8 @@
#ifndef XMRIG_APP_H
#define XMRIG_APP_H
#include "base/kernel/interfaces/IConsoleListener.h"
#include "base/kernel/interfaces/ISignalListener.h"
#include "base/cc/interfaces/ICommandListener.h"
#include "cc/ControlCommand.h"
@ -77,5 +75,4 @@ private:
} /* namespace xmrig */
#endif /* XMRIG_APP_H */

View file

@ -123,9 +123,6 @@ bool xmrig::CpuWorker<N>::selfTest()
verify2(Algorithm::CN_R, test_output_r) &&
verify(Algorithm::CN_RWZ, test_output_rwz) &&
verify(Algorithm::CN_ZLS, test_output_zls) &&
#ifndef XMRIG_ARM
verify(Algorithm::CN_CONCEAL, test_output_conceal) &&
#endif
verify(Algorithm::CN_DOUBLE, test_output_double);
# ifdef XMRIG_ALGO_CN_GPU

View file

@ -37,7 +37,7 @@
# define HWLOC_OBJ_NUMANODE HWLOC_OBJ_NODE
#endif
#include "crypto/cn/CnAlgo.h"
#include "backend/cpu/platform/HwlocCpuInfo.h"
#include "base/io/log/Log.h"
@ -290,6 +290,11 @@ void xmrig::HwlocCpuInfo::processTopLevelCache(hwloc_obj_t cache, const Algorith
}
# endif
if (CnAlgo<>::base(algorithm) == Algorithm::CN_0 || CnAlgo<>::base(algorithm) == Algorithm::CN_1) {
intensity = std::min<uint32_t >(static_cast<const uint32_t &>(cacheHashes / PUs), algorithm.maxIntensity());
}
# ifdef XMRIG_ALGO_CN_GPU
if (algorithm == Algorithm::CN_GPU) {
cacheHashes = PUs;

View file

@ -62,7 +62,6 @@ set(SOURCES_BASE
src/base/io/json/JsonRequest.cpp
src/base/io/log/backends/ConsoleLog.cpp
src/base/io/log/backends/FileLog.cpp
src/base/io/log/backends/RemoteLog.cpp
src/base/io/log/Log.cpp
src/base/io/Watcher.cpp
src/base/kernel/Base.cpp

View file

@ -31,8 +31,11 @@
xmrig::Console::Console(IConsoleListener *listener)
: m_listener(listener)
{
m_tty = new uv_tty_t;
if (!isSupported()) {
return;
}
m_tty = new uv_tty_t;
m_tty->data = this;
uv_tty_init(uv_default_loop(), m_tty, 0, 1);
@ -53,6 +56,10 @@ xmrig::Console::~Console()
void xmrig::Console::stop()
{
if (!m_tty) {
return;
}
uv_tty_reset_mode();
Handle::close(m_tty);
@ -60,6 +67,13 @@ void xmrig::Console::stop()
}
bool xmrig::Console::isSupported() const
{
const uv_handle_type type = uv_guess_handle(0);
return type == UV_TTY || type == UV_NAMED_PIPE;
}
void xmrig::Console::onAllocBuffer(uv_handle_t *handle, size_t, uv_buf_t *buf)
{
auto console = static_cast<Console*>(handle->data);

View file

@ -26,9 +26,11 @@
#define XMRIG_CONSOLE_H
#include <uv.h>
#include "base/tools/Object.h"
#include <uv.h>
namespace xmrig {
@ -39,18 +41,22 @@ class IConsoleListener;
class Console
{
public:
XMRIG_DISABLE_COPY_MOVE_DEFAULT(Console)
Console(IConsoleListener *listener);
~Console();
void stop();
private:
bool isSupported() const;
static void onAllocBuffer(uv_handle_t *handle, size_t suggested_size, uv_buf_t *buf);
static void onRead(uv_stream_t *stream, ssize_t nread, const uv_buf_t *buf);
char m_buf[1];
char m_buf[1] = { 0 };
IConsoleListener *m_listener;
uv_tty_t *m_tty;
uv_tty_t *m_tty = nullptr;
};

View file

@ -28,6 +28,7 @@
#ifdef __GNUC__
# include <fcntl.h>
# include <sys/stat.h>
# include <ext/stdio_filebuf.h>
#endif
@ -102,7 +103,7 @@ bool xmrig::Json::save(const char *fileName, const rapidjson::Document &doc)
return false;
}
# elif defined(__GNUC__)
const int fd = _wopen(toUtf16(fileName).c_str(), _O_WRONLY | _O_BINARY | _O_CREAT | _O_TRUNC);
const int fd = _wopen(toUtf16(fileName).c_str(), _O_WRONLY | _O_BINARY | _O_CREAT | _O_TRUNC, _S_IWRITE);
if (fd == -1) {
return false;
}

View file

@ -24,7 +24,7 @@
*/
#include <stdio.h>
#include <cstdio>
#include "base/tools/Handle.h"
@ -32,9 +32,13 @@
#include "base/io/log/Log.h"
xmrig::ConsoleLog::ConsoleLog() :
m_stream(nullptr)
xmrig::ConsoleLog::ConsoleLog()
{
if (!isSupported()) {
Log::colors = false;
return;
}
m_tty = new uv_tty_t;
if (uv_tty_init(uv_default_loop(), m_tty, 1, 0) < 0) {
@ -66,7 +70,7 @@ xmrig::ConsoleLog::~ConsoleLog()
void xmrig::ConsoleLog::print(int, const char *line, size_t, size_t size, bool colors)
{
if (Log::colors != colors) {
if (!m_tty || Log::colors != colors) {
return;
}
@ -86,12 +90,18 @@ void xmrig::ConsoleLog::print(int, const char *line, size_t, size_t size, bool c
}
bool xmrig::ConsoleLog::isSupported() const
{
const uv_handle_type type = uv_guess_handle(1);
return type == UV_TTY || type == UV_NAMED_PIPE;
}
bool xmrig::ConsoleLog::isWritable() const
{
if (!m_stream || uv_is_writable(m_stream) != 1) {
return false;
}
const uv_handle_type type = uv_guess_handle(1);
return type == UV_TTY || type == UV_NAMED_PIPE;
return isSupported();
}

View file

@ -27,11 +27,12 @@
#define XMRIG_CONSOLELOG_H
typedef struct uv_stream_s uv_stream_t;
typedef struct uv_tty_s uv_tty_t;
using uv_stream_t = struct uv_stream_s;
using uv_tty_t = struct uv_tty_s;
#include "base/kernel/interfaces/ILogBackend.h"
#include "base/tools/Object.h"
namespace xmrig {
@ -40,6 +41,8 @@ namespace xmrig {
class ConsoleLog : public ILogBackend
{
public:
XMRIG_DISABLE_COPY_MOVE(ConsoleLog)
ConsoleLog();
~ConsoleLog() override;
@ -47,10 +50,11 @@ protected:
void print(int level, const char *line, size_t offset, size_t size, bool colors) override;
private:
bool isSupported() const;
bool isWritable() const;
uv_stream_t *m_stream;
uv_tty_t *m_tty;
uv_stream_t *m_stream = nullptr;
uv_tty_t *m_tty = nullptr;
};

View file

@ -25,13 +25,13 @@
#include <assert.h>
#include <memory>
#include <base/io/log/backends/RemoteLog.h>
#include "base/io/json/Json.h"
#include "base/io/json/JsonChain.h"
#include "base/io/log/backends/ConsoleLog.h"
#include "base/io/log/backends/FileLog.h"
#include "base/io/log/backends/RemoteLog.h"
#include "base/io/log/Log.h"
#include "base/io/Watcher.h"
#include "base/kernel/Base.h"
@ -277,6 +277,7 @@ void xmrig::Base::stop()
d_ptr->watcher = nullptr;
}
xmrig::Api *xmrig::Base::api() const
{
assert(d_ptr->api != nullptr);
@ -284,6 +285,7 @@ xmrig::Api *xmrig::Base::api() const
return d_ptr->api;
}
xmrig::CCClient *xmrig::Base::ccClient() const
{
assert(d_ptr->ccClient != nullptr);
@ -291,6 +293,7 @@ xmrig::CCClient *xmrig::Base::ccClient() const
return d_ptr->ccClient;
}
bool xmrig::Base::reload(const rapidjson::Value &json)
{
JsonReader reader(json);

View file

@ -25,7 +25,6 @@
#ifndef XMRIG_BASECONFIG_H
#define XMRIG_BASECONFIG_H
#include "base/tools/String.h"
#include "base/kernel/interfaces/IConfig.h"
#include "base/net/http/Http.h"
#include "base/net/stratum/Pools.h"
@ -91,7 +90,7 @@ protected:
CCClientConfig m_ccClient;
# endif
String m_apiId;
String m_apiId;
String m_apiWorkerId;
String m_fileName;
String m_logFile;

View file

@ -47,6 +47,7 @@ namespace xmrig
static const char *kAlgo = "algo";
static const char *kApi = "api";
static const char *kCoin = "coin";
static const char *kHttp = "http";
static const char *kPools = "pools";
static const char *kCCClient = "cc-client";
@ -108,6 +109,15 @@ void xmrig::BaseTransform::finalize(rapidjson::Document &doc)
}
}
}
if (m_coin.isValid() && doc.HasMember(kPools)) {
auto &pools = doc[kPools];
for (Value &pool : pools.GetArray()) {
if (!pool.HasMember(kCoin)) {
pool.AddMember(StringRef(kCoin), m_coin.toJSON(), allocator);
}
}
}
}
@ -123,6 +133,15 @@ void xmrig::BaseTransform::transform(rapidjson::Document &doc, int key, const ch
}
break;
case IConfig::CoinKey: /* --coin */
if (!doc.HasMember(kPools)) {
m_coin = arg;
}
else {
return add(doc, kPools, kCoin, arg);
}
break;
case IConfig::UserpassKey: /* --userpass */
{
const char *p = strrchr(arg, ':');

View file

@ -27,6 +27,7 @@
#include "base/kernel/interfaces/IConfigTransform.h"
#include "crypto/common/Coin.h"
#include "rapidjson/document.h"
@ -99,6 +100,7 @@ protected:
protected:
Algorithm m_algorithm;
Coin m_coin;
private:

View file

@ -43,6 +43,7 @@ public:
enum Keys {
// common
AlgorithmKey = 'a',
CoinKey = 1025,
ApiWorkerIdKey = 4002,
ApiIdKey = 4005,
HttpPort = 4100,
@ -140,7 +141,6 @@ public:
CCAccessToken = 9007,
CCWorkerId = 9008,
CCUpdateInterval = 9009,
};
virtual ~IConfig() = default;

View file

@ -334,6 +334,9 @@ bool xmrig::Client::parseJob(const rapidjson::Value &params, int *code)
if (algo) {
job.setAlgorithm(algo);
}
else if (m_pool.coin().isValid()) {
job.setAlgorithm(m_pool.coin().algorithm(job.blob()[0]));
}
job.setHeight(Json::getUint64(params, "height"));
@ -426,7 +429,12 @@ bool xmrig::Client::verifyAlgorithm(const Algorithm &algorithm, const char *algo
{
if (!algorithm.isValid()) {
if (!isQuiet()) {
LOG_ERR("[%s] Unknown/unsupported algorithm \"%s\" detected, reconnect", url(), algo);
if (algo == nullptr) {
LOG_ERR("[%s] unknown algorithm, make sure you set \"algo\" or \"coin\" option", url(), algo);
}
else {
LOG_ERR("[%s] unsupported algorithm \"%s\" detected, reconnect", url(), algo);
}
}
return false;
@ -436,7 +444,7 @@ bool xmrig::Client::verifyAlgorithm(const Algorithm &algorithm, const char *algo
m_listener->onVerifyAlgorithm(this, algorithm, &ok);
if (!ok && !isQuiet()) {
LOG_ERR("[%s] Incompatible/disabled algorithm \"%s\" detected, reconnect", url(), algorithm.shortName());
LOG_ERR("[%s] incompatible/disabled algorithm \"%s\" detected, reconnect", url(), algorithm.shortName());
}
return ok;
@ -900,6 +908,12 @@ void xmrig::Client::onConnect(uv_connect_t *req, int status)
LOG_ERR("[%s] connect error: \"%s\"", client->url(), uv_strerror(status));
}
if (client->state() != ConnectingState) {
LOG_ERR("[%s] connect error: \"invalid state: %d\"", client->url(), client->state());
return;
}
delete req;
client->close();
return;

View file

@ -25,7 +25,7 @@
#include <algorithm>
#include <assert.h>
#include <cassert>
#include "3rdparty/http-parser/http_parser.h"
@ -225,6 +225,10 @@ bool xmrig::DaemonClient::parseJob(const rapidjson::Value &params, int *code)
job.setDiff(Json::getUint64(params, "difficulty"));
job.setId(blocktemplate.data() + blocktemplate.size() - 32);
if (m_pool.coin().isValid()) {
job.setAlgorithm(m_pool.coin().algorithm(job.blob()[0]));
}
m_job = std::move(job);
m_blocktemplate = std::move(blocktemplate);
m_prevHash = Json::getString(params, "prev_hash");

View file

@ -73,6 +73,7 @@ public:
inline uint8_t fixedByte() const { return *(m_blob + 42); }
inline uint8_t index() const { return m_index; }
inline void reset() { m_size = 0; m_diff = 0; }
inline void setAlgorithm(const Algorithm::Id id) { m_algorithm = id; }
inline void setAlgorithm(const char *algo) { m_algorithm = algo; }
inline void setClientId(const String &id) { m_clientId = id; }
inline void setHeight(uint64_t height) { m_height = height; }

View file

@ -48,6 +48,7 @@
namespace xmrig {
static const char *kAlgo = "algo";
static const char *kCoin = "coin";
static const char *kDaemon = "daemon";
static const char *kDaemonPollInterval = "daemon-poll-interval";
static const char *kEnabled = "enabled";
@ -120,6 +121,7 @@ xmrig::Pool::Pool(const rapidjson::Value &object) :
m_fingerprint = Json::getString(object, kFingerprint);
m_pollInterval = Json::getUint64(object, kDaemonPollInterval, kDefaultPollInterval);
m_algorithm = Json::getString(object, kAlgo);
m_coin = Json::getString(object, kCoin);
m_flags.set(FLAG_ENABLED, Json::getBool(object, kEnabled, true));
m_flags.set(FLAG_NICEHASH, Json::getBool(object, kNicehash));
@ -172,7 +174,7 @@ bool xmrig::Pool::isEnabled() const
}
# endif
if (isDaemon() && !algorithm().isValid()) {
if (isDaemon() && (!algorithm().isValid() && !coin().isValid())) {
return false;
}
@ -186,6 +188,7 @@ bool xmrig::Pool::isEqual(const Pool &other) const
&& m_keepAlive == other.m_keepAlive
&& m_port == other.m_port
&& m_algorithm == other.m_algorithm
&& m_coin == other.m_coin
&& m_fingerprint == other.m_fingerprint
&& m_host == other.m_host
&& m_password == other.m_password
@ -268,6 +271,7 @@ rapidjson::Value xmrig::Pool::toJSON(rapidjson::Document &doc) const
Value obj(kObjectType);
obj.AddMember(StringRef(kAlgo), m_algorithm.toJSON(), allocator);
obj.AddMember(StringRef(kCoin), m_coin.toJSON(), allocator);
obj.AddMember(StringRef(kUrl), m_url.toJSON(), allocator);
obj.AddMember(StringRef(kUser), m_user.toJSON(), allocator);

View file

@ -32,7 +32,7 @@
#include "base/tools/String.h"
#include "crypto/common/Algorithm.h"
#include "crypto/common/Coin.h"
#include "rapidjson/fwd.h"
@ -74,6 +74,7 @@ public:
inline bool isTLS() const { return m_flags.test(FLAG_TLS); }
inline bool isValid() const { return !m_host.isNull() && m_port > 0; }
inline const Algorithm &algorithm() const { return m_algorithm; }
inline const Coin &coin() const { return m_coin; }
inline const String &fingerprint() const { return m_fingerprint; }
inline const String &host() const { return m_host; }
inline const String &password() const { return !m_password.isNull() ? m_password : kDefaultPassword; }
@ -107,6 +108,7 @@ private:
bool parseIPv6(const char *addr);
Algorithm m_algorithm;
Coin m_coin;
int m_keepAlive;
std::bitset<FLAG_MAX> m_flags;
String m_fingerprint;

View file

@ -135,12 +135,13 @@ void xmrig::Pools::print() const
{
size_t i = 1;
for (const Pool &pool : m_data) {
Log::print(GREEN_BOLD(" * ") WHITE_BOLD("POOL #%-7zu") CSI "1;%dm%s" CLEAR " algo " WHITE_BOLD("%s"),
Log::print(GREEN_BOLD(" * ") WHITE_BOLD("POOL #%-7zu") CSI "1;%dm%s" CLEAR " %s " WHITE_BOLD("%s"),
i,
(pool.isEnabled() ? (pool.isTLS() ? 32 : 36) : 31),
pool.url().data(),
pool.algorithm().isValid() ? pool.algorithm().shortName() : "auto"
);
pool.coin().isValid() ? "coin" : "algo",
pool.coin().isValid() ? pool.coin().name() : (pool.algorithm().isValid() ? pool.algorithm().shortName() : "auto")
);
i++;
}

52
src/base/tools/Object.h Normal file
View file

@ -0,0 +1,52 @@
/* 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_OBJECT_H
#define XMRIG_OBJECT_H
#include <chrono>
namespace xmrig {
#define XMRIG_DISABLE_COPY_MOVE(X) \
X(const X &other) = delete; \
X(X &&other) = delete; \
X &operator=(const X &other) = delete; \
X &operator=(X &&other) = delete;
#define XMRIG_DISABLE_COPY_MOVE_DEFAULT(X) \
X() = delete; \
X(const X &other) = delete; \
X(X &&other) = delete; \
X &operator=(const X &other) = delete; \
X &operator=(X &&other) = delete;
} /* namespace xmrig */
#endif /* XMRIG_OBJECT_H */

122
src/cc/CCCServerConfig.cpp Normal file
View file

@ -0,0 +1,122 @@
/* XMRigCC
* Copyright 2019- BenDr0id <https://github.com/BenDr0id>, <ben@graef.in>
*
* 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 <rapidjson/document.h>
#include "base/io/json/JsonChain.h"
#include "base/io/log/Log.h"
#include "CCServerConfig.h"
template<class T>
T getParseResult(const cxxopts::ParseResult &parseResult, const std::string &propery, T defaultValue)
{
if (parseResult.count(propery) > 0)
{
return parseResult[propery].as<T>();
}
else
{
return defaultValue;
}
}
CCServerConfig::CCServerConfig(cxxopts::ParseResult& parseResult)
{
try
{
xmrig::JsonChain chain;
auto m_configFile = getParseResult(parseResult, "config", std::string());
if (!m_configFile.empty())
{
chain.addFile(m_configFile.c_str());
}
else
{
chain.addFile("config_cc.json");
}
read(chain);
m_bindIp = getParseResult(parseResult, "bind", m_bindIp);
m_port = getParseResult(parseResult, "port", m_port);
m_adminUser = getParseResult(parseResult, "user", m_adminUser);
m_adminPass = getParseResult(parseResult, "pass", m_adminPass);
m_token = getParseResult(parseResult, "token", m_token);
m_useTLS = getParseResult(parseResult, "tls", m_useTLS);
m_keyFile = getParseResult(parseResult, "key-file", m_keyFile);
m_certFile = getParseResult(parseResult, "cert-file", m_certFile);
m_colors = !getParseResult(parseResult, "no-colors", !m_colors);
m_background = getParseResult(parseResult, "background", m_background);
m_syslog = getParseResult(parseResult, "syslog", m_syslog);
m_clientLogHistory = getParseResult(parseResult, "client-log-lines-history", m_clientLogHistory);
m_customDashboard = getParseResult(parseResult, "custom-dashboard", m_customDashboard);
m_clientConfigFolder = getParseResult(parseResult, "client-config-folder", m_clientConfigFolder);
m_logFile = getParseResult(parseResult, "log-file", m_logFile);
m_pushoverApiToken = getParseResult(parseResult, "pushover-api-token", m_pushoverApiToken);
m_pushoverUserKey = getParseResult(parseResult, "pushover-user-key", m_pushoverUserKey);
m_telegramBotToken = getParseResult(parseResult, "telegram-bot-token", m_telegramBotToken);
m_telegramChatId = getParseResult(parseResult, "telegram-chat-id", m_telegramChatId);
m_pushOfflineMiners = getParseResult(parseResult, "push-miner-offline-info", m_pushOfflineMiners);
m_pushZeroHashrateMiners = getParseResult(parseResult, "push-miner-zero-hash-info", m_pushZeroHashrateMiners);
m_pushPeriodicStatus = getParseResult(parseResult, "push-periodic-mining-status", m_pushPeriodicStatus);
}
catch (const cxxopts::OptionException& e)
{
LOG_WARN("Failed to parse params. Error: %s", e.what());
}
}
bool CCServerConfig::read(const xmrig::IJsonReader& reader)
{
if (reader.isEmpty())
{
return false;
}
m_port = reader.getInt("port", m_port);
m_bindIp = reader.getString("bind-ip", m_bindIp.c_str());
m_adminUser = reader.getString("user", m_adminUser.c_str());
m_adminPass = reader.getString("pass", m_adminPass.c_str());
m_token = reader.getString("access-token", m_token.c_str());
m_useTLS = reader.getBool("use-tls", m_useTLS);
m_keyFile = reader.getString("key-file", m_keyFile.c_str());
m_certFile = reader.getString("cert-file", m_certFile.c_str());
m_colors = reader.getBool("colors", m_colors);
m_background = reader.getBool("background", m_background);
m_syslog = reader.getBool("syslog", m_syslog);
m_clientLogHistory = reader.getInt("client-log-lines-history", m_clientLogHistory);
m_customDashboard = reader.getString("custom-dashboard", m_customDashboard.c_str());
m_clientConfigFolder = reader.getString("client-config-folder", m_clientConfigFolder.c_str());
m_logFile = reader.getString("log-file", m_logFile.c_str());
m_pushoverApiToken = reader.getString("pushover-api-token", m_pushoverApiToken.c_str());
m_pushoverUserKey = reader.getString("pushover-user-key", m_pushoverUserKey.c_str());
m_telegramBotToken = reader.getString("telegram-bot-token", m_telegramBotToken.c_str());
m_telegramChatId = reader.getString("telegram-chat-id", m_telegramChatId.c_str());
m_pushOfflineMiners = reader.getBool("push-miner-offline-info", m_pushOfflineMiners);
m_pushZeroHashrateMiners = reader.getBool("push-miner-zero-hash-info", m_pushZeroHashrateMiners);
m_pushPeriodicStatus = reader.getBool("push-periodic-mining-status", m_pushPeriodicStatus);
return true;
}

View file

@ -1,5 +1,5 @@
/* XMRigCC
* Copyright 2017- BenDr0id <https://github.com/BenDr0id>, <ben@graef.in>
* Copyright 2019- BenDr0id <https://github.com/BenDr0id>, <ben@graef.in>
*
* 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
@ -16,178 +16,185 @@
*/
#include <uv.h>
#include <memory>
#include "CCServer.h"
#include "Service.h"
#include "Httpd.h"
#include "Console.h"
#include "log/ConsoleLog.h"
#include "log/FileLog.h"
#include "log/Log.h"
#include "Options.h"
#include "Summary.h"
#if _WIN32
#include <winsock2.h>
#include <windows.h>
#else
# include "unistd.h"
#endif
#include "base/io/log/backends/ConsoleLog.h"
#include "base/io/log/backends/FileLog.h"
#include "base/io/json/JsonChain.h"
#include "base/io/log/Log.h"
#ifdef HAVE_SYSLOG_H
# include "log/SysLog.h"
#include "base/io/log/backends/SysLog.h"
#endif
CCServer *CCServer::m_self = nullptr;
#include "CCServerConfig.h"
#include "Httpd.h"
#include "CCServer.h"
#include "Summary.h"
CCServer::CCServer(int argc, char** argv) :
m_console(nullptr),
m_httpd(nullptr),
m_options(nullptr)
CCServer::CCServer(cxxopts::ParseResult& parseResult)
{
m_self = this;
m_config = std::make_shared<CCServerConfig>(parseResult);
Log::init();
if (!m_config->background())
{
xmrig::Log::colors = m_config->colors();
xmrig::Log::add(new xmrig::ConsoleLog());
m_console = std::make_shared<xmrig::Console>(this);
}
m_options = Options::parse(argc, argv);
if (!m_options) {
return;
}
if (!m_options->background()) {
Log::add(new ConsoleLog(m_options->colors()));
m_console = new Console(this);
}
if (!m_config->logFile().empty())
{
xmrig::Log::add(new xmrig::FileLog(m_config->logFile().c_str()));
}
if (m_options->logFile()) {
Log::add(new FileLog(m_options->logFile()));
}
# ifdef HAVE_SYSLOG_H
if (m_options->syslog()) {
Log::add(new SysLog());
}
# endif
uv_signal_init(uv_default_loop(), &m_signal);
#ifdef HAVE_SYSLOG_H
if (m_config->syslog())
{
xmrig::Log::add(new xmrig::SysLog());
}
#endif
}
CCServer::~CCServer()
{
uv_tty_reset_mode();
delete m_httpd;
m_signals.reset();
m_console.reset();
m_httpd.reset();
m_config.reset();
}
int CCServer::start()
{
if (!m_options) {
return EINVAL;
}
if (!m_config->isValid())
{
LOG_ERR("Invalid config provided");
return EINVAL;
}
uv_signal_start(&m_signal, CCServer::onSignal, SIGHUP);
uv_signal_start(&m_signal, CCServer::onSignal, SIGTERM);
uv_signal_start(&m_signal, CCServer::onSignal, SIGINT);
m_signals = std::make_shared<xmrig::Signals>(this);
if (m_options->background()) {
moveToBackground();
}
if (m_config->background())
{
moveToBackground();
}
Summary::print();
Summary::print(m_config);
Service::start();
startUvLoopThread();
m_httpd = new Httpd(m_options);
if (!m_httpd->start()) {
return EINVAL;
}
m_httpd = std::make_shared<Httpd>(m_config);
int retVal = m_httpd->start();
if (retVal > 0)
{
LOG_ERR("Failed to bind %sServer to %s:%d", m_config->useTLS() ? "TLS " : "", m_config->bindIp().c_str(),
m_config->port());
}
else if (retVal < 0)
{
LOG_ERR("Invalid config. %s", m_config->useTLS() ? "Check bindIp, port and the certificate/key file"
: "Check bindIp and port");
}
else
{
LOG_INFO("Server stopped. Exit.");
}
const int r = uv_run(uv_default_loop(), UV_RUN_DEFAULT);
uv_loop_close(uv_default_loop());
return retVal;
}
Options::release();
return r;
void CCServer::startUvLoopThread() const
{
std::thread([]()
{
uv_run(uv_default_loop(), UV_RUN_DEFAULT);
uv_loop_close(uv_default_loop());
}).detach();
}
void CCServer::onConsoleCommand(char command)
{
switch (command) {
switch (command)
{
case 'q':
case 'Q':
stop();
break;
stop();
break;
case 3:
LOG_WARN("Ctrl+C received, exiting");
stop();
break;
LOG_WARN("Ctrl+C received, exiting");
stop();
break;
default:
break;
}
break;
}
}
void CCServer::stop()
{
uv_stop(uv_default_loop());
m_httpd->stop();
uv_stop(uv_default_loop());
}
void CCServer::onSignal(uv_signal_t* handle, int signum)
void CCServer::onSignal(int signum)
{
switch (signum)
{
switch (signum)
{
case SIGHUP:
LOG_WARN("SIGHUP received, exiting");
break;
LOG_WARN("SIGHUP received, exiting");
break;
case SIGTERM:
LOG_WARN("SIGTERM received, exiting");
break;
LOG_WARN("SIGTERM received, exiting");
break;
case SIGINT:
LOG_WARN("SIGINT received, exiting");
break;
LOG_WARN("SIGINT received, exiting");
break;
default:
break;
}
break;
}
uv_signal_stop(handle);
m_self->stop();
stop();
}
void CCServer::moveToBackground()
{
#ifdef WIN32
HWND hcon = GetConsoleWindow();
if (hcon) {
ShowWindow(hcon, SW_HIDE);
} else {
HANDLE h = GetStdHandle(STD_OUTPUT_HANDLE);
CloseHandle(h);
FreeConsole();
}
HWND hcon = GetConsoleWindow();
if (hcon) {
ShowWindow(hcon, SW_HIDE);
} else {
HANDLE h = GetStdHandle(STD_OUTPUT_HANDLE);
CloseHandle(h);
FreeConsole();
}
#else
int i = fork();
if (i < 0) {
exit(1);
}
int i = fork();
if (i < 0)
{
exit(1);
}
if (i > 0) {
exit(0);
}
if (i > 0)
{
exit(0);
}
i = setsid();
i = setsid();
if (i < 0) {
LOG_ERR("setsid() failed (errno = %d)", errno);
}
if (i < 0)
{
LOG_ERR("setsid() failed (errno = %d)", errno);
}
i = chdir("/");
if (i < 0) {
LOG_ERR("chdir() failed (errno = %d)", errno);
}
i = chdir("/");
if (i < 0)
{
LOG_ERR("chdir() failed (errno = %d)", errno);
}
#endif
}

View file

@ -18,40 +18,39 @@
#ifndef __CC_SERVER_H__
#define __CC_SERVER_H__
#include <memory>
#include <cxxopts/cxxopts.hpp>
#include <uv.h>
#include "base/kernel/interfaces/IConsoleListener.h"
#include "base/kernel/interfaces/ISignalListener.h"
#include "base/kernel/Signals.h"
#include "base/io/Console.h"
#include "CCServerConfig.h"
#include "Httpd.h"
#include "interfaces/IConsoleListener.h"
class Console;
class Httpd;
class Options;
class CCServer : public IConsoleListener
class CCServer : public xmrig::IConsoleListener, public xmrig::ISignalListener
{
public:
CCServer(int argc, char **argv);
CCServer(cxxopts::ParseResult& parseResult);
~CCServer();
int start();
protected:
void onConsoleCommand(char command) override;
void onSignal(int signum) override;
private:
void stop();
void moveToBackground();
static void onSignal(uv_signal_t* handle, int signum);
std::shared_ptr<xmrig::Console> m_console;
std::shared_ptr<xmrig::Signals> m_signals;
std::shared_ptr<CCServerConfig> m_config;
std::shared_ptr<Httpd> m_httpd;
static CCServer* m_self;
Console* m_console;
Httpd* m_httpd;
Options* m_options;
uv_signal_t m_signal;
void startUvLoopThread() const;
};

95
src/cc/CCServerConfig.h Normal file
View file

@ -0,0 +1,95 @@
/* XMRigCC
* Copyright 2019- BenDr0id <https://github.com/BenDr0id>, <ben@graef.in>
*
* 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_CC_SERVER_CONFIG_H
#define XMRIG_CC_SERVER_CONFIG_H
#include <string>
#include <rapidjson/fwd.h>
#include <cxxopts/cxxopts.hpp>
#include "base/kernel/interfaces/IJsonReader.h"
class CCServerConfig
{
public:
explicit CCServerConfig(cxxopts::ParseResult& parseResult);
public:
bool read(const xmrig::IJsonReader &reader);
inline bool colors() const { return m_colors; }
inline bool background() const { return m_background; }
inline bool syslog() const { return m_syslog; }
inline bool useTLS() const { return m_useTLS; }
inline bool usePushover() const { return !m_pushoverUserKey.empty() && !m_pushoverApiToken.empty(); }
inline bool useTelegram() const { return !m_telegramBotToken.empty() && !m_telegramChatId.empty(); }
inline bool pushOfflineMiners() const { return m_pushOfflineMiners; }
inline bool pushZeroHashrateMiners() const { return m_pushZeroHashrateMiners; }
inline bool pushPeriodicStatus() const { return m_pushPeriodicStatus; }
inline std::string bindIp() const { return m_bindIp; }
inline std::string adminUser() const { return m_adminUser; }
inline std::string adminPass() const { return m_adminPass; }
inline std::string token() const { return m_token; }
inline std::string customDashboard() const { return m_customDashboard; }
inline std::string clientConfigFolder() const { return m_clientConfigFolder; }
inline std::string logFile() const { return m_logFile; }
inline std::string keyFile() const { return m_keyFile; }
inline std::string certFile() const { return m_certFile; }
inline std::string pushoverApiToken() const { return m_pushoverApiToken; }
inline std::string pushoverUserKey() const { return m_pushoverUserKey; }
inline std::string telegramBotToken() const { return m_telegramBotToken; }
inline std::string telegramChatId() const { return m_telegramChatId; }
inline int port() const { return m_port; }
inline int clientLogHistory() const { return m_clientLogHistory; }
inline bool isValid() const { return !m_bindIp.empty() &&
m_port > 0 && m_port < 65535; }
private:
bool m_colors = true;
bool m_background = false;
bool m_syslog = false;
bool m_useTLS = false;
bool m_pushOfflineMiners = true;
bool m_pushZeroHashrateMiners = true;
bool m_pushPeriodicStatus = true;
int m_clientLogHistory = 100;
int m_port = 3344;
std::string m_bindIp = "0.0.0.0";
std::string m_adminUser = "";
std::string m_adminPass = "";
std::string m_token = "";
std::string m_customDashboard = "index.html";
std::string m_clientConfigFolder;
std::string m_logFile;
std::string m_keyFile = "server.key";
std::string m_certFile = "server.pem";
std::string m_pushoverApiToken;
std::string m_pushoverUserKey;
std::string m_telegramBotToken;
std::string m_telegramChatId;
};
#endif /* XMRIG_CC_SERVER_CONFIG_H */

View file

@ -1,5 +1,5 @@
/* XMRigCC
* Copyright 2017- BenDr0id <https://github.com/BenDr0id>, <ben@graef.in>
* Copyright 2019- BenDr0id <https://github.com/BenDr0id>, <ben@graef.in>
*
* 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
@ -18,272 +18,198 @@
#include <cstring>
#include <sstream>
#include <fstream>
#include <microhttpd.h>
#include <memory>
#include <3rdparty/cpp-httplib/httplib.h>
#include <3rdparty/base64/base64.h>
#include "version.h"
#include "base/io/log/Log.h"
#include "CCServerConfig.h"
#include "Service.h"
#include "Httpd.h"
#include "log/Log.h"
#include "version.h"
Httpd::Httpd(const Options *options)
: m_options(options)
, m_daemon(nullptr)
namespace
{
void addResponseHeader(httplib::Response& res)
{
res.set_header("Access-Control-Allow-Origin", "*");
res.set_header("Access-Control-Allow-Methods", "POST, GET, OPTIONS");
res.set_header("Access-Control-Allow-Headers", "Content-Type, Authorization");
res.set_header("WWW-Authenticate", "Basic");
res.set_header("WWW-Authenticate", "Bearer");
}
}
Httpd::Httpd(const std::shared_ptr<CCServerConfig>& config)
: m_config(config)
{
}
bool Httpd::start()
Httpd::~Httpd()
{
if (!m_options->ccPort()) {
return false;
}
# ifndef XMRIG_NO_TLS
if (m_options->ccUseTls()) {
m_keyPem = readFile(m_options->ccKeyFile());
m_certPem = readFile(m_options->ccCertFile());
if (m_keyPem.empty() || m_certPem.empty()) {
LOG_ERR("HTTPS Daemon failed to start. Unable to load Key/Cert.");
return false;
}
m_daemon = MHD_start_daemon (MHD_USE_SELECT_INTERNALLY | MHD_USE_SSL,
static_cast<uint16_t>(m_options->ccPort()), nullptr, nullptr, &Httpd::handler,
this, MHD_OPTION_CONNECTION_TIMEOUT, (unsigned int) 25,
MHD_OPTION_HTTPS_MEM_KEY, m_keyPem.c_str(),
MHD_OPTION_HTTPS_MEM_CERT, m_certPem.c_str(),
MHD_OPTION_END);
} else {
# endif
m_daemon = MHD_start_daemon(MHD_USE_SELECT_INTERNALLY, static_cast<uint16_t>(m_options->ccPort()), nullptr,
nullptr, &Httpd::handler,
this, MHD_OPTION_CONNECTION_TIMEOUT, (unsigned int) 25, MHD_OPTION_END);
# ifndef XMRIG_NO_TLS
}
# endif
if (!m_daemon) {
LOG_ERR("HTTP Daemon failed to start.");
return false;
} else {
LOG_INFO("%s Server started on Port: %d %s", APP_NAME, m_options->ccPort(), m_options->ccUseTls() ? "with TLS" : "");
}
return true;
stop();
}
std::string Httpd::readFile(const std::string &fileName)
int Httpd::start()
{
std::stringstream data;
std::ifstream file(fileName);
if (file) {
data << file.rdbuf();
file.close();
}
m_service = std::make_shared<Service>(m_config);
m_service->start();
return data.str();
}
unsigned Httpd::tokenAuth(struct MHD_Connection* connection, const std::string& clientIp)
{
if (!m_options->ccToken()) {
LOG_WARN("[%s] 200 OK - WARNING AccessToken not set!", clientIp.c_str());
return MHD_HTTP_OK;
}
const char* header = MHD_lookup_connection_value(connection, MHD_HEADER_KIND, MHD_HTTP_HEADER_AUTHORIZATION);
if (m_options->ccToken() && !header) {
LOG_WARN("[%s] 401 UNAUTHORIZED", clientIp.c_str());
return MHD_HTTP_UNAUTHORIZED;
}
const size_t size = strlen(header);
if (size < 8 || strlen(m_options->ccToken()) != size - 7 || memcmp("Bearer ", header, 7) != 0) {
LOG_ERR("[%s] 403 FORBIDDEN - AccessToken wrong!", clientIp.c_str());
return MHD_HTTP_FORBIDDEN;
}
return strncmp(m_options->ccToken(), header + 7, strlen(m_options->ccToken())) == 0 ? MHD_HTTP_OK : MHD_HTTP_FORBIDDEN;
}
unsigned Httpd::basicAuth(struct MHD_Connection* connection, const std::string& clientIp, std::string& resp)
{
unsigned result = MHD_HTTP_OK;
if (!m_options->ccAdminUser() || !m_options->ccAdminPass()) {
resp = std::string("<html><body\\>"
"Please configure admin user and pass to view this Page."
"</body><html\\>");
LOG_ERR("[%s] 403 FORBIDDEN - Admin user/password not set!", clientIp.c_str());
result = MHD_HTTP_FORBIDDEN;
}
else {
const char* header = MHD_lookup_connection_value(connection, MHD_HEADER_KIND, MHD_HTTP_HEADER_AUTHORIZATION);
if (header) {
char* user = nullptr;
char* pass = nullptr;
user = MHD_basic_auth_get_username_password(connection, &pass);
if (user == nullptr || strcmp(user, m_options->ccAdminUser()) != 0 ||
pass == nullptr || strcmp(pass, m_options->ccAdminPass()) != 0) {
LOG_ERR("[%s] 403 FORBIDDEN - Admin user/password wrong!", clientIp.c_str());
result = MHD_HTTP_UNAUTHORIZED;
}
if (user) {
free(user);
}
if (pass) {
free(pass);
}
} else {
LOG_WARN("[%s] 401 UNAUTHORIZED", clientIp.c_str());
result = MHD_HTTP_UNAUTHORIZED;
}
}
return result;
}
int Httpd::sendResponse(MHD_Connection* connection, unsigned status, MHD_Response* rsp, const char* contentType)
{
if (!rsp) {
rsp = MHD_create_response_from_buffer(0, nullptr, MHD_RESPMEM_MUST_COPY);
}
MHD_add_response_header(rsp, "Content-Type", contentType);
MHD_add_response_header(rsp, "Access-Control-Allow-Origin", "*");
MHD_add_response_header(rsp, "Access-Control-Allow-Methods", "POST, GET, OPTIONS");
MHD_add_response_header(rsp, "Access-Control-Allow-Headers", "Content-Type, Authorization");
MHD_add_response_header(rsp, "WWW-Authenticate", "Basic");
MHD_add_response_header(rsp, "WWW-Authenticate", "Bearer");
int ret = MHD_queue_response(connection, status, rsp);
MHD_destroy_response(rsp);
return ret;
}
int Httpd::handler(void* httpd, MHD_Connection* connection, const char* url, const char* method,
const char* version, const char* upload_data, size_t* upload_data_size, void** con_cls)
{
std::string clientIp;
const MHD_ConnectionInfo *info = MHD_get_connection_info(connection, MHD_CONNECTION_INFO_CLIENT_ADDRESS);
if (info) {
char clientHost[NI_MAXHOST];
int ec = getnameinfo(info->client_addr, sizeof(*info->client_addr), clientHost, sizeof(clientHost),
0, 0, NI_NUMERICHOST|NI_NUMERICSERV);
if (ec == 0) {
clientIp = std::string(clientHost);
}
}
if (strcmp(method, MHD_HTTP_METHOD_OPTIONS) == 0) {
LOG_INFO("[%s] OPTIONS Requested", clientIp.c_str());
return sendResponse(connection, MHD_HTTP_OK, nullptr, CONTENT_TYPE_HTML);
}
if (strcmp(method, MHD_HTTP_METHOD_GET) != 0 && strcmp(method, MHD_HTTP_METHOD_POST) != 0) {
LOG_ERR("[%s] 405 METHOD NOT ALLOWED (%s)", clientIp.c_str(), method);
return sendResponse(connection, MHD_HTTP_METHOD_NOT_ALLOWED, nullptr, CONTENT_TYPE_HTML);
}
if (strstr(url, "/client/")) {
unsigned status = static_cast<Httpd*>(httpd)->tokenAuth(connection, clientIp);
if (status != MHD_HTTP_OK) {
return sendResponse(connection, status, nullptr, CONTENT_TYPE_JSON);
}
} else {
std::string resp;
unsigned status = static_cast<Httpd*>(httpd)->basicAuth(connection, clientIp, resp);
if (status != MHD_HTTP_OK) {
MHD_Response* rsp = nullptr;
if (!resp.empty()) {
rsp = MHD_create_response_from_buffer(resp.length(), (void*)resp.c_str(), MHD_RESPMEM_MUST_COPY);
}
return sendResponse(connection, status, rsp, CONTENT_TYPE_HTML);
}
}
if (strcmp(method, MHD_HTTP_METHOD_GET) == 0) {
return handleGET(static_cast<Httpd*>(httpd), connection, clientIp, url);
} else {
return handlePOST(static_cast<Httpd*>(httpd), connection, clientIp, url, upload_data, upload_data_size, con_cls);
}
}
int Httpd::handleGET(const Httpd* httpd, struct MHD_Connection* connection, const std::string& clientIp, const char* urlPtr)
{
std::string resp;
std::string url(urlPtr);
std::string clientId;
const char* clientIdPtr = MHD_lookup_connection_value(connection, MHD_GET_ARGUMENT_KIND, "clientId");
if (clientIdPtr)
#ifdef XMRIG_FEATURE_TLS
if (m_config->useTLS())
{
if (m_config->keyFile().empty() || m_config->certFile().empty())
{
clientId = std::string(clientIdPtr);
LOG_ERR("HTTPS Daemon failed to start. Unable to load Key/Cert.");
return false;
}
unsigned status = Service::handleGET(httpd->m_options, url, clientIp, clientId, resp);
m_srv = std::make_shared<httplib::SSLServer>(m_config->certFile().c_str(), m_config->keyFile().c_str());
}
else
{
#endif
m_srv = std::make_shared<httplib::Server>();
#ifdef XMRIG_FEATURE_TLS
}
#endif
MHD_Response* rsp = nullptr;
if (!resp.empty()) {
rsp = MHD_create_response_from_buffer(resp.length(), (void*) resp.c_str(), MHD_RESPMEM_MUST_COPY);
if (!m_srv->is_valid())
{
return -1;
}
xmrig::Log::print(GREEN_BOLD(" * ") WHITE_BOLD("%-13s") CSI "1;%dm%s:%d",
"LISTENING",
(m_config->useTLS() ? 32 : 36),
m_config->bindIp().c_str(),
m_config->port()
);
m_srv->Get(R"(/.*)", [this](const httplib::Request& req, httplib::Response& res)
{
int status;
if (req.path.find("/client/") == 0)
{
status = this->bearerAuth(req, res);
}
else
{
status = this->basicAuth(req, res);
}
char* contentType;
if (url == "/") {
contentType = const_cast<char*>(CONTENT_TYPE_HTML);
} else {
contentType = const_cast<char*>(CONTENT_TYPE_JSON);
if (status == HTTP_OK)
{
status = this->m_service->handleGET(req, res);
}
return sendResponse(connection, status, rsp, contentType);
res.status = status;
addResponseHeader(res);
});
m_srv->Post(R"(/.*)", [this](const httplib::Request& req, httplib::Response& res)
{
int status;
if (req.path.find("/client/") == 0)
{
status = this->bearerAuth(req, res);
}
else
{
status = this->basicAuth(req, res);
}
if (status == HTTP_OK)
{
status = this->m_service->handlePOST(req, res);
}
res.status = status;
addResponseHeader(res);
});
return m_srv->listen(m_config->bindIp().c_str(), m_config->port()) ? 0 : 1;
}
int Httpd::handlePOST(const Httpd* httpd, struct MHD_Connection* connection, const std::string& clientIp, const char* urlPtr, const char* upload_data,
size_t* upload_data_size, void** con_cls)
void Httpd::stop()
{
auto* cc = (ConnectionContext*)* con_cls;
if (cc == nullptr) {
cc = new ConnectionContext();
*con_cls = (void*) cc;
} else {
if (*upload_data_size != 0) {
cc->data << std::string(upload_data, *upload_data_size);
*upload_data_size = 0;
} else {
std::string resp;
std::string url(urlPtr);
std::string clientId;
const char* clientIdPtr = MHD_lookup_connection_value(connection, MHD_GET_ARGUMENT_KIND, "clientId");
if (clientIdPtr) {
clientId = std::string(clientIdPtr);
}
unsigned status = Service::handlePOST(httpd->m_options, url, clientIp, clientId, cc->data.str(), resp);
MHD_Response* rsp = nullptr;
if (!resp.empty()) {
rsp = MHD_create_response_from_buffer(resp.length(), (void*) resp.c_str(), MHD_RESPMEM_MUST_COPY);
}
delete cc;
*con_cls = nullptr;
return sendResponse(connection, status, rsp, CONTENT_TYPE_JSON);
}
}
return MHD_YES;
if (m_srv->is_running())
{
m_srv->stop();
}
}
int Httpd::basicAuth(const httplib::Request& req, httplib::Response& res)
{
int result = HTTP_UNAUTHORIZED;
if (m_config->adminUser().empty() || m_config->adminPass().empty())
{
res.set_content(std::string("<html><body\\>"
"Please configure admin user and pass to view this Page."
"</body><html\\>"), CONTENT_TYPE_HTML);
LOG_ERR("[%s] 403 FORBIDDEN - Admin user/password not set!", req.remoteAddr.c_str());
result = HTTP_FORBIDDEN;
}
else
{
auto authHeader = req.get_header_value("Authorization");
auto credentials = std::string("Basic ") + Base64::Encode(m_config->adminUser() + std::string(":") + m_config->adminPass());
if (!authHeader.empty() && credentials == authHeader)
{
result = HTTP_OK;
}
else if (authHeader.empty())
{
LOG_WARN("[%s] 401 UNAUTHORIZED", req.remoteAddr.c_str());
}
else
{
LOG_ERR("[%s] 403 FORBIDDEN - Admin user/password wrong!", req.remoteAddr.c_str());
}
}
res.status = result;
return result;
}
int Httpd::bearerAuth(const httplib::Request& req, httplib::Response& res)
{
int result = HTTP_UNAUTHORIZED;
if (m_config->token().empty())
{
LOG_WARN("[%s] 200 OK - WARNING AccessToken not set!", req.remoteAddr.c_str());
result = HTTP_OK;
}
else
{
auto authHeader = req.get_header_value("Authorization");
auto credentials = std::string("Bearer ") + m_config->token();
if (!authHeader.empty() && credentials == authHeader)
{
result = HTTP_OK;
}
else if (authHeader.empty())
{
LOG_WARN("[%s] 401 UNAUTHORIZED", req.remoteAddr.c_str());
}
else
{
LOG_ERR("[%s] 403 FORBIDDEN - AccessToken wrong!", req.remoteAddr.c_str());
result = HTTP_FORBIDDEN;
}
}
res.status = result;
return result;
}

View file

@ -1,5 +1,5 @@
/* XMRigCC
* Copyright 2017- BenDr0id <https://github.com/BenDr0id>, <ben@graef.in>
* Copyright 2019- BenDr0id <https://github.com/BenDr0id>, <ben@graef.in>
*
* 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
@ -18,46 +18,32 @@
#ifndef __HTTPD_H__
#define __HTTPD_H__
#include <memory>
#include <string>
#include <sstream>
#include <uv.h>
#include "Options.h"
#include "3rdparty/cpp-httplib/httplib.h"
struct MHD_Connection;
struct MHD_Daemon;
struct MHD_Response;
#include "CCServerConfig.h"
#include "Service.h"
class Httpd
{
public:
Httpd(const Options *options);
bool start();
explicit Httpd(const std::shared_ptr<CCServerConfig>& config);
~Httpd();
public:
int start();
void stop();
private:
int basicAuth(const httplib::Request& req, httplib::Response& res);
int bearerAuth(const httplib::Request& req, httplib::Response& res);
typedef struct PostContext
{
std::stringstream data;
} ConnectionContext;
static int sendResponse(MHD_Connection* connection, unsigned status, MHD_Response* rsp, const char* contentType);
unsigned basicAuth(MHD_Connection* connection, const std::string& clientIp, std::string &resp);
unsigned tokenAuth(MHD_Connection* connection, const std::string& clientIp);
static int handler(void* httpd, MHD_Connection* connection, const char* url, const char* method, const char* version, const char* upload_data, size_t* upload_data_size, void**con_cls);
static int handleGET(const Httpd* httpd, MHD_Connection* connection, const std::string& clientIp, const char* url);
static int handlePOST(const Httpd* httpd, MHD_Connection* connection, const std::string& clientIp, const char* url, const char* upload_data, size_t* upload_data_size, void** con_cls);
static std::string readFile(const std::string &fileName);
const Options* m_options;
MHD_Daemon* m_daemon;
std::string m_keyPem;
std::string m_certPem;
const std::shared_ptr<CCServerConfig> m_config;
std::shared_ptr<Service> m_service;
std::shared_ptr<httplib::Server> m_srv;
};
#endif /* __HTTPD_H__ */

File diff suppressed because it is too large Load diff

View file

@ -1,5 +1,5 @@
/* XMRigCC
* Copyright 2017- BenDr0id <https://github.com/BenDr0id>, <ben@graef.in>
* Copyright 2019- BenDr0id <https://github.com/BenDr0id>, <ben@graef.in>
*
* 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
@ -18,71 +18,84 @@
#ifndef __SERVICE_H__
#define __SERVICE_H__
#define CONTENT_TYPE_HTML "text/html"
#define CONTENT_TYPE_JSON "application/json"
#include <memory>
#include <string>
#include <uv.h>
#include <microhttpd.h>
#include <map>
#include "Options.h"
#include <3rdparty/cpp-httplib/httplib.h>
#include "CCServerConfig.h"
#include "ClientStatus.h"
#include "ControlCommand.h"
#include "Timer.h"
#define TIMER_INTERVAL 10000
#define OFFLINE_TRESHOLD_IN_MS 60000
#define STATUS_UPDATE_INTERVAL 3600000
constexpr static char CONTENT_TYPE_HTML[] = "text/html";
constexpr static char CONTENT_TYPE_JSON[] = "application/json";
constexpr static int HTTP_OK = 200;
constexpr static int HTTP_BAD_REQUEST = 400;
constexpr static int HTTP_UNAUTHORIZED = 401;
constexpr static int HTTP_FORBIDDEN = 403;
constexpr static int HTTP_NOT_FOUND = 404;
constexpr static int HTTP_INTERNAL_ERROR = 500;
constexpr static int TIMER_INTERVAL = 10000;
constexpr static int OFFLINE_TRESHOLD_IN_MS = 60000;
constexpr static int STATUS_UPDATE_INTERVAL = 3600000;
class Service
{
public:
static bool start();
static void release();
explicit Service(const std::shared_ptr<CCServerConfig>& config);
~Service();
static unsigned handleGET(const Options* options, const std::string& url, const std::string& clientIp, const std::string& clientId, std::string& resp);
static unsigned handlePOST(const Options* options, const std::string& url, const std::string& clientIp, const std::string& clientId, const std::string& data, std::string& resp);
public:
bool start();
void stop();
int handleGET(const httplib::Request& req, httplib::Response& res);
int handlePOST(const httplib::Request& req, httplib::Response& res);
private:
static unsigned getClientConfig(const Options* options, const std::string& clientId, std::string& resp);
static unsigned getClientCommand(const std::string& clientId, std::string& resp);
static unsigned getClientLog(const std::string& clientId, std::string& resp);
static unsigned getClientStatusList(std::string& resp);
static unsigned getClientConfigTemplates(const Options* options, std::string& resp);
static unsigned getAdminPage(const Options* options, std::string& resp);
int getAdminPage(httplib::Response& res);
static unsigned setClientStatus(const Options* options, const std::string& clientIp, const std::string& clientId, const std::string& data, std::string& resp);
static unsigned setClientCommand(const std::string& clientId, const std::string& data, std::string& resp);
static unsigned setClientConfig(const Options* options, const std::string &clientId, const std::string &data, std::string &resp);
static unsigned deleteClientConfig(const Options* options, const std::string& clientId, std::string& resp);
static unsigned resetClientStatusList(const std::string& data, std::string& resp);
int getClientStatusList(httplib::Response& res);
int getClientCommand(const std::string& clientId, httplib::Response& res);
int getClientConfigTemplates(httplib::Response& res);
int getClientConfig(const std::string& clientId, httplib::Response& res);
int getClientLog(const std::string& clientId, httplib::Response& res);
static void setClientLog(size_t maxRows, const std::string& clientId, const std::string& log);
int setClientStatus(const httplib::Request& req, const std::string& clientId, httplib::Response& res);
int setClientCommand(const httplib::Request& req, const std::string& clientId, httplib::Response& res);
int setClientConfig(const httplib::Request& req, const std::string& clientId, httplib::Response& res);
int deleteClientConfig(const std::string& clientId);
int resetClientStatusList();
static std::string getClientConfigFileName(const Options *options, const std::string &clientId);
std::string getClientConfigFileName(const std::string& clientId);
static void onPushTimer(uv_timer_t* handle);
static void sendServerStatusPush(uint64_t now);
static void sendMinerOfflinePush(uint64_t now);
static void sendMinerZeroHashratePush(uint64_t now);
static void triggerPush(const std::string& title, const std::string& message);
void setClientLog(size_t maxRows, const std::string& clientId, const std::string& log);
void sendServerStatusPush(uint64_t now);
void sendMinerOfflinePush(uint64_t now);
void sendMinerZeroHashratePush(uint64_t now);
void triggerPush(const std::string& title, const std::string& message);
void sendViaPushover(const std::string& title, const std::string& message);
void sendViaTelegram(const std::string& title, const std::string& message);
private:
static uint64_t m_currentServerTime;
static uint64_t m_lastStatusUpdateTime;
std::shared_ptr<CCServerConfig> m_config;
std::shared_ptr<Timer> m_timer;
static std::map<std::string, ClientStatus> m_clientStatus;
static std::map<std::string, ControlCommand> m_clientCommand;
static std::map<std::string, std::list<std::string>> m_clientLog;
uint64_t m_currentServerTime = 0;
uint64_t m_lastStatusUpdateTime = 0;
static std::list<std::string> m_offlineNotified;
static std::list<std::string> m_zeroHashNotified;
std::map<std::string, ClientStatus> m_clientStatus;
std::map<std::string, ControlCommand> m_clientCommand;
std::map<std::string, std::list<std::string>> m_clientLog;
static uv_mutex_t m_mutex;
static uv_timer_t m_timer;
std::list<std::string> m_offlineNotified;
std::list<std::string> m_zeroHashNotified;
static void sendViaPushover(const std::string &title, const std::string &message);
static void sendViaTelegram(const std::string &title, const std::string &message);
std::mutex m_mutex;
};
#endif /* __SERVICE_H__ */

View file

@ -1,5 +1,5 @@
/* XMRigCC
* Copyright 2017- BenDr0id <https://github.com/BenDr0id>, <ben@graef.in>
* Copyright 2019- BenDr0id <https://github.com/BenDr0id>, <ben@graef.in>
*
* 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
@ -14,80 +14,70 @@
* 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 <string>
#include <uv.h>
#include "log/Log.h"
#include "Options.h"
#include "Summary.h"
#ifdef XMRIG_FEATURE_TLS
# include <openssl/opensslv.h>
# include <cstring>
#endif
#include "base/io/log/Log.h"
#include "version.h"
#include "Summary.h"
static void print_versions()
static void printVersions()
{
char buf[16];
char buf[256] = { 0 };
# if defined(__clang__)
snprintf(buf, 16, " clang/%d.%d.%d", __clang_major__, __clang_minor__, __clang_patchlevel__);
snprintf(buf, sizeof buf, "clang/%d.%d.%d", __clang_major__, __clang_minor__, __clang_patchlevel__);
# elif defined(__GNUC__)
snprintf(buf, 16, " gcc/%d.%d.%d", __GNUC__, __GNUC_MINOR__, __GNUC_PATCHLEVEL__);
snprintf(buf, sizeof buf, "gcc/%d.%d.%d", __GNUC__, __GNUC_MINOR__, __GNUC_PATCHLEVEL__);
# elif defined(_MSC_VER)
snprintf(buf, 16, " MSVC/%d", MSVC_VERSION);
# else
buf[0] = '\0';
snprintf(buf, sizeof buf, "MSVC/%d", MSVC_VERSION);
# endif
Log::i()->text(Options::i()->colors() ? "\x1B[01;32m * \x1B[01;37mVERSIONS: \x1B[01;36m%s/%s\x1B[01;37m libuv/%s%s \x1B[01;36m(%s)" : " * VERSIONS: %s/%s libuv/%s%s (%s)",
APP_NAME, APP_VERSION, uv_version_string(), buf, BUILD_TYPE);
}
xmrig::Log::print(GREEN_BOLD(" * ") WHITE_BOLD("%-13s") CYAN_BOLD("%s/%s") WHITE_BOLD(" %s") BLUE_BOLD(" (%s)"), "ABOUT", APP_NAME, APP_VERSION, buf, BUILD_TYPE);
static void print_commands()
std::string libs;
#if defined(XMRIG_FEATURE_TLS) && defined(OPENSSL_VERSION_TEXT)
{
if (Options::i()->colors()) {
Log::i()->text("\x1B[01;32m * \x1B[01;37mCOMMANDS: \x1B[01;35mq\x1B[01;37muit");
}
else {
Log::i()->text(" * COMMANDS: 'q' Quit");
}
constexpr const char *v = OPENSSL_VERSION_TEXT + 8;
snprintf(buf, sizeof buf, "OpenSSL/%.*s ", static_cast<int>(strchr(v, ' ') - v), v);
libs += buf;
}
void Summary::print_pushinfo() {
if (Options::i()->ccUsePushover() || Options::i()->ccUseTelegram())
{
#ifndef XMRIG_NO_TLS
if (Options::i()->colors()) {
Log::i()->text("\x1B[01;32m * \x1B[01;37mPUSHSERVICE: \x1B[01;32m%s%s%s",
Options::i()->ccUsePushover() ? "Pushover" : "",
Options::i()->ccUsePushover() && Options::i()->ccUseTelegram() ? ", " : "",
Options::i()->ccUseTelegram() ? "Telegram" : "");
}
else {
Log::i()->text(" * PUSHSERVICE: %s%s%s",
Options::i()->ccUsePushover() ? "Pushover" : "",
Options::i()->ccUsePushover() && Options::i()->ccUseTelegram() ? ", " : "",
Options::i()->ccUseTelegram() ? "Telegram" : "");
}
#else
if (Options::i()->colors()) {
Log::i()->text("\x1B[01;32m * \x1B[01;37mPUSHSERVICE: \x1B[01;31mUnavailable requires TLS");
}
else {
Log::i()->text(" * PUSHSERVICE: Unavailable requires TLS");
}
#endif
} else {
if (Options::i()->colors()) {
Log::i()->text("\x1B[01;32m * \x1B[01;37mPUSHSERVICE: \x1B[01;31mDisabled");
}
else {
Log::i()->text(" * PUSHSERVICE: Disabled");
}
}
}
void Summary::print()
static void printCommands()
{
print_versions();
print_pushinfo();
print_commands();
xmrig::Log::print(GREEN_BOLD(" * ") WHITE_BOLD("COMMANDS ") MAGENTA_BOLD("q") WHITE_BOLD("uit, "));
}
static void printPushinfo(const std::shared_ptr<CCServerConfig>& config)
{
if (config->usePushover() || config->useTelegram())
{
#ifdef XMRIG_FEATURE_TLS
xmrig::Log::print(GREEN_BOLD(" * ") WHITE_BOLD("%-13s") CYAN_BOLD("%s%s%s"), "PUSHSERVICE",
config->usePushover() ? "Pushover" : "",
config->usePushover() && config->useTelegram() ? ", " : "",
config->useTelegram() ? "Telegram" : "");
#else
xmrig::Log::print(GREEN_BOLD(" * ") WHITE_BOLD("%-13s") RED_BOLD("Unavailable requires TLS"), "PUSHSERVICE");
#endif
}
else
{
xmrig::Log::print(GREEN_BOLD(" * ") WHITE_BOLD("%-13s") RED_BOLD("Disabled"), "PUSHSERVICE");
}
}
void Summary::print(const std::shared_ptr<CCServerConfig>& config)
{
printVersions();
printPushinfo(config);
printCommands();
}

30
src/cc/Summary.h Normal file
View file

@ -0,0 +1,30 @@
/* XMRigCC
* Copyright 2019- BenDr0id <https://github.com/BenDr0id>, <ben@graef.in>
*
* 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 XMRIGCC_SUMMARY_H
#define XMRIGCC_SUMMARY_H
#include <memory>
#include "CCServerConfig.h"
class Summary
{
public:
static void print(const std::shared_ptr<CCServerConfig>& config);
};
#endif /* XMRIGCC_SUMMARY_H */

97
src/cc/Timer.h Normal file
View file

@ -0,0 +1,97 @@
/* XMRigCC
* Copyright 2019- BenDr0id <https://github.com/BenDr0id>, <ben@graef.in>
*
* 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 __TIMER_H__
#define __TIMER_H__
#include <iostream>
#include <chrono>
#include <functional>
#include <thread>
class Timer
{
public:
Timer() {}
Timer(std::function<void(void)> func, uint64_t interval)
{
m_func = func;
m_interval = interval;
}
~Timer()
{
stop();
}
public:
void start()
{
m_running = true;
m_thread = std::thread([&]()
{
while (m_running)
{
auto delta = std::chrono::steady_clock::now() + std::chrono::milliseconds(m_interval);
std::this_thread::sleep_until(delta);
m_func();
}
});
m_thread.detach();
}
void stop()
{
m_running = false;
if (m_thread.joinable())
{
m_thread.join();
}
}
void setFunction(std::function<void(void)> func)
{
m_func = func;
}
void setInterval(uint64_t interval)
{
m_interval = interval;
}
bool isRunning()
{
return m_running;
}
uint64_t getInterval()
{
return m_interval;
}
private:
std::function<void(void)> m_func;
std::thread m_thread;
uint64_t m_interval = 0;
bool m_running = false;
};
#endif //__TIMER_H__

View file

@ -1,5 +1,5 @@
/* XMRigCC
* Copyright 2017- BenDr0id <https://github.com/BenDr0id>, <ben@graef.in>
* Copyright 2019- BenDr0id <https://github.com/BenDr0id>, <ben@graef.in>
*
* 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
@ -15,10 +15,69 @@
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
#include <iostream>
#include <cxxopts/cxxopts.hpp>
#include "CCServer.h"
#include "version.h"
int main(int argc, char** argv)
{
int ret = 0;
int main(int argc, char** argv) {
CCServer ccServer(argc, argv);
return ccServer.start();
try
{
cxxopts::Options options(argv[0] ,APP_NAME "Server " APP_VERSION);
options.positional_help("[optional args]");
options.show_positional_help();
options.add_options()
("b, bind", "The CC Server bind ip", cxxopts::value<std::string>()->default_value("0.0.0.0"))
("p, port", "The CC Server port", cxxopts::value<int>(), "N")
("U, user", "The CC Server admin user", cxxopts::value<std::string>())
("P, pass", "The CC Server admin pass", cxxopts::value<std::string>())
("T, token", "The CC Server access token for the CC Client", cxxopts::value<std::string>())
("t, tls", "Enable SSL/TLS support", cxxopts::value<bool>()->default_value("false"))
("K, key-file", "The private key file to use when TLS is ON", cxxopts::value<std::string>()->default_value("server.key"), "FILE")
("C, cert-file", "The cert file to use when TLS is ON", cxxopts::value<std::string>()->default_value("server.pem"), "FILE")
("B, background", "Run the Server in the background", cxxopts::value<bool>()->default_value("false"))
("S, syslog", "Log to the syslog", cxxopts::value<bool>()->default_value("false"))
("no-colors", "Disable colored output", cxxopts::value<bool>()->default_value("false"))
("pushover-user-key", "The user key for pushover notifications", cxxopts::value<std::string>())
("pushover-api-token", "The api token/keytoken of the application for pushover notification", cxxopts::value<std::string>())
("telegram-bot-token", "The bot token for telegram notifications", cxxopts::value<std::string>())
("telegram-chat-id", "The chat-id for telegram notifications", cxxopts::value<std::string>())
("push-miner-offline-info", "Push notification for offline miners and recovery", cxxopts::value<bool>()->default_value("true"))
("push-miner-zero-hash-info", "Push notification when miner reports 0 hashrate and recovers", cxxopts::value<bool>()->default_value("true"))
("push-periodic-mining-status", "Push every hour a status notification", cxxopts::value<bool>()->default_value("true"))
("custom-dashboard", "The custom dashboard to use", cxxopts::value<std::string>()->default_value("index.html"), "FILE")
("client-config-folder", "The CC Server access token for the CC Client", cxxopts::value<std::string>(), "FOLDER")
("log-file", "The log file to write", cxxopts::value<std::string>(), "FILE")
("client-log-lines-history", "Maximum lines of log history kept per miner", cxxopts::value<int>()->default_value("100"), "N")
("c, config", "The JSON-format configuration file to use", cxxopts::value<std::string>(), "FILE")
("h, help", "Print this help")
;
auto result = options.parse(argc, argv);
if (result.count("help"))
{
std::cout << options.help({""}) << std::endl;
}
else
{
CCServer server(result);
ret = server.start();
}
}
catch (const cxxopts::OptionException& e)
{
std::cout << "error parsing options: " << e.what() << std::endl;
ret = EINVAL;
}
return ret;
}

View file

@ -33,6 +33,7 @@
"pools": [
{
"algo": null,
"coin": null,
"url": "donate.graef.in:80",
"user": "YOUR_WALLET_ADDRESS",
"pass": "x",

View file

@ -1,27 +1,26 @@
{
"background": false, // true to run the cc-server in the background (no console)
"colors": true, // false to disable colored output
"log-file": null, // log all output to a file
"syslog": false, // use system log for output messages
"cc-server": {
"port": 3344, // port the CC Server will listens on
"use-tls" : false, // use tls for CC communication (needs to be enabled on miners too)
"cert-file" : "server.pem", // when tls is turned on, use this to point to the right cert file
"key-file" : "server.key", // when tls is turned on, use this to point to the right key file
"access-token": "mySecret", // access token for CC Clients (should be set!!!)
"user": "admin", // admin user for access CC Dashboard
"pass": "pass", // admin pass for access CC Dashboard
"client-config-folder" : null, // folder which contains the client-config files (null=current)
"client-log-lines-history" : 100, // maximum lines of log history kept per miner
"custom-dashboard" : "index.html", // dashboard html file
// Pushnotification Howto @ https://github.com/Bendr0id/xmrigCC/wiki/Setup-Pushover
"pushover-user-key" : "", // your user key for pushover notifications
"pushover-api-token" : "", // api token/keytoken of the application for pushover notifications
// Telegram Howto @ https://github.com/Bendr0id/xmrigCC/wiki/Setup-Telegram
"telegram-bot-token" : "", // pushover token to use for push notifications
"telegram-chat-id" : "", // pushover token to use for push notifications
"push-miner-offline-info" : true, // push notification for offline miners
"push-miner-zero-hash-info" : true, // push notification when miner reports 0 hashrate
"push-periodic-mining-status" : true // push periodic status notification (every hour)
}
"background": false, // true to run the cc-server in the background (no console)
"colors": true, // false to disable colored output
"log-file": null, // log all output to a file
"syslog": false, // use system log for output messages
"bind-ip": "0.0.0.0", // ip the CC Server will listens on
"port": 3344, // port the CC Server will listens on
"user": "admin", // admin user for access CC Dashboard
"pass": "pass", // admin pass for access CC Dashboard
"access-token": "mySecret", // access token for CC Clients (should be set!!!)
"use-tls" : false, // use tls for CC communication (needs to be enabled on miners too)
"cert-file" : "server.pem", // when tls is turned on, use this to point to the right cert file
"key-file" : "server.key", // when tls is turned on, use this to point to the right key file
"client-config-folder" : null, // folder which contains the client-config files (null=current)
"client-log-lines-history" : 100, // maximum lines of log history kept per miner
"custom-dashboard" : "index.html", // dashboard html file
// Pushnotification Howto @ https://github.com/Bendr0id/xmrigCC/wiki/Setup-Pushover
"pushover-user-key" : "", // your user key for pushover notifications
"pushover-api-token" : "", // api token/keytoken of the application for pushover notifications
// Telegram Howto @ https://github.com/Bendr0id/xmrigCC/wiki/Setup-Telegram
"telegram-bot-token" : "", // pushover token to use for push notifications
"telegram-chat-id" : "", // pushover token to use for push notifications
"push-miner-offline-info" : true, // push notification for offline miners
"push-miner-zero-hash-info" : true, // push notification when miner reports 0 hashrate
"push-periodic-mining-status" : true // push periodic status notification (every hour)
}

View file

@ -115,16 +115,15 @@ public:
{
active = true;
if (reset) {
Nonce::reset(job.index());
}
for (IBackend *backend : backends) {
backend->setJob(job);
}
if (reset) {
Nonce::reset(job.index());
}
else {
Nonce::touch();
}
Nonce::touch();
if (enabled) {
Nonce::pause(false);;
@ -499,7 +498,6 @@ void xmrig::Miner::onRequest(IApiRequest &request)
}
#endif
#ifdef XMRIG_FEATURE_CC_CLIENT
void xmrig::Miner::onUpdateRequest(ClientStatus& clientStatus)
{

View file

@ -67,6 +67,7 @@ R"===(
"pools": [
{
"algo": null,
"coin": null,
"url": "donate.graef.in:80",
"user": "YOUR_WALLET_ADDRESS",
"pass": "x",
@ -94,7 +95,7 @@ R"===(
"retry-pause": 5,
"syslog": false,
"user-agent": null,
"watch": false
"watch": true
}
)===";
#endif

View file

@ -45,6 +45,7 @@ static const char short_options[] = "a:c:kBp:Px:r:R:s:t:T:o:u:O:v:l:S";
static const option options[] = {
{ "algo", 1, nullptr, IConfig::AlgorithmKey },
{ "coin", 1, nullptr, IConfig::CoinKey },
{ "api-worker-id", 1, nullptr, IConfig::ApiWorkerIdKey },
{ "api-id", 1, nullptr, IConfig::ApiIdKey },
{ "http-enabled", 0, nullptr, IConfig::HttpEnabledKey },

View file

@ -68,6 +68,7 @@ Options:\n\
rx/wow, rx/loki\n"
#endif
"\
--coin=COIN specify coin instead of algorithm\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\

View file

@ -105,6 +105,43 @@ public:
return ((memory(algo) - 1) / 16) * 16;
}
inline static Algorithm::Id base(Algorithm::Id algo)
{
switch (algo)
{
case Algorithm::CN_0:
case Algorithm::CN_XAO:
case Algorithm::CN_CONCEAL:
# ifdef XMRIG_ALGO_CN_LITE
case Algorithm::CN_LITE_0:
# endif
# ifdef XMRIG_ALGO_CN_HEAVY
case Algorithm::CN_HEAVY_0:
case Algorithm::CN_HEAVY_XHV:
# endif
return Algorithm::CN_0;
# ifdef XMRIG_ALGO_CN_GPU
case Algorithm::CN_GPU:
Algorithm::CN_GPU,
# endif
case Algorithm::CN_1:
case Algorithm::CN_FAST:
case Algorithm::CN_RTO:
# ifdef XMRIG_ALGO_CN_LITE
case Algorithm::CN_LITE_1:
# endif
# ifdef XMRIG_ALGO_CN_HEAVY
case Algorithm::CN_HEAVY_TUBE:
# endif
return Algorithm::CN_1;
default:
return Algorithm::CN_2;
}
}
private:
constexpr const static size_t CN_MEMORY = 0x200000;
constexpr const static uint32_t CN_ITER = 0x80000;

View file

@ -260,20 +260,6 @@ const static uint8_t test_output_double[160] = {
0x5E, 0x2E, 0xC1, 0x80, 0x89, 0x39, 0xB3, 0x54, 0x39, 0x52, 0x0E, 0x69, 0x3D, 0xF6, 0xC5, 0x4A
};
// "cn/conceal"
const static uint8_t test_output_conceal[160] = {
0xB3, 0xA1, 0x67, 0x86, 0xD2, 0xC9, 0x85, 0xEC, 0xAD, 0xC4, 0x5F, 0x91, 0x05, 0x27, 0xC7, 0xA1,
0x96, 0xF0, 0xE1, 0xE9, 0x7C, 0x87, 0x09, 0x38, 0x1D, 0x7D, 0x41, 0x93, 0x35, 0xF8, 0x16, 0x72,
0xC3, 0xBD, 0x8D, 0xE8, 0xD5, 0xAE, 0xB8, 0x59, 0x0A, 0x6C, 0xCB, 0x7B, 0x41, 0x30, 0xF7, 0x04,
0xA5, 0x7C, 0xF9, 0xCA, 0x20, 0x49, 0x9C, 0xFD, 0xE8, 0x43, 0xCF, 0x66, 0x78, 0xEA, 0x76, 0xDD,
0x91, 0x0C, 0xDE, 0x29, 0x2A, 0xE0, 0xA8, 0xCA, 0xBC, 0xAA, 0x53, 0x4C, 0x93, 0x3E, 0x7B, 0x2C,
0xF1, 0xF9, 0xE1, 0x98, 0xB2, 0x92, 0x1E, 0x19, 0x93, 0x2A, 0x74, 0x9D, 0xDB, 0x10, 0x0F, 0x16,
0xD5, 0x3D, 0xE4, 0xC4, 0x23, 0xD9, 0x2E, 0xFD, 0x79, 0x8D, 0x1E, 0x48, 0x4E, 0x46, 0x08, 0x6C,
0xFF, 0x8A, 0x49, 0xFA, 0x1E, 0xB0, 0xB6, 0x9A, 0x47, 0x1C, 0xC6, 0x30, 0x36, 0x5D, 0xFD, 0x76,
0x10, 0x07, 0x44, 0xE6, 0xC8, 0x20, 0x2A, 0x84, 0x9D, 0x70, 0x22, 0x00, 0x8B, 0x9B, 0xBD, 0x8D,
0x27, 0x49, 0xA6, 0x06, 0xDC, 0xF0, 0xA1, 0x4B, 0x50, 0xA0, 0x12, 0xCD, 0x77, 0x01, 0x4C, 0x28
};
#ifdef XMRIG_ALGO_CN_LITE
// "cn-lite/0"
const static uint8_t test_output_v0_lite[160] = {

View file

@ -116,9 +116,8 @@ static AlgoName const algorithm_names[] = {
{ "cryptonight-extremelite", nullptr, Algorithm::CN_EXTREMELITE_0},
# endif
# ifdef XMRIG_ALGO_RANDOMX
{ "randomx/0", "rx/0", Algorithm::RX_0 },
{ "randomx/test", "rx/test", Algorithm::RX_0 },
{ "randomx/0", "rx/0", Algorithm::RX_0 },
{ "randomx/0", "rx/0", Algorithm::RX_0 },
{ "RandomX", "rx", Algorithm::RX_0 },
{ "randomx/wow", "rx/wow", Algorithm::RX_WOW },
{ "RandomWOW", nullptr, Algorithm::RX_WOW },

103
src/crypto/common/Coin.cpp Normal file
View file

@ -0,0 +1,103 @@
/* 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 "crypto/common/Coin.h"
#include "rapidjson/document.h"
#include <cstring>
#ifdef _MSC_VER
# define strcasecmp _stricmp
#endif
namespace xmrig {
struct CoinName
{
const char *name;
const Coin::Id id;
};
static CoinName const coin_names[] = {
{ "monero", Coin::MONERO },
{ "xmr", Coin::MONERO },
};
} /* namespace xmrig */
xmrig::Algorithm::Id xmrig::Coin::algorithm(uint8_t blobVersion) const
{
if (id() == MONERO) {
return (blobVersion >= 12) ? Algorithm::RX_0 : Algorithm::CN_R;
}
return Algorithm::INVALID;
}
const char *xmrig::Coin::name() const
{
for (const auto &i : coin_names) {
if (i.id == m_id) {
return i.name;
}
}
return nullptr;
}
rapidjson::Value xmrig::Coin::toJSON() const
{
using namespace rapidjson;
return isValid() ? Value(StringRef(name())) : Value(kNullType);
}
xmrig::Coin::Id xmrig::Coin::parse(const char *name)
{
if (name == nullptr || strlen(name) < 3) {
return INVALID;
}
for (const auto &i : coin_names) {
if (strcasecmp(name, i.name) == 0) {
return i.id;
}
}
return INVALID;
}

75
src/crypto/common/Coin.h Normal file
View file

@ -0,0 +1,75 @@
/* 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_COIN_H
#define XMRIG_COIN_H
#include "crypto/common/Algorithm.h"
#include "rapidjson/fwd.h"
namespace xmrig {
class Coin
{
public:
enum Id : int {
INVALID = -1,
MONERO,
};
Coin() = default;
inline Coin(const char *name) : m_id(parse(name)) {}
inline Coin(Id id) : m_id(id) {}
inline bool isEqual(const Coin &other) const { return m_id == other.m_id; }
inline bool isValid() const { return m_id != INVALID; }
inline Id id() const { return m_id; }
Algorithm::Id algorithm(uint8_t blobVersion) const;
const char *name() const;
rapidjson::Value toJSON() const;
inline bool operator!=(Coin::Id id) const { return m_id != id; }
inline bool operator!=(const Coin &other) const { return !isEqual(other); }
inline bool operator==(Coin::Id id) const { return m_id == id; }
inline bool operator==(const Coin &other) const { return isEqual(other); }
inline operator Coin::Id() const { return m_id; }
static Id parse(const char *name);
private:
Id m_id = INVALID;
};
} /* namespace xmrig */
#endif /* XMRIG_COIN_H */

View file

@ -78,7 +78,6 @@ void xmrig::Nonce::reset(uint8_t index)
std::lock_guard<std::mutex> lock(mutex);
m_nonces[index] = 0;
touch();
}

View file

@ -1,5 +1,3 @@
mov rdx, rax
and eax, RANDOMX_SCRATCHPAD_MASK
lea rcx, [rsi+rax]
push rcx
xor r8, qword ptr [rcx+0]
@ -10,8 +8,6 @@
xor r13, qword ptr [rcx+40]
xor r14, qword ptr [rcx+48]
xor r15, qword ptr [rcx+56]
ror rdx, 32
and edx, RANDOMX_SCRATCHPAD_MASK
lea rcx, [rsi+rdx]
push rcx
cvtdq2pd xmm0, qword ptr [rcx+0]

View file

@ -1,4 +1,3 @@
xor eax, eax
pop rcx
mov qword ptr [rcx+0], r8
mov qword ptr [rcx+8], r9

View file

@ -12,6 +12,13 @@
mov rcx, rdi
mov rbp, qword ptr [rsi] ;# "mx", "ma"
mov rdi, qword ptr [rsi+8] ;# uint8_t* dataset
;# dataset prefetch for the first iteration of the main loop
mov rax, rbp
shr rax, 32
and eax, RANDOMX_DATASET_BASE_MASK
prefetchnta byte ptr [rdi+rax]
mov rsi, rdx ;# uint8_t* scratchpad
mov rax, rbp

View file

@ -24,6 +24,13 @@
push rcx ;# RegisterFile& registerFile
mov rbp, qword ptr [rdx] ;# "mx", "ma"
mov rdi, qword ptr [rdx+8] ;# uint8_t* dataset
;# dataset prefetch for the first iteration of the main loop
mov rax, rbp
shr rax, 32
and eax, RANDOMX_DATASET_BASE_MASK
prefetchnta byte ptr [rdi+rax]
mov rsi, r8 ;# uint8_t* scratchpad
mov rbx, r9 ;# loop counter

View file

@ -3,8 +3,10 @@
#include <string.h>
#if defined(_MSC_VER)
#define FORCE_INLINE __inline
#elif defined(__GNUC__) || defined(__clang__)
#define FORCE_INLINE __forceinline
#elif defined(__GNUC__)
#define FORCE_INLINE __attribute__((always_inline)) inline
#elif defined(__clang__)
#define FORCE_INLINE __inline__
#else
#define FORCE_INLINE

View file

@ -76,6 +76,8 @@ namespace randomx {
*/
const uint8_t* codePrefetchScratchpad = (uint8_t*)&randomx_prefetch_scratchpad;
const uint8_t* codePrefetchScratchpadEnd = (uint8_t*)&randomx_prefetch_scratchpad_end;
const uint8_t* codePrologue = (uint8_t*)&randomx_program_prologue;
const uint8_t* codeLoopBegin = (uint8_t*)&randomx_program_loop_begin;
const uint8_t* codeLoopLoad = (uint8_t*)&randomx_program_loop_load;
@ -93,6 +95,7 @@ namespace randomx {
const uint8_t* codeShhEnd = (uint8_t*)&randomx_sshash_end;
const uint8_t* codeShhInit = (uint8_t*)&randomx_sshash_init;
const int32_t prefetchScratchpadSize = codePrefetchScratchpadEnd - codePrefetchScratchpad;
const int32_t prologueSize = codeLoopBegin - codePrologue;
const int32_t loopLoadSize = codeProgamStart - codeLoopLoad;
const int32_t readDatasetSize = codeReadDatasetLightSshInit - codeReadDataset;
@ -160,7 +163,7 @@ namespace randomx {
static const uint8_t REX_MAXPD[] = { 0x66, 0x41, 0x0f, 0x5f };
static const uint8_t REX_DIVPD[] = { 0x66, 0x41, 0x0f, 0x5e };
static const uint8_t SQRTPD[] = { 0x66, 0x0f, 0x51 };
static const uint8_t AND_OR_MOV_LDMXCSR[] = { 0x25, 0x00, 0x60, 0x00, 0x00, 0x0D, 0xC0, 0x9F, 0x00, 0x00, 0x50, 0x0F, 0xAE, 0x14, 0x24, 0x58 };
static const uint8_t AND_OR_MOV_LDMXCSR[] = { 0x25, 0x00, 0x60, 0x00, 0x00, 0x0D, 0xC0, 0x9F, 0x00, 0x00, 0x89, 0x44, 0x24, 0xFC, 0x0F, 0xAE, 0x54, 0x24, 0xFC };
static const uint8_t ROL_RAX[] = { 0x48, 0xc1, 0xc0 };
static const uint8_t XOR_ECX_ECX[] = { 0x33, 0xC9 };
static const uint8_t REX_CMP_R32I[] = { 0x41, 0x81 };
@ -214,7 +217,7 @@ namespace randomx {
generateProgramPrologue(prog, pcfg);
memcpy(code + codePos, RandomX_CurrentConfig.codeReadDatasetTweaked, readDatasetSize);
codePos += readDatasetSize;
generateProgramEpilogue(prog);
generateProgramEpilogue(prog, pcfg);
}
void JitCompilerX86::generateProgramLight(Program& prog, ProgramConfiguration& pcfg, uint32_t datasetOffset) {
@ -225,7 +228,7 @@ namespace randomx {
emitByte(CALL, code, codePos);
emit32(superScalarHashOffset - (codePos + 4), code, codePos);
emit(codeReadDatasetLightSshFin, readDatasetLightFinSize, code, codePos);
generateProgramEpilogue(prog);
generateProgramEpilogue(prog, pcfg);
}
template<size_t N>
@ -266,13 +269,16 @@ namespace randomx {
void JitCompilerX86::generateProgramPrologue(Program& prog, ProgramConfiguration& pcfg) {
memset(registerUsage, -1, sizeof(registerUsage));
codePos = ((uint8_t*)randomx_program_prologue_first_load) - ((uint8_t*)randomx_program_prologue);
code[codePos + 2] = 0xc0 + pcfg.readReg0;
code[codePos + 5] = 0xc0 + pcfg.readReg1;
*(uint32_t*)(code + codePos + 10) = RandomX_CurrentConfig.ScratchpadL3Mask64_Calculated;
*(uint32_t*)(code + codePos + 20) = RandomX_CurrentConfig.ScratchpadL3Mask64_Calculated;
codePos = prologueSize;
memcpy(code + codePos - 48, &pcfg.eMask, sizeof(pcfg.eMask));
emit(REX_XOR_RAX_R64, code, codePos);
emitByte(0xc0 + pcfg.readReg0, code, codePos);
emit(REX_XOR_RAX_R64, code, codePos);
emitByte(0xc0 + pcfg.readReg1, code, codePos);
memcpy(code + codePos, RandomX_CurrentConfig.codeLoopLoadTweaked, loopLoadSize);
memcpy(code + codePos, codeLoopLoad, loopLoadSize);
codePos += loopLoadSize;
for (unsigned i = 0; i < prog.getSize(); ++i) {
Instruction& instr = prog(i);
@ -287,7 +293,12 @@ namespace randomx {
emitByte(0xc0 + pcfg.readReg3, code, codePos);
}
void JitCompilerX86::generateProgramEpilogue(Program& prog) {
void JitCompilerX86::generateProgramEpilogue(Program& prog, ProgramConfiguration& pcfg) {
emit(REX_MOV_RR64, code, codePos);
emitByte(0xc0 + pcfg.readReg0, code, codePos);
emit(REX_XOR_RAX_R64, code, codePos);
emitByte(0xc0 + pcfg.readReg1, code, codePos);
emit(RandomX_CurrentConfig.codePrefetchScratchpadTweaked, prefetchScratchpadSize, code, codePos);
memcpy(code + codePos, codeLoopStore, loopStoreSize);
codePos += loopStoreSize;
emit(SUB_EBX, code, codePos);

View file

@ -72,7 +72,7 @@ namespace randomx {
int32_t codePos;
void generateProgramPrologue(Program&, ProgramConfiguration&);
void generateProgramEpilogue(Program&);
void generateProgramEpilogue(Program&, ProgramConfiguration&);
static void genAddressReg(Instruction&, uint8_t* code, int& codePos, bool rax = true);
static void genAddressRegDst(Instruction&, uint8_t* code, int& codePos);
static void genAddressImm(Instruction&, uint8_t* code, int& codePos);

View file

@ -37,7 +37,10 @@
#define WINABI
#endif
.global DECL(randomx_prefetch_scratchpad)
.global DECL(randomx_prefetch_scratchpad_end)
.global DECL(randomx_program_prologue)
.global DECL(randomx_program_prologue_first_load)
.global DECL(randomx_program_loop_begin)
.global DECL(randomx_program_loop_load)
.global DECL(randomx_program_start)
@ -61,6 +64,16 @@
#define db .byte
DECL(randomx_prefetch_scratchpad):
mov rdx, rax
and eax, RANDOMX_SCRATCHPAD_MASK
prefetcht0 [rsi+rax]
ror rdx, 32
and edx, RANDOMX_SCRATCHPAD_MASK
prefetcht0 [rsi+rdx]
DECL(randomx_prefetch_scratchpad_end):
.balign 64
DECL(randomx_program_prologue):
#if defined(WINABI)
@ -71,6 +84,14 @@ DECL(randomx_program_prologue):
movapd xmm13, xmmword ptr [mantissaMask+rip]
movapd xmm14, xmmword ptr [exp240+rip]
movapd xmm15, xmmword ptr [scaleMask+rip]
DECL(randomx_program_prologue_first_load):
xor rax, r8
xor rax, r8
mov rdx, rax
and eax, RANDOMX_SCRATCHPAD_MASK
ror rdx, 32
and edx, RANDOMX_SCRATCHPAD_MASK
jmp DECL(randomx_program_loop_begin)
.balign 64

View file

@ -28,7 +28,10 @@ IFDEF RAX
_RANDOMX_JITX86_STATIC SEGMENT PAGE READ EXECUTE
PUBLIC randomx_prefetch_scratchpad
PUBLIC randomx_prefetch_scratchpad_end
PUBLIC randomx_program_prologue
PUBLIC randomx_program_prologue_first_load
PUBLIC randomx_program_loop_begin
PUBLIC randomx_program_loop_load
PUBLIC randomx_program_start
@ -50,15 +53,36 @@ RANDOMX_SCRATCHPAD_MASK EQU 2097088
RANDOMX_DATASET_BASE_MASK EQU 2147483584
RANDOMX_CACHE_MASK EQU 4194303
randomx_prefetch_scratchpad PROC
mov rdx, rax
and eax, RANDOMX_SCRATCHPAD_MASK
prefetcht0 [rsi+rax]
ror rdx, 32
and edx, RANDOMX_SCRATCHPAD_MASK
prefetcht0 [rsi+rdx]
randomx_prefetch_scratchpad ENDP
randomx_prefetch_scratchpad_end PROC
randomx_prefetch_scratchpad_end ENDP
ALIGN 64
randomx_program_prologue PROC
include asm/program_prologue_win64.inc
movapd xmm13, xmmword ptr [mantissaMask]
movapd xmm14, xmmword ptr [exp240]
movapd xmm15, xmmword ptr [scaleMask]
jmp randomx_program_loop_begin
randomx_program_prologue ENDP
randomx_program_prologue_first_load PROC
xor rax, r8
xor rax, r8
mov rdx, rax
and eax, RANDOMX_SCRATCHPAD_MASK
ror rdx, 32
and edx, RANDOMX_SCRATCHPAD_MASK
jmp randomx_program_loop_begin
randomx_program_prologue_first_load ENDP
ALIGN 64
include asm/program_xmm_constants.inc

View file

@ -29,7 +29,10 @@ OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
#pragma once
extern "C" {
void randomx_prefetch_scratchpad();
void randomx_prefetch_scratchpad_end();
void randomx_program_prologue();
void randomx_program_prologue_first_load();
void randomx_program_loop_begin();
void randomx_program_loop_load();
void randomx_program_start();

View file

@ -149,9 +149,9 @@ RandomX_ConfigurationBase::RandomX_ConfigurationBase()
memcpy(codeReadDatasetLightSshInitTweaked, a, b - a);
}
{
const uint8_t* a = (const uint8_t*)&randomx_program_loop_load;
const uint8_t* b = (const uint8_t*)&randomx_program_start;
memcpy(codeLoopLoadTweaked, a, b - a);
const uint8_t* a = (const uint8_t*)&randomx_prefetch_scratchpad;
const uint8_t* b = (const uint8_t*)&randomx_prefetch_scratchpad_end;
memcpy(codePrefetchScratchpadTweaked, a, b - a);
}
#endif
}
@ -177,8 +177,8 @@ void RandomX_ConfigurationBase::Apply()
ScratchpadL3Mask64_Calculated = ((ScratchpadL3_Size / sizeof(uint64_t)) / 8 - 1) * 64;
#if defined(_M_X64) || defined(__x86_64__)
*(uint32_t*)(codeLoopLoadTweaked + 4) = ScratchpadL3Mask64_Calculated;
*(uint32_t*)(codeLoopLoadTweaked + 50) = ScratchpadL3Mask64_Calculated;
*(uint32_t*)(codePrefetchScratchpadTweaked + 4) = ScratchpadL3Mask64_Calculated;
*(uint32_t*)(codePrefetchScratchpadTweaked + 18) = ScratchpadL3Mask64_Calculated;
#endif
ConditionMask_Calculated = (1 << JumpBits) - 1;

View file

@ -116,7 +116,7 @@ struct RandomX_ConfigurationBase
uint8_t codeShhPrefetchTweaked[20];
uint8_t codeReadDatasetTweaked[64];
uint8_t codeReadDatasetLightSshInitTweaked[68];
uint8_t codeLoopLoadTweaked[140];
uint8_t codePrefetchScratchpadTweaked[32];
uint32_t CacheLineAlignMask_Calculated;
uint32_t DatasetExtraItems_Calculated;

View file

@ -1,5 +1,6 @@
/*
Copyright (c) 2018-2019, tevador <tevador@gmail.com>
Copyright (c) 2019 SChernykh <https://github.com/SChernykh>
All rights reserved.
@ -28,337 +29,91 @@ OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
#include "crypto/randomx/soft_aes.h"
alignas(16) const uint8_t sbox[256] = {
0x63, 0x7c, 0x77, 0x7b, 0xf2, 0x6b, 0x6f, 0xc5, 0x30, 0x01, 0x67, 0x2b, 0xfe, 0xd7, 0xab, 0x76,
0xca, 0x82, 0xc9, 0x7d, 0xfa, 0x59, 0x47, 0xf0, 0xad, 0xd4, 0xa2, 0xaf, 0x9c, 0xa4, 0x72, 0xc0,
0xb7, 0xfd, 0x93, 0x26, 0x36, 0x3f, 0xf7, 0xcc, 0x34, 0xa5, 0xe5, 0xf1, 0x71, 0xd8, 0x31, 0x15,
0x04, 0xc7, 0x23, 0xc3, 0x18, 0x96, 0x05, 0x9a, 0x07, 0x12, 0x80, 0xe2, 0xeb, 0x27, 0xb2, 0x75,
0x09, 0x83, 0x2c, 0x1a, 0x1b, 0x6e, 0x5a, 0xa0, 0x52, 0x3b, 0xd6, 0xb3, 0x29, 0xe3, 0x2f, 0x84,
0x53, 0xd1, 0x00, 0xed, 0x20, 0xfc, 0xb1, 0x5b, 0x6a, 0xcb, 0xbe, 0x39, 0x4a, 0x4c, 0x58, 0xcf,
0xd0, 0xef, 0xaa, 0xfb, 0x43, 0x4d, 0x33, 0x85, 0x45, 0xf9, 0x02, 0x7f, 0x50, 0x3c, 0x9f, 0xa8,
0x51, 0xa3, 0x40, 0x8f, 0x92, 0x9d, 0x38, 0xf5, 0xbc, 0xb6, 0xda, 0x21, 0x10, 0xff, 0xf3, 0xd2,
0xcd, 0x0c, 0x13, 0xec, 0x5f, 0x97, 0x44, 0x17, 0xc4, 0xa7, 0x7e, 0x3d, 0x64, 0x5d, 0x19, 0x73,
0x60, 0x81, 0x4f, 0xdc, 0x22, 0x2a, 0x90, 0x88, 0x46, 0xee, 0xb8, 0x14, 0xde, 0x5e, 0x0b, 0xdb,
0xe0, 0x32, 0x3a, 0x0a, 0x49, 0x06, 0x24, 0x5c, 0xc2, 0xd3, 0xac, 0x62, 0x91, 0x95, 0xe4, 0x79,
0xe7, 0xc8, 0x37, 0x6d, 0x8d, 0xd5, 0x4e, 0xa9, 0x6c, 0x56, 0xf4, 0xea, 0x65, 0x7a, 0xae, 0x08,
0xba, 0x78, 0x25, 0x2e, 0x1c, 0xa6, 0xb4, 0xc6, 0xe8, 0xdd, 0x74, 0x1f, 0x4b, 0xbd, 0x8b, 0x8a,
0x70, 0x3e, 0xb5, 0x66, 0x48, 0x03, 0xf6, 0x0e, 0x61, 0x35, 0x57, 0xb9, 0x86, 0xc1, 0x1d, 0x9e,
0xe1, 0xf8, 0x98, 0x11, 0x69, 0xd9, 0x8e, 0x94, 0x9b, 0x1e, 0x87, 0xe9, 0xce, 0x55, 0x28, 0xdf,
0x8c, 0xa1, 0x89, 0x0d, 0xbf, 0xe6, 0x42, 0x68, 0x41, 0x99, 0x2d, 0x0f, 0xb0, 0x54, 0xbb, 0x16,
};
alignas(64) uint32_t lutEnc0[256];
alignas(64) uint32_t lutEnc1[256];
alignas(64) uint32_t lutEnc2[256];
alignas(64) uint32_t lutEnc3[256];
alignas(16) const uint32_t lutEnc0[256] = {
0xa56363c6, 0x847c7cf8, 0x997777ee, 0x8d7b7bf6, 0x0df2f2ff, 0xbd6b6bd6, 0xb16f6fde, 0x54c5c591,
0x50303060, 0x03010102, 0xa96767ce, 0x7d2b2b56, 0x19fefee7, 0x62d7d7b5, 0xe6abab4d, 0x9a7676ec,
0x45caca8f, 0x9d82821f, 0x40c9c989, 0x877d7dfa, 0x15fafaef, 0xeb5959b2, 0xc947478e, 0x0bf0f0fb,
0xecadad41, 0x67d4d4b3, 0xfda2a25f, 0xeaafaf45, 0xbf9c9c23, 0xf7a4a453, 0x967272e4, 0x5bc0c09b,
0xc2b7b775, 0x1cfdfde1, 0xae93933d, 0x6a26264c, 0x5a36366c, 0x413f3f7e, 0x02f7f7f5, 0x4fcccc83,
0x5c343468, 0xf4a5a551, 0x34e5e5d1, 0x08f1f1f9, 0x937171e2, 0x73d8d8ab, 0x53313162, 0x3f15152a,
0x0c040408, 0x52c7c795, 0x65232346, 0x5ec3c39d, 0x28181830, 0xa1969637, 0x0f05050a, 0xb59a9a2f,
0x0907070e, 0x36121224, 0x9b80801b, 0x3de2e2df, 0x26ebebcd, 0x6927274e, 0xcdb2b27f, 0x9f7575ea,
0x1b090912, 0x9e83831d, 0x742c2c58, 0x2e1a1a34, 0x2d1b1b36, 0xb26e6edc, 0xee5a5ab4, 0xfba0a05b,
0xf65252a4, 0x4d3b3b76, 0x61d6d6b7, 0xceb3b37d, 0x7b292952, 0x3ee3e3dd, 0x712f2f5e, 0x97848413,
0xf55353a6, 0x68d1d1b9, 0x00000000, 0x2cededc1, 0x60202040, 0x1ffcfce3, 0xc8b1b179, 0xed5b5bb6,
0xbe6a6ad4, 0x46cbcb8d, 0xd9bebe67, 0x4b393972, 0xde4a4a94, 0xd44c4c98, 0xe85858b0, 0x4acfcf85,
0x6bd0d0bb, 0x2aefefc5, 0xe5aaaa4f, 0x16fbfbed, 0xc5434386, 0xd74d4d9a, 0x55333366, 0x94858511,
0xcf45458a, 0x10f9f9e9, 0x06020204, 0x817f7ffe, 0xf05050a0, 0x443c3c78, 0xba9f9f25, 0xe3a8a84b,
0xf35151a2, 0xfea3a35d, 0xc0404080, 0x8a8f8f05, 0xad92923f, 0xbc9d9d21, 0x48383870, 0x04f5f5f1,
0xdfbcbc63, 0xc1b6b677, 0x75dadaaf, 0x63212142, 0x30101020, 0x1affffe5, 0x0ef3f3fd, 0x6dd2d2bf,
0x4ccdcd81, 0x140c0c18, 0x35131326, 0x2fececc3, 0xe15f5fbe, 0xa2979735, 0xcc444488, 0x3917172e,
0x57c4c493, 0xf2a7a755, 0x827e7efc, 0x473d3d7a, 0xac6464c8, 0xe75d5dba, 0x2b191932, 0x957373e6,
0xa06060c0, 0x98818119, 0xd14f4f9e, 0x7fdcdca3, 0x66222244, 0x7e2a2a54, 0xab90903b, 0x8388880b,
0xca46468c, 0x29eeeec7, 0xd3b8b86b, 0x3c141428, 0x79dedea7, 0xe25e5ebc, 0x1d0b0b16, 0x76dbdbad,
0x3be0e0db, 0x56323264, 0x4e3a3a74, 0x1e0a0a14, 0xdb494992, 0x0a06060c, 0x6c242448, 0xe45c5cb8,
0x5dc2c29f, 0x6ed3d3bd, 0xefacac43, 0xa66262c4, 0xa8919139, 0xa4959531, 0x37e4e4d3, 0x8b7979f2,
0x32e7e7d5, 0x43c8c88b, 0x5937376e, 0xb76d6dda, 0x8c8d8d01, 0x64d5d5b1, 0xd24e4e9c, 0xe0a9a949,
0xb46c6cd8, 0xfa5656ac, 0x07f4f4f3, 0x25eaeacf, 0xaf6565ca, 0x8e7a7af4, 0xe9aeae47, 0x18080810,
0xd5baba6f, 0x887878f0, 0x6f25254a, 0x722e2e5c, 0x241c1c38, 0xf1a6a657, 0xc7b4b473, 0x51c6c697,
0x23e8e8cb, 0x7cdddda1, 0x9c7474e8, 0x211f1f3e, 0xdd4b4b96, 0xdcbdbd61, 0x868b8b0d, 0x858a8a0f,
0x907070e0, 0x423e3e7c, 0xc4b5b571, 0xaa6666cc, 0xd8484890, 0x05030306, 0x01f6f6f7, 0x120e0e1c,
0xa36161c2, 0x5f35356a, 0xf95757ae, 0xd0b9b969, 0x91868617, 0x58c1c199, 0x271d1d3a, 0xb99e9e27,
0x38e1e1d9, 0x13f8f8eb, 0xb398982b, 0x33111122, 0xbb6969d2, 0x70d9d9a9, 0x898e8e07, 0xa7949433,
0xb69b9b2d, 0x221e1e3c, 0x92878715, 0x20e9e9c9, 0x49cece87, 0xff5555aa, 0x78282850, 0x7adfdfa5,
0x8f8c8c03, 0xf8a1a159, 0x80898909, 0x170d0d1a, 0xdabfbf65, 0x31e6e6d7, 0xc6424284, 0xb86868d0,
0xc3414182, 0xb0999929, 0x772d2d5a, 0x110f0f1e, 0xcbb0b07b, 0xfc5454a8, 0xd6bbbb6d, 0x3a16162c,
};
alignas(64) uint32_t lutDec0[256];
alignas(64) uint32_t lutDec1[256];
alignas(64) uint32_t lutDec2[256];
alignas(64) uint32_t lutDec3[256];
alignas(16) const uint32_t lutEnc1[256] = {
0x6363c6a5, 0x7c7cf884, 0x7777ee99, 0x7b7bf68d, 0xf2f2ff0d, 0x6b6bd6bd, 0x6f6fdeb1, 0xc5c59154,
0x30306050, 0x01010203, 0x6767cea9, 0x2b2b567d, 0xfefee719, 0xd7d7b562, 0xabab4de6, 0x7676ec9a,
0xcaca8f45, 0x82821f9d, 0xc9c98940, 0x7d7dfa87, 0xfafaef15, 0x5959b2eb, 0x47478ec9, 0xf0f0fb0b,
0xadad41ec, 0xd4d4b367, 0xa2a25ffd, 0xafaf45ea, 0x9c9c23bf, 0xa4a453f7, 0x7272e496, 0xc0c09b5b,
0xb7b775c2, 0xfdfde11c, 0x93933dae, 0x26264c6a, 0x36366c5a, 0x3f3f7e41, 0xf7f7f502, 0xcccc834f,
0x3434685c, 0xa5a551f4, 0xe5e5d134, 0xf1f1f908, 0x7171e293, 0xd8d8ab73, 0x31316253, 0x15152a3f,
0x0404080c, 0xc7c79552, 0x23234665, 0xc3c39d5e, 0x18183028, 0x969637a1, 0x05050a0f, 0x9a9a2fb5,
0x07070e09, 0x12122436, 0x80801b9b, 0xe2e2df3d, 0xebebcd26, 0x27274e69, 0xb2b27fcd, 0x7575ea9f,
0x0909121b, 0x83831d9e, 0x2c2c5874, 0x1a1a342e, 0x1b1b362d, 0x6e6edcb2, 0x5a5ab4ee, 0xa0a05bfb,
0x5252a4f6, 0x3b3b764d, 0xd6d6b761, 0xb3b37dce, 0x2929527b, 0xe3e3dd3e, 0x2f2f5e71, 0x84841397,
0x5353a6f5, 0xd1d1b968, 0x00000000, 0xededc12c, 0x20204060, 0xfcfce31f, 0xb1b179c8, 0x5b5bb6ed,
0x6a6ad4be, 0xcbcb8d46, 0xbebe67d9, 0x3939724b, 0x4a4a94de, 0x4c4c98d4, 0x5858b0e8, 0xcfcf854a,
0xd0d0bb6b, 0xefefc52a, 0xaaaa4fe5, 0xfbfbed16, 0x434386c5, 0x4d4d9ad7, 0x33336655, 0x85851194,
0x45458acf, 0xf9f9e910, 0x02020406, 0x7f7ffe81, 0x5050a0f0, 0x3c3c7844, 0x9f9f25ba, 0xa8a84be3,
0x5151a2f3, 0xa3a35dfe, 0x404080c0, 0x8f8f058a, 0x92923fad, 0x9d9d21bc, 0x38387048, 0xf5f5f104,
0xbcbc63df, 0xb6b677c1, 0xdadaaf75, 0x21214263, 0x10102030, 0xffffe51a, 0xf3f3fd0e, 0xd2d2bf6d,
0xcdcd814c, 0x0c0c1814, 0x13132635, 0xececc32f, 0x5f5fbee1, 0x979735a2, 0x444488cc, 0x17172e39,
0xc4c49357, 0xa7a755f2, 0x7e7efc82, 0x3d3d7a47, 0x6464c8ac, 0x5d5dbae7, 0x1919322b, 0x7373e695,
0x6060c0a0, 0x81811998, 0x4f4f9ed1, 0xdcdca37f, 0x22224466, 0x2a2a547e, 0x90903bab, 0x88880b83,
0x46468cca, 0xeeeec729, 0xb8b86bd3, 0x1414283c, 0xdedea779, 0x5e5ebce2, 0x0b0b161d, 0xdbdbad76,
0xe0e0db3b, 0x32326456, 0x3a3a744e, 0x0a0a141e, 0x494992db, 0x06060c0a, 0x2424486c, 0x5c5cb8e4,
0xc2c29f5d, 0xd3d3bd6e, 0xacac43ef, 0x6262c4a6, 0x919139a8, 0x959531a4, 0xe4e4d337, 0x7979f28b,
0xe7e7d532, 0xc8c88b43, 0x37376e59, 0x6d6ddab7, 0x8d8d018c, 0xd5d5b164, 0x4e4e9cd2, 0xa9a949e0,
0x6c6cd8b4, 0x5656acfa, 0xf4f4f307, 0xeaeacf25, 0x6565caaf, 0x7a7af48e, 0xaeae47e9, 0x08081018,
0xbaba6fd5, 0x7878f088, 0x25254a6f, 0x2e2e5c72, 0x1c1c3824, 0xa6a657f1, 0xb4b473c7, 0xc6c69751,
0xe8e8cb23, 0xdddda17c, 0x7474e89c, 0x1f1f3e21, 0x4b4b96dd, 0xbdbd61dc, 0x8b8b0d86, 0x8a8a0f85,
0x7070e090, 0x3e3e7c42, 0xb5b571c4, 0x6666ccaa, 0x484890d8, 0x03030605, 0xf6f6f701, 0x0e0e1c12,
0x6161c2a3, 0x35356a5f, 0x5757aef9, 0xb9b969d0, 0x86861791, 0xc1c19958, 0x1d1d3a27, 0x9e9e27b9,
0xe1e1d938, 0xf8f8eb13, 0x98982bb3, 0x11112233, 0x6969d2bb, 0xd9d9a970, 0x8e8e0789, 0x949433a7,
0x9b9b2db6, 0x1e1e3c22, 0x87871592, 0xe9e9c920, 0xcece8749, 0x5555aaff, 0x28285078, 0xdfdfa57a,
0x8c8c038f, 0xa1a159f8, 0x89890980, 0x0d0d1a17, 0xbfbf65da, 0xe6e6d731, 0x424284c6, 0x6868d0b8,
0x414182c3, 0x999929b0, 0x2d2d5a77, 0x0f0f1e11, 0xb0b07bcb, 0x5454a8fc, 0xbbbb6dd6, 0x16162c3a,
};
static uint32_t mul_gf2(uint32_t b, uint32_t c)
{
uint32_t s = 0;
for (uint32_t i = b, j = c, k = 1; (k < 0x100) && j; k <<= 1)
{
if (j & k)
{
s ^= i;
j ^= k;
}
alignas(16) const uint32_t lutEnc2[256] = {
0x63c6a563, 0x7cf8847c, 0x77ee9977, 0x7bf68d7b, 0xf2ff0df2, 0x6bd6bd6b, 0x6fdeb16f, 0xc59154c5,
0x30605030, 0x01020301, 0x67cea967, 0x2b567d2b, 0xfee719fe, 0xd7b562d7, 0xab4de6ab, 0x76ec9a76,
0xca8f45ca, 0x821f9d82, 0xc98940c9, 0x7dfa877d, 0xfaef15fa, 0x59b2eb59, 0x478ec947, 0xf0fb0bf0,
0xad41ecad, 0xd4b367d4, 0xa25ffda2, 0xaf45eaaf, 0x9c23bf9c, 0xa453f7a4, 0x72e49672, 0xc09b5bc0,
0xb775c2b7, 0xfde11cfd, 0x933dae93, 0x264c6a26, 0x366c5a36, 0x3f7e413f, 0xf7f502f7, 0xcc834fcc,
0x34685c34, 0xa551f4a5, 0xe5d134e5, 0xf1f908f1, 0x71e29371, 0xd8ab73d8, 0x31625331, 0x152a3f15,
0x04080c04, 0xc79552c7, 0x23466523, 0xc39d5ec3, 0x18302818, 0x9637a196, 0x050a0f05, 0x9a2fb59a,
0x070e0907, 0x12243612, 0x801b9b80, 0xe2df3de2, 0xebcd26eb, 0x274e6927, 0xb27fcdb2, 0x75ea9f75,
0x09121b09, 0x831d9e83, 0x2c58742c, 0x1a342e1a, 0x1b362d1b, 0x6edcb26e, 0x5ab4ee5a, 0xa05bfba0,
0x52a4f652, 0x3b764d3b, 0xd6b761d6, 0xb37dceb3, 0x29527b29, 0xe3dd3ee3, 0x2f5e712f, 0x84139784,
0x53a6f553, 0xd1b968d1, 0x00000000, 0xedc12ced, 0x20406020, 0xfce31ffc, 0xb179c8b1, 0x5bb6ed5b,
0x6ad4be6a, 0xcb8d46cb, 0xbe67d9be, 0x39724b39, 0x4a94de4a, 0x4c98d44c, 0x58b0e858, 0xcf854acf,
0xd0bb6bd0, 0xefc52aef, 0xaa4fe5aa, 0xfbed16fb, 0x4386c543, 0x4d9ad74d, 0x33665533, 0x85119485,
0x458acf45, 0xf9e910f9, 0x02040602, 0x7ffe817f, 0x50a0f050, 0x3c78443c, 0x9f25ba9f, 0xa84be3a8,
0x51a2f351, 0xa35dfea3, 0x4080c040, 0x8f058a8f, 0x923fad92, 0x9d21bc9d, 0x38704838, 0xf5f104f5,
0xbc63dfbc, 0xb677c1b6, 0xdaaf75da, 0x21426321, 0x10203010, 0xffe51aff, 0xf3fd0ef3, 0xd2bf6dd2,
0xcd814ccd, 0x0c18140c, 0x13263513, 0xecc32fec, 0x5fbee15f, 0x9735a297, 0x4488cc44, 0x172e3917,
0xc49357c4, 0xa755f2a7, 0x7efc827e, 0x3d7a473d, 0x64c8ac64, 0x5dbae75d, 0x19322b19, 0x73e69573,
0x60c0a060, 0x81199881, 0x4f9ed14f, 0xdca37fdc, 0x22446622, 0x2a547e2a, 0x903bab90, 0x880b8388,
0x468cca46, 0xeec729ee, 0xb86bd3b8, 0x14283c14, 0xdea779de, 0x5ebce25e, 0x0b161d0b, 0xdbad76db,
0xe0db3be0, 0x32645632, 0x3a744e3a, 0x0a141e0a, 0x4992db49, 0x060c0a06, 0x24486c24, 0x5cb8e45c,
0xc29f5dc2, 0xd3bd6ed3, 0xac43efac, 0x62c4a662, 0x9139a891, 0x9531a495, 0xe4d337e4, 0x79f28b79,
0xe7d532e7, 0xc88b43c8, 0x376e5937, 0x6ddab76d, 0x8d018c8d, 0xd5b164d5, 0x4e9cd24e, 0xa949e0a9,
0x6cd8b46c, 0x56acfa56, 0xf4f307f4, 0xeacf25ea, 0x65caaf65, 0x7af48e7a, 0xae47e9ae, 0x08101808,
0xba6fd5ba, 0x78f08878, 0x254a6f25, 0x2e5c722e, 0x1c38241c, 0xa657f1a6, 0xb473c7b4, 0xc69751c6,
0xe8cb23e8, 0xdda17cdd, 0x74e89c74, 0x1f3e211f, 0x4b96dd4b, 0xbd61dcbd, 0x8b0d868b, 0x8a0f858a,
0x70e09070, 0x3e7c423e, 0xb571c4b5, 0x66ccaa66, 0x4890d848, 0x03060503, 0xf6f701f6, 0x0e1c120e,
0x61c2a361, 0x356a5f35, 0x57aef957, 0xb969d0b9, 0x86179186, 0xc19958c1, 0x1d3a271d, 0x9e27b99e,
0xe1d938e1, 0xf8eb13f8, 0x982bb398, 0x11223311, 0x69d2bb69, 0xd9a970d9, 0x8e07898e, 0x9433a794,
0x9b2db69b, 0x1e3c221e, 0x87159287, 0xe9c920e9, 0xce8749ce, 0x55aaff55, 0x28507828, 0xdfa57adf,
0x8c038f8c, 0xa159f8a1, 0x89098089, 0x0d1a170d, 0xbf65dabf, 0xe6d731e6, 0x4284c642, 0x68d0b868,
0x4182c341, 0x9929b099, 0x2d5a772d, 0x0f1e110f, 0xb07bcbb0, 0x54a8fc54, 0xbb6dd6bb, 0x162c3a16,
};
i <<= 1;
if (i & 0x100)
i ^= (1 << 8) | (1 << 4) | (1 << 3) | (1 << 1) | (1 << 0);
}
alignas(16) const uint32_t lutEnc3[256] = {
0xc6a56363, 0xf8847c7c, 0xee997777, 0xf68d7b7b, 0xff0df2f2, 0xd6bd6b6b, 0xdeb16f6f, 0x9154c5c5,
0x60503030, 0x02030101, 0xcea96767, 0x567d2b2b, 0xe719fefe, 0xb562d7d7, 0x4de6abab, 0xec9a7676,
0x8f45caca, 0x1f9d8282, 0x8940c9c9, 0xfa877d7d, 0xef15fafa, 0xb2eb5959, 0x8ec94747, 0xfb0bf0f0,
0x41ecadad, 0xb367d4d4, 0x5ffda2a2, 0x45eaafaf, 0x23bf9c9c, 0x53f7a4a4, 0xe4967272, 0x9b5bc0c0,
0x75c2b7b7, 0xe11cfdfd, 0x3dae9393, 0x4c6a2626, 0x6c5a3636, 0x7e413f3f, 0xf502f7f7, 0x834fcccc,
0x685c3434, 0x51f4a5a5, 0xd134e5e5, 0xf908f1f1, 0xe2937171, 0xab73d8d8, 0x62533131, 0x2a3f1515,
0x080c0404, 0x9552c7c7, 0x46652323, 0x9d5ec3c3, 0x30281818, 0x37a19696, 0x0a0f0505, 0x2fb59a9a,
0x0e090707, 0x24361212, 0x1b9b8080, 0xdf3de2e2, 0xcd26ebeb, 0x4e692727, 0x7fcdb2b2, 0xea9f7575,
0x121b0909, 0x1d9e8383, 0x58742c2c, 0x342e1a1a, 0x362d1b1b, 0xdcb26e6e, 0xb4ee5a5a, 0x5bfba0a0,
0xa4f65252, 0x764d3b3b, 0xb761d6d6, 0x7dceb3b3, 0x527b2929, 0xdd3ee3e3, 0x5e712f2f, 0x13978484,
0xa6f55353, 0xb968d1d1, 0x00000000, 0xc12ceded, 0x40602020, 0xe31ffcfc, 0x79c8b1b1, 0xb6ed5b5b,
0xd4be6a6a, 0x8d46cbcb, 0x67d9bebe, 0x724b3939, 0x94de4a4a, 0x98d44c4c, 0xb0e85858, 0x854acfcf,
0xbb6bd0d0, 0xc52aefef, 0x4fe5aaaa, 0xed16fbfb, 0x86c54343, 0x9ad74d4d, 0x66553333, 0x11948585,
0x8acf4545, 0xe910f9f9, 0x04060202, 0xfe817f7f, 0xa0f05050, 0x78443c3c, 0x25ba9f9f, 0x4be3a8a8,
0xa2f35151, 0x5dfea3a3, 0x80c04040, 0x058a8f8f, 0x3fad9292, 0x21bc9d9d, 0x70483838, 0xf104f5f5,
0x63dfbcbc, 0x77c1b6b6, 0xaf75dada, 0x42632121, 0x20301010, 0xe51affff, 0xfd0ef3f3, 0xbf6dd2d2,
0x814ccdcd, 0x18140c0c, 0x26351313, 0xc32fecec, 0xbee15f5f, 0x35a29797, 0x88cc4444, 0x2e391717,
0x9357c4c4, 0x55f2a7a7, 0xfc827e7e, 0x7a473d3d, 0xc8ac6464, 0xbae75d5d, 0x322b1919, 0xe6957373,
0xc0a06060, 0x19988181, 0x9ed14f4f, 0xa37fdcdc, 0x44662222, 0x547e2a2a, 0x3bab9090, 0x0b838888,
0x8cca4646, 0xc729eeee, 0x6bd3b8b8, 0x283c1414, 0xa779dede, 0xbce25e5e, 0x161d0b0b, 0xad76dbdb,
0xdb3be0e0, 0x64563232, 0x744e3a3a, 0x141e0a0a, 0x92db4949, 0x0c0a0606, 0x486c2424, 0xb8e45c5c,
0x9f5dc2c2, 0xbd6ed3d3, 0x43efacac, 0xc4a66262, 0x39a89191, 0x31a49595, 0xd337e4e4, 0xf28b7979,
0xd532e7e7, 0x8b43c8c8, 0x6e593737, 0xdab76d6d, 0x018c8d8d, 0xb164d5d5, 0x9cd24e4e, 0x49e0a9a9,
0xd8b46c6c, 0xacfa5656, 0xf307f4f4, 0xcf25eaea, 0xcaaf6565, 0xf48e7a7a, 0x47e9aeae, 0x10180808,
0x6fd5baba, 0xf0887878, 0x4a6f2525, 0x5c722e2e, 0x38241c1c, 0x57f1a6a6, 0x73c7b4b4, 0x9751c6c6,
0xcb23e8e8, 0xa17cdddd, 0xe89c7474, 0x3e211f1f, 0x96dd4b4b, 0x61dcbdbd, 0x0d868b8b, 0x0f858a8a,
0xe0907070, 0x7c423e3e, 0x71c4b5b5, 0xccaa6666, 0x90d84848, 0x06050303, 0xf701f6f6, 0x1c120e0e,
0xc2a36161, 0x6a5f3535, 0xaef95757, 0x69d0b9b9, 0x17918686, 0x9958c1c1, 0x3a271d1d, 0x27b99e9e,
0xd938e1e1, 0xeb13f8f8, 0x2bb39898, 0x22331111, 0xd2bb6969, 0xa970d9d9, 0x07898e8e, 0x33a79494,
0x2db69b9b, 0x3c221e1e, 0x15928787, 0xc920e9e9, 0x8749cece, 0xaaff5555, 0x50782828, 0xa57adfdf,
0x038f8c8c, 0x59f8a1a1, 0x09808989, 0x1a170d0d, 0x65dabfbf, 0xd731e6e6, 0x84c64242, 0xd0b86868,
0x82c34141, 0x29b09999, 0x5a772d2d, 0x1e110f0f, 0x7bcbb0b0, 0xa8fc5454, 0x6dd6bbbb, 0x2c3a1616,
};
alignas(16) const uint32_t lutDec0[256] = {
0x50a7f451, 0x5365417e, 0xc3a4171a, 0x965e273a, 0xcb6bab3b, 0xf1459d1f, 0xab58faac, 0x9303e34b,
0x55fa3020, 0xf66d76ad, 0x9176cc88, 0x254c02f5, 0xfcd7e54f, 0xd7cb2ac5, 0x80443526, 0x8fa362b5,
0x495ab1de, 0x671bba25, 0x980eea45, 0xe1c0fe5d, 0x02752fc3, 0x12f04c81, 0xa397468d, 0xc6f9d36b,
0xe75f8f03, 0x959c9215, 0xeb7a6dbf, 0xda595295, 0x2d83bed4, 0xd3217458, 0x2969e049, 0x44c8c98e,
0x6a89c275, 0x78798ef4, 0x6b3e5899, 0xdd71b927, 0xb64fe1be, 0x17ad88f0, 0x66ac20c9, 0xb43ace7d,
0x184adf63, 0x82311ae5, 0x60335197, 0x457f5362, 0xe07764b1, 0x84ae6bbb, 0x1ca081fe, 0x942b08f9,
0x58684870, 0x19fd458f, 0x876cde94, 0xb7f87b52, 0x23d373ab, 0xe2024b72, 0x578f1fe3, 0x2aab5566,
0x0728ebb2, 0x03c2b52f, 0x9a7bc586, 0xa50837d3, 0xf2872830, 0xb2a5bf23, 0xba6a0302, 0x5c8216ed,
0x2b1ccf8a, 0x92b479a7, 0xf0f207f3, 0xa1e2694e, 0xcdf4da65, 0xd5be0506, 0x1f6234d1, 0x8afea6c4,
0x9d532e34, 0xa055f3a2, 0x32e18a05, 0x75ebf6a4, 0x39ec830b, 0xaaef6040, 0x069f715e, 0x51106ebd,
0xf98a213e, 0x3d06dd96, 0xae053edd, 0x46bde64d, 0xb58d5491, 0x055dc471, 0x6fd40604, 0xff155060,
0x24fb9819, 0x97e9bdd6, 0xcc434089, 0x779ed967, 0xbd42e8b0, 0x888b8907, 0x385b19e7, 0xdbeec879,
0x470a7ca1, 0xe90f427c, 0xc91e84f8, 0x00000000, 0x83868009, 0x48ed2b32, 0xac70111e, 0x4e725a6c,
0xfbff0efd, 0x5638850f, 0x1ed5ae3d, 0x27392d36, 0x64d90f0a, 0x21a65c68, 0xd1545b9b, 0x3a2e3624,
0xb1670a0c, 0x0fe75793, 0xd296eeb4, 0x9e919b1b, 0x4fc5c080, 0xa220dc61, 0x694b775a, 0x161a121c,
0x0aba93e2, 0xe52aa0c0, 0x43e0223c, 0x1d171b12, 0x0b0d090e, 0xadc78bf2, 0xb9a8b62d, 0xc8a91e14,
0x8519f157, 0x4c0775af, 0xbbdd99ee, 0xfd607fa3, 0x9f2601f7, 0xbcf5725c, 0xc53b6644, 0x347efb5b,
0x7629438b, 0xdcc623cb, 0x68fcedb6, 0x63f1e4b8, 0xcadc31d7, 0x10856342, 0x40229713, 0x2011c684,
0x7d244a85, 0xf83dbbd2, 0x1132f9ae, 0x6da129c7, 0x4b2f9e1d, 0xf330b2dc, 0xec52860d, 0xd0e3c177,
0x6c16b32b, 0x99b970a9, 0xfa489411, 0x2264e947, 0xc48cfca8, 0x1a3ff0a0, 0xd82c7d56, 0xef903322,
0xc74e4987, 0xc1d138d9, 0xfea2ca8c, 0x360bd498, 0xcf81f5a6, 0x28de7aa5, 0x268eb7da, 0xa4bfad3f,
0xe49d3a2c, 0x0d927850, 0x9bcc5f6a, 0x62467e54, 0xc2138df6, 0xe8b8d890, 0x5ef7392e, 0xf5afc382,
0xbe805d9f, 0x7c93d069, 0xa92dd56f, 0xb31225cf, 0x3b99acc8, 0xa77d1810, 0x6e639ce8, 0x7bbb3bdb,
0x097826cd, 0xf418596e, 0x01b79aec, 0xa89a4f83, 0x656e95e6, 0x7ee6ffaa, 0x08cfbc21, 0xe6e815ef,
0xd99be7ba, 0xce366f4a, 0xd4099fea, 0xd67cb029, 0xafb2a431, 0x31233f2a, 0x3094a5c6, 0xc066a235,
0x37bc4e74, 0xa6ca82fc, 0xb0d090e0, 0x15d8a733, 0x4a9804f1, 0xf7daec41, 0x0e50cd7f, 0x2ff69117,
0x8dd64d76, 0x4db0ef43, 0x544daacc, 0xdf0496e4, 0xe3b5d19e, 0x1b886a4c, 0xb81f2cc1, 0x7f516546,
0x04ea5e9d, 0x5d358c01, 0x737487fa, 0x2e410bfb, 0x5a1d67b3, 0x52d2db92, 0x335610e9, 0x1347d66d,
0x8c61d79a, 0x7a0ca137, 0x8e14f859, 0x893c13eb, 0xee27a9ce, 0x35c961b7, 0xede51ce1, 0x3cb1477a,
0x59dfd29c, 0x3f73f255, 0x79ce1418, 0xbf37c773, 0xeacdf753, 0x5baafd5f, 0x146f3ddf, 0x86db4478,
0x81f3afca, 0x3ec468b9, 0x2c342438, 0x5f40a3c2, 0x72c31d16, 0x0c25e2bc, 0x8b493c28, 0x41950dff,
0x7101a839, 0xdeb30c08, 0x9ce4b4d8, 0x90c15664, 0x6184cb7b, 0x70b632d5, 0x745c6c48, 0x4257b8d0,
};
alignas(16) const uint32_t lutDec1[256] = {
0xa7f45150, 0x65417e53, 0xa4171ac3, 0x5e273a96, 0x6bab3bcb, 0x459d1ff1, 0x58faacab, 0x03e34b93,
0xfa302055, 0x6d76adf6, 0x76cc8891, 0x4c02f525, 0xd7e54ffc, 0xcb2ac5d7, 0x44352680, 0xa362b58f,
0x5ab1de49, 0x1bba2567, 0x0eea4598, 0xc0fe5de1, 0x752fc302, 0xf04c8112, 0x97468da3, 0xf9d36bc6,
0x5f8f03e7, 0x9c921595, 0x7a6dbfeb, 0x595295da, 0x83bed42d, 0x217458d3, 0x69e04929, 0xc8c98e44,
0x89c2756a, 0x798ef478, 0x3e58996b, 0x71b927dd, 0x4fe1beb6, 0xad88f017, 0xac20c966, 0x3ace7db4,
0x4adf6318, 0x311ae582, 0x33519760, 0x7f536245, 0x7764b1e0, 0xae6bbb84, 0xa081fe1c, 0x2b08f994,
0x68487058, 0xfd458f19, 0x6cde9487, 0xf87b52b7, 0xd373ab23, 0x024b72e2, 0x8f1fe357, 0xab55662a,
0x28ebb207, 0xc2b52f03, 0x7bc5869a, 0x0837d3a5, 0x872830f2, 0xa5bf23b2, 0x6a0302ba, 0x8216ed5c,
0x1ccf8a2b, 0xb479a792, 0xf207f3f0, 0xe2694ea1, 0xf4da65cd, 0xbe0506d5, 0x6234d11f, 0xfea6c48a,
0x532e349d, 0x55f3a2a0, 0xe18a0532, 0xebf6a475, 0xec830b39, 0xef6040aa, 0x9f715e06, 0x106ebd51,
0x8a213ef9, 0x06dd963d, 0x053eddae, 0xbde64d46, 0x8d5491b5, 0x5dc47105, 0xd406046f, 0x155060ff,
0xfb981924, 0xe9bdd697, 0x434089cc, 0x9ed96777, 0x42e8b0bd, 0x8b890788, 0x5b19e738, 0xeec879db,
0x0a7ca147, 0x0f427ce9, 0x1e84f8c9, 0x00000000, 0x86800983, 0xed2b3248, 0x70111eac, 0x725a6c4e,
0xff0efdfb, 0x38850f56, 0xd5ae3d1e, 0x392d3627, 0xd90f0a64, 0xa65c6821, 0x545b9bd1, 0x2e36243a,
0x670a0cb1, 0xe757930f, 0x96eeb4d2, 0x919b1b9e, 0xc5c0804f, 0x20dc61a2, 0x4b775a69, 0x1a121c16,
0xba93e20a, 0x2aa0c0e5, 0xe0223c43, 0x171b121d, 0x0d090e0b, 0xc78bf2ad, 0xa8b62db9, 0xa91e14c8,
0x19f15785, 0x0775af4c, 0xdd99eebb, 0x607fa3fd, 0x2601f79f, 0xf5725cbc, 0x3b6644c5, 0x7efb5b34,
0x29438b76, 0xc623cbdc, 0xfcedb668, 0xf1e4b863, 0xdc31d7ca, 0x85634210, 0x22971340, 0x11c68420,
0x244a857d, 0x3dbbd2f8, 0x32f9ae11, 0xa129c76d, 0x2f9e1d4b, 0x30b2dcf3, 0x52860dec, 0xe3c177d0,
0x16b32b6c, 0xb970a999, 0x489411fa, 0x64e94722, 0x8cfca8c4, 0x3ff0a01a, 0x2c7d56d8, 0x903322ef,
0x4e4987c7, 0xd138d9c1, 0xa2ca8cfe, 0x0bd49836, 0x81f5a6cf, 0xde7aa528, 0x8eb7da26, 0xbfad3fa4,
0x9d3a2ce4, 0x9278500d, 0xcc5f6a9b, 0x467e5462, 0x138df6c2, 0xb8d890e8, 0xf7392e5e, 0xafc382f5,
0x805d9fbe, 0x93d0697c, 0x2dd56fa9, 0x1225cfb3, 0x99acc83b, 0x7d1810a7, 0x639ce86e, 0xbb3bdb7b,
0x7826cd09, 0x18596ef4, 0xb79aec01, 0x9a4f83a8, 0x6e95e665, 0xe6ffaa7e, 0xcfbc2108, 0xe815efe6,
0x9be7bad9, 0x366f4ace, 0x099fead4, 0x7cb029d6, 0xb2a431af, 0x233f2a31, 0x94a5c630, 0x66a235c0,
0xbc4e7437, 0xca82fca6, 0xd090e0b0, 0xd8a73315, 0x9804f14a, 0xdaec41f7, 0x50cd7f0e, 0xf691172f,
0xd64d768d, 0xb0ef434d, 0x4daacc54, 0x0496e4df, 0xb5d19ee3, 0x886a4c1b, 0x1f2cc1b8, 0x5165467f,
0xea5e9d04, 0x358c015d, 0x7487fa73, 0x410bfb2e, 0x1d67b35a, 0xd2db9252, 0x5610e933, 0x47d66d13,
0x61d79a8c, 0x0ca1377a, 0x14f8598e, 0x3c13eb89, 0x27a9ceee, 0xc961b735, 0xe51ce1ed, 0xb1477a3c,
0xdfd29c59, 0x73f2553f, 0xce141879, 0x37c773bf, 0xcdf753ea, 0xaafd5f5b, 0x6f3ddf14, 0xdb447886,
0xf3afca81, 0xc468b93e, 0x3424382c, 0x40a3c25f, 0xc31d1672, 0x25e2bc0c, 0x493c288b, 0x950dff41,
0x01a83971, 0xb30c08de, 0xe4b4d89c, 0xc1566490, 0x84cb7b61, 0xb632d570, 0x5c6c4874, 0x57b8d042,
};
alignas(16) const uint32_t lutDec2[256] = {
0xf45150a7, 0x417e5365, 0x171ac3a4, 0x273a965e, 0xab3bcb6b, 0x9d1ff145, 0xfaacab58, 0xe34b9303,
0x302055fa, 0x76adf66d, 0xcc889176, 0x02f5254c, 0xe54ffcd7, 0x2ac5d7cb, 0x35268044, 0x62b58fa3,
0xb1de495a, 0xba25671b, 0xea45980e, 0xfe5de1c0, 0x2fc30275, 0x4c8112f0, 0x468da397, 0xd36bc6f9,
0x8f03e75f, 0x9215959c, 0x6dbfeb7a, 0x5295da59, 0xbed42d83, 0x7458d321, 0xe0492969, 0xc98e44c8,
0xc2756a89, 0x8ef47879, 0x58996b3e, 0xb927dd71, 0xe1beb64f, 0x88f017ad, 0x20c966ac, 0xce7db43a,
0xdf63184a, 0x1ae58231, 0x51976033, 0x5362457f, 0x64b1e077, 0x6bbb84ae, 0x81fe1ca0, 0x08f9942b,
0x48705868, 0x458f19fd, 0xde94876c, 0x7b52b7f8, 0x73ab23d3, 0x4b72e202, 0x1fe3578f, 0x55662aab,
0xebb20728, 0xb52f03c2, 0xc5869a7b, 0x37d3a508, 0x2830f287, 0xbf23b2a5, 0x0302ba6a, 0x16ed5c82,
0xcf8a2b1c, 0x79a792b4, 0x07f3f0f2, 0x694ea1e2, 0xda65cdf4, 0x0506d5be, 0x34d11f62, 0xa6c48afe,
0x2e349d53, 0xf3a2a055, 0x8a0532e1, 0xf6a475eb, 0x830b39ec, 0x6040aaef, 0x715e069f, 0x6ebd5110,
0x213ef98a, 0xdd963d06, 0x3eddae05, 0xe64d46bd, 0x5491b58d, 0xc471055d, 0x06046fd4, 0x5060ff15,
0x981924fb, 0xbdd697e9, 0x4089cc43, 0xd967779e, 0xe8b0bd42, 0x8907888b, 0x19e7385b, 0xc879dbee,
0x7ca1470a, 0x427ce90f, 0x84f8c91e, 0x00000000, 0x80098386, 0x2b3248ed, 0x111eac70, 0x5a6c4e72,
0x0efdfbff, 0x850f5638, 0xae3d1ed5, 0x2d362739, 0x0f0a64d9, 0x5c6821a6, 0x5b9bd154, 0x36243a2e,
0x0a0cb167, 0x57930fe7, 0xeeb4d296, 0x9b1b9e91, 0xc0804fc5, 0xdc61a220, 0x775a694b, 0x121c161a,
0x93e20aba, 0xa0c0e52a, 0x223c43e0, 0x1b121d17, 0x090e0b0d, 0x8bf2adc7, 0xb62db9a8, 0x1e14c8a9,
0xf1578519, 0x75af4c07, 0x99eebbdd, 0x7fa3fd60, 0x01f79f26, 0x725cbcf5, 0x6644c53b, 0xfb5b347e,
0x438b7629, 0x23cbdcc6, 0xedb668fc, 0xe4b863f1, 0x31d7cadc, 0x63421085, 0x97134022, 0xc6842011,
0x4a857d24, 0xbbd2f83d, 0xf9ae1132, 0x29c76da1, 0x9e1d4b2f, 0xb2dcf330, 0x860dec52, 0xc177d0e3,
0xb32b6c16, 0x70a999b9, 0x9411fa48, 0xe9472264, 0xfca8c48c, 0xf0a01a3f, 0x7d56d82c, 0x3322ef90,
0x4987c74e, 0x38d9c1d1, 0xca8cfea2, 0xd498360b, 0xf5a6cf81, 0x7aa528de, 0xb7da268e, 0xad3fa4bf,
0x3a2ce49d, 0x78500d92, 0x5f6a9bcc, 0x7e546246, 0x8df6c213, 0xd890e8b8, 0x392e5ef7, 0xc382f5af,
0x5d9fbe80, 0xd0697c93, 0xd56fa92d, 0x25cfb312, 0xacc83b99, 0x1810a77d, 0x9ce86e63, 0x3bdb7bbb,
0x26cd0978, 0x596ef418, 0x9aec01b7, 0x4f83a89a, 0x95e6656e, 0xffaa7ee6, 0xbc2108cf, 0x15efe6e8,
0xe7bad99b, 0x6f4ace36, 0x9fead409, 0xb029d67c, 0xa431afb2, 0x3f2a3123, 0xa5c63094, 0xa235c066,
0x4e7437bc, 0x82fca6ca, 0x90e0b0d0, 0xa73315d8, 0x04f14a98, 0xec41f7da, 0xcd7f0e50, 0x91172ff6,
0x4d768dd6, 0xef434db0, 0xaacc544d, 0x96e4df04, 0xd19ee3b5, 0x6a4c1b88, 0x2cc1b81f, 0x65467f51,
0x5e9d04ea, 0x8c015d35, 0x87fa7374, 0x0bfb2e41, 0x67b35a1d, 0xdb9252d2, 0x10e93356, 0xd66d1347,
0xd79a8c61, 0xa1377a0c, 0xf8598e14, 0x13eb893c, 0xa9ceee27, 0x61b735c9, 0x1ce1ede5, 0x477a3cb1,
0xd29c59df, 0xf2553f73, 0x141879ce, 0xc773bf37, 0xf753eacd, 0xfd5f5baa, 0x3ddf146f, 0x447886db,
0xafca81f3, 0x68b93ec4, 0x24382c34, 0xa3c25f40, 0x1d1672c3, 0xe2bc0c25, 0x3c288b49, 0x0dff4195,
0xa8397101, 0x0c08deb3, 0xb4d89ce4, 0x566490c1, 0xcb7b6184, 0x32d570b6, 0x6c48745c, 0xb8d04257,
};
alignas(16) const uint32_t lutDec3[256] = {
0x5150a7f4, 0x7e536541, 0x1ac3a417, 0x3a965e27, 0x3bcb6bab, 0x1ff1459d, 0xacab58fa, 0x4b9303e3,
0x2055fa30, 0xadf66d76, 0x889176cc, 0xf5254c02, 0x4ffcd7e5, 0xc5d7cb2a, 0x26804435, 0xb58fa362,
0xde495ab1, 0x25671bba, 0x45980eea, 0x5de1c0fe, 0xc302752f, 0x8112f04c, 0x8da39746, 0x6bc6f9d3,
0x03e75f8f, 0x15959c92, 0xbfeb7a6d, 0x95da5952, 0xd42d83be, 0x58d32174, 0x492969e0, 0x8e44c8c9,
0x756a89c2, 0xf478798e, 0x996b3e58, 0x27dd71b9, 0xbeb64fe1, 0xf017ad88, 0xc966ac20, 0x7db43ace,
0x63184adf, 0xe582311a, 0x97603351, 0x62457f53, 0xb1e07764, 0xbb84ae6b, 0xfe1ca081, 0xf9942b08,
0x70586848, 0x8f19fd45, 0x94876cde, 0x52b7f87b, 0xab23d373, 0x72e2024b, 0xe3578f1f, 0x662aab55,
0xb20728eb, 0x2f03c2b5, 0x869a7bc5, 0xd3a50837, 0x30f28728, 0x23b2a5bf, 0x02ba6a03, 0xed5c8216,
0x8a2b1ccf, 0xa792b479, 0xf3f0f207, 0x4ea1e269, 0x65cdf4da, 0x06d5be05, 0xd11f6234, 0xc48afea6,
0x349d532e, 0xa2a055f3, 0x0532e18a, 0xa475ebf6, 0x0b39ec83, 0x40aaef60, 0x5e069f71, 0xbd51106e,
0x3ef98a21, 0x963d06dd, 0xddae053e, 0x4d46bde6, 0x91b58d54, 0x71055dc4, 0x046fd406, 0x60ff1550,
0x1924fb98, 0xd697e9bd, 0x89cc4340, 0x67779ed9, 0xb0bd42e8, 0x07888b89, 0xe7385b19, 0x79dbeec8,
0xa1470a7c, 0x7ce90f42, 0xf8c91e84, 0x00000000, 0x09838680, 0x3248ed2b, 0x1eac7011, 0x6c4e725a,
0xfdfbff0e, 0x0f563885, 0x3d1ed5ae, 0x3627392d, 0x0a64d90f, 0x6821a65c, 0x9bd1545b, 0x243a2e36,
0x0cb1670a, 0x930fe757, 0xb4d296ee, 0x1b9e919b, 0x804fc5c0, 0x61a220dc, 0x5a694b77, 0x1c161a12,
0xe20aba93, 0xc0e52aa0, 0x3c43e022, 0x121d171b, 0x0e0b0d09, 0xf2adc78b, 0x2db9a8b6, 0x14c8a91e,
0x578519f1, 0xaf4c0775, 0xeebbdd99, 0xa3fd607f, 0xf79f2601, 0x5cbcf572, 0x44c53b66, 0x5b347efb,
0x8b762943, 0xcbdcc623, 0xb668fced, 0xb863f1e4, 0xd7cadc31, 0x42108563, 0x13402297, 0x842011c6,
0x857d244a, 0xd2f83dbb, 0xae1132f9, 0xc76da129, 0x1d4b2f9e, 0xdcf330b2, 0x0dec5286, 0x77d0e3c1,
0x2b6c16b3, 0xa999b970, 0x11fa4894, 0x472264e9, 0xa8c48cfc, 0xa01a3ff0, 0x56d82c7d, 0x22ef9033,
0x87c74e49, 0xd9c1d138, 0x8cfea2ca, 0x98360bd4, 0xa6cf81f5, 0xa528de7a, 0xda268eb7, 0x3fa4bfad,
0x2ce49d3a, 0x500d9278, 0x6a9bcc5f, 0x5462467e, 0xf6c2138d, 0x90e8b8d8, 0x2e5ef739, 0x82f5afc3,
0x9fbe805d, 0x697c93d0, 0x6fa92dd5, 0xcfb31225, 0xc83b99ac, 0x10a77d18, 0xe86e639c, 0xdb7bbb3b,
0xcd097826, 0x6ef41859, 0xec01b79a, 0x83a89a4f, 0xe6656e95, 0xaa7ee6ff, 0x2108cfbc, 0xefe6e815,
0xbad99be7, 0x4ace366f, 0xead4099f, 0x29d67cb0, 0x31afb2a4, 0x2a31233f, 0xc63094a5, 0x35c066a2,
0x7437bc4e, 0xfca6ca82, 0xe0b0d090, 0x3315d8a7, 0xf14a9804, 0x41f7daec, 0x7f0e50cd, 0x172ff691,
0x768dd64d, 0x434db0ef, 0xcc544daa, 0xe4df0496, 0x9ee3b5d1, 0x4c1b886a, 0xc1b81f2c, 0x467f5165,
0x9d04ea5e, 0x015d358c, 0xfa737487, 0xfb2e410b, 0xb35a1d67, 0x9252d2db, 0xe9335610, 0x6d1347d6,
0x9a8c61d7, 0x377a0ca1, 0x598e14f8, 0xeb893c13, 0xceee27a9, 0xb735c961, 0xe1ede51c, 0x7a3cb147,
0x9c59dfd2, 0x553f73f2, 0x1879ce14, 0x73bf37c7, 0x53eacdf7, 0x5f5baafd, 0xdf146f3d, 0x7886db44,
0xca81f3af, 0xb93ec468, 0x382c3424, 0xc25f40a3, 0x1672c31d, 0xbc0c25e2, 0x288b493c, 0xff41950d,
0x397101a8, 0x08deb30c, 0xd89ce4b4, 0x6490c156, 0x7b6184cb, 0xd570b632, 0x48745c6c, 0xd04257b8,
};
rx_vec_i128 soft_aesenc(rx_vec_i128 in, rx_vec_i128 key) {
uint32_t s0, s1, s2, s3;
s0 = rx_vec_i128_w(in);
s1 = rx_vec_i128_z(in);
s2 = rx_vec_i128_y(in);
s3 = rx_vec_i128_x(in);
rx_vec_i128 out = rx_set_int_vec_i128(
(lutEnc0[s0 & 0xff] ^ lutEnc1[(s3 >> 8) & 0xff] ^ lutEnc2[(s2 >> 16) & 0xff] ^ lutEnc3[s1 >> 24]),
(lutEnc0[s1 & 0xff] ^ lutEnc1[(s0 >> 8) & 0xff] ^ lutEnc2[(s3 >> 16) & 0xff] ^ lutEnc3[s2 >> 24]),
(lutEnc0[s2 & 0xff] ^ lutEnc1[(s1 >> 8) & 0xff] ^ lutEnc2[(s0 >> 16) & 0xff] ^ lutEnc3[s3 >> 24]),
(lutEnc0[s3 & 0xff] ^ lutEnc1[(s2 >> 8) & 0xff] ^ lutEnc2[(s1 >> 16) & 0xff] ^ lutEnc3[s0 >> 24])
);
return rx_xor_vec_i128(out, key);
return s;
}
rx_vec_i128 soft_aesdec(rx_vec_i128 in, rx_vec_i128 key) {
uint32_t s0, s1, s2, s3;
#define ROTL8(x,shift) ((uint8_t) ((x) << (shift)) | ((x) >> (8 - (shift))))
s0 = rx_vec_i128_w(in);
s1 = rx_vec_i128_z(in);
s2 = rx_vec_i128_y(in);
s3 = rx_vec_i128_x(in);
static struct SAESInitializer
{
SAESInitializer()
{
static uint8_t sbox[256];
static uint8_t sbox_reverse[256];
rx_vec_i128 out = rx_set_int_vec_i128(
(lutDec0[s0 & 0xff] ^ lutDec1[(s1 >> 8) & 0xff] ^ lutDec2[(s2 >> 16) & 0xff] ^ lutDec3[s3 >> 24]),
(lutDec0[s1 & 0xff] ^ lutDec1[(s2 >> 8) & 0xff] ^ lutDec2[(s3 >> 16) & 0xff] ^ lutDec3[s0 >> 24]),
(lutDec0[s2 & 0xff] ^ lutDec1[(s3 >> 8) & 0xff] ^ lutDec2[(s0 >> 16) & 0xff] ^ lutDec3[s1 >> 24]),
(lutDec0[s3 & 0xff] ^ lutDec1[(s0 >> 8) & 0xff] ^ lutDec2[(s1 >> 16) & 0xff] ^ lutDec3[s2 >> 24])
);
uint8_t p = 1, q = 1;
return rx_xor_vec_i128(out, key);
}
do {
p = p ^ (p << 1) ^ (p & 0x80 ? 0x1B : 0);
q ^= q << 1;
q ^= q << 2;
q ^= q << 4;
q ^= (q & 0x80) ? 0x09 : 0;
const uint8_t value = q ^ ROTL8(q, 1) ^ ROTL8(q, 2) ^ ROTL8(q, 3) ^ ROTL8(q, 4) ^ 0x63;
sbox[p] = value;
sbox_reverse[value] = p;
} while (p != 1);
sbox[0] = 0x63;
sbox_reverse[0x63] = 0;
for (uint32_t i = 0; i < 0x100; ++i)
{
union
{
uint32_t w;
uint8_t p[4];
};
uint32_t s = sbox[i];
p[0] = mul_gf2(s, 2);
p[1] = s;
p[2] = s;
p[3] = mul_gf2(s, 3);
lutEnc0[i] = w; w = (w << 8) | (w >> 24);
lutEnc1[i] = w; w = (w << 8) | (w >> 24);
lutEnc2[i] = w; w = (w << 8) | (w >> 24);
lutEnc3[i] = w;
s = sbox_reverse[i];
p[0] = mul_gf2(s, 0xe);
p[1] = mul_gf2(s, 0x9);
p[2] = mul_gf2(s, 0xd);
p[3] = mul_gf2(s, 0xb);
lutDec0[i] = w; w = (w << 8) | (w >> 24);
lutDec1[i] = w; w = (w << 8) | (w >> 24);
lutDec2[i] = w; w = (w << 8) | (w >> 24);
lutDec3[i] = w;
}
}
} aes_initializer;

View file

@ -1,5 +1,6 @@
/*
Copyright (c) 2018-2019, tevador <tevador@gmail.com>
Copyright (c) 2019 SChernykh <https://github.com/SChernykh>
All rights reserved.
@ -31,16 +32,80 @@ OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
#include <stdint.h>
#include "crypto/randomx/intrin_portable.h"
rx_vec_i128 soft_aesenc(rx_vec_i128 in, rx_vec_i128 key);
extern uint32_t lutEnc0[256];
extern uint32_t lutEnc1[256];
extern uint32_t lutEnc2[256];
extern uint32_t lutEnc3[256];
extern uint32_t lutDec0[256];
extern uint32_t lutDec1[256];
extern uint32_t lutDec2[256];
extern uint32_t lutDec3[256];
rx_vec_i128 soft_aesdec(rx_vec_i128 in, rx_vec_i128 key);
template<bool soft> rx_vec_i128 aesenc(rx_vec_i128 in, rx_vec_i128 key);
template<bool soft> rx_vec_i128 aesdec(rx_vec_i128 in, rx_vec_i128 key);
template<bool soft>
inline rx_vec_i128 aesenc(rx_vec_i128 in, rx_vec_i128 key) {
return soft ? soft_aesenc(in, key) : rx_aesenc_vec_i128(in, key);
template<>
FORCE_INLINE rx_vec_i128 aesenc<true>(rx_vec_i128 in, rx_vec_i128 key) {
volatile uint8_t s[16];
memcpy((void*) s, &in, 16);
uint32_t s0 = lutEnc0[s[ 0]];
uint32_t s1 = lutEnc0[s[ 4]];
uint32_t s2 = lutEnc0[s[ 8]];
uint32_t s3 = lutEnc0[s[12]];
s0 ^= lutEnc1[s[ 5]];
s1 ^= lutEnc1[s[ 9]];
s2 ^= lutEnc1[s[13]];
s3 ^= lutEnc1[s[ 1]];
s0 ^= lutEnc2[s[10]];
s1 ^= lutEnc2[s[14]];
s2 ^= lutEnc2[s[ 2]];
s3 ^= lutEnc2[s[ 6]];
s0 ^= lutEnc3[s[15]];
s1 ^= lutEnc3[s[ 3]];
s2 ^= lutEnc3[s[ 7]];
s3 ^= lutEnc3[s[11]];
return rx_xor_vec_i128(rx_set_int_vec_i128(s3, s2, s1, s0), key);
}
template<bool soft>
inline rx_vec_i128 aesdec(rx_vec_i128 in, rx_vec_i128 key) {
return soft ? soft_aesdec(in, key) : rx_aesdec_vec_i128(in, key);
template<>
FORCE_INLINE rx_vec_i128 aesdec<true>(rx_vec_i128 in, rx_vec_i128 key) {
volatile uint8_t s[16];
memcpy((void*) s, &in, 16);
uint32_t s0 = lutDec0[s[ 0]];
uint32_t s1 = lutDec0[s[ 4]];
uint32_t s2 = lutDec0[s[ 8]];
uint32_t s3 = lutDec0[s[12]];
s0 ^= lutDec1[s[13]];
s1 ^= lutDec1[s[ 1]];
s2 ^= lutDec1[s[ 5]];
s3 ^= lutDec1[s[ 9]];
s0 ^= lutDec2[s[10]];
s1 ^= lutDec2[s[14]];
s2 ^= lutDec2[s[ 2]];
s3 ^= lutDec2[s[ 6]];
s0 ^= lutDec3[s[ 7]];
s1 ^= lutDec3[s[11]];
s2 ^= lutDec3[s[15]];
s3 ^= lutDec3[s[ 3]];
return rx_xor_vec_i128(rx_set_int_vec_i128(s3, s2, s1, s0), key);
}
template<>
FORCE_INLINE rx_vec_i128 aesenc<false>(rx_vec_i128 in, rx_vec_i128 key) {
return rx_aesenc_vec_i128(in, key);
}
template<>
FORCE_INLINE rx_vec_i128 aesdec<false>(rx_vec_i128 in, rx_vec_i128 key) {
return rx_aesdec_vec_i128(in, key);
}

View file

@ -72,13 +72,13 @@ bool xmrig::RxDataset::init(const uint8_t *seed, uint32_t numThreads)
return true;
}
const uint32_t datasetItemCount = randomx_dataset_item_count();
const uint64_t datasetItemCount = randomx_dataset_item_count();
if (numThreads > 1) {
std::vector<std::thread> threads;
threads.reserve(numThreads);
for (uint32_t i = 0; i < numThreads; ++i) {
for (uint64_t i = 0; i < numThreads; ++i) {
const uint32_t a = (datasetItemCount * i) / numThreads;
const uint32_t b = (datasetItemCount * (i + 1)) / numThreads;
threads.emplace_back(randomx_init_dataset, m_dataset, m_cache->get(), a, b - a);

View file

@ -48,7 +48,6 @@
#include "net/strategies/DonateStrategy.h"
#include "rapidjson/document.h"
#ifdef XMRIG_FEATURE_API
# include "base/api/Api.h"
# include "base/api/interfaces/IApiRequest.h"

View file

@ -41,7 +41,6 @@
namespace xmrig {
class Controller;
class IStrategy;
@ -53,7 +52,6 @@ public:
~Network() override;
inline IStrategy *strategy() const { return m_strategy; }
void connect();
protected:

View file

@ -28,14 +28,14 @@
#define APP_ID "XMRigCC"
#define APP_NAME "XMRigCC"
#define APP_DESC "XMRigCC CPU miner"
#define APP_VERSION "2.0.0"
#define APP_VERSION "2.1.0"
#define APP_DOMAIN ""
#define APP_SITE "https://github.com/BenDr0id/xmrigCC/"
#define APP_COPYRIGHT "Copyright (C) 2017- XMRigCC"
#define APP_KIND "cpu"
#define APP_VER_MAJOR 2
#define APP_VER_MINOR 0
#define APP_VER_MINOR 1
#define APP_VER_PATCH 0
#ifndef NDEBUG