diff --git a/CHANGELOG.md b/CHANGELOG.md
index 949e60c14..5307fc1e5 100644
--- a/CHANGELOG.md
+++ b/CHANGELOG.md
@@ -1,3 +1,12 @@
+# v5.10.0
+- [#1590](https://github.com/xmrig/xmrig/pull/1590) MSR mod automatically deactivated after switching from RandomX algorithms.
+- [#1592](https://github.com/xmrig/xmrig/pull/1592) Added AVX2 optimized code for AstroBWT algorithm.
+  - Added new config option `astrobwt-avx2` in `cpu` object and command line option `--astrobwt-avx2`.
+- [#1596](https://github.com/xmrig/xmrig/issues/1596) Major TLS (Transport Layer Security) subsystem update.
+  - Added new TLS options, please check [xmrig-proxy documentation](https://xmrig.com/docs/proxy/tls) for details.
+- `cn/gpu` algorithm now disabled by default and will be removed in next major (v6.x.x) release, no ETA for it right now.
+- Added command line option `--data-dir`.
+
 # v5.9.0
 - [#1578](https://github.com/xmrig/xmrig/pull/1578) Added new RandomKEVA algorithm for upcoming Kevacoin fork, as `"algo": "rx/keva"` or `"coin": "keva"`.
 - [#1584](https://github.com/xmrig/xmrig/pull/1584) Fixed invalid AstroBWT hashes after algorithm switching.
diff --git a/CMakeLists.txt b/CMakeLists.txt
index 74c546d7e..ba98c11ac 100644
--- a/CMakeLists.txt
+++ b/CMakeLists.txt
@@ -6,7 +6,7 @@ option(WITH_HWLOC           "Enable hwloc support" ON)
 option(WITH_CN_LITE         "Enable CryptoNight-Lite algorithms family" ON)
 option(WITH_CN_HEAVY        "Enable CryptoNight-Heavy algorithms family" ON)
 option(WITH_CN_PICO         "Enable CryptoNight-Pico algorithm" ON)
-option(WITH_CN_GPU          "Enable CryptoNight-GPU algorithm" ON)
+option(WITH_CN_GPU          "Enable CryptoNight-GPU algorithm" OFF)
 option(WITH_RANDOMX         "Enable RandomX algorithms family" ON)
 option(WITH_ARGON2          "Enable Argon2 algorithms family" ON)
 option(WITH_ASTROBWT        "Enable AstroBWT algorithms family" ON)
@@ -67,7 +67,6 @@ set(HEADERS_CRYPTO
     src/crypto/cn/c_groestl.h
     src/crypto/cn/c_jh.h
     src/crypto/cn/c_skein.h
-    src/crypto/cn/CnAlgo.h
     src/crypto/cn/CnCtx.h
     src/crypto/cn/CnHash.h
     src/crypto/cn/CryptoNight_monero.h
@@ -77,10 +76,7 @@ set(HEADERS_CRYPTO
     src/crypto/cn/hash.h
     src/crypto/cn/skein_port.h
     src/crypto/cn/soft_aes.h
-    src/crypto/common/Algorithm.h
-    src/crypto/common/Coin.h
     src/crypto/common/HugePagesInfo.h
-    src/crypto/common/keccak.h
     src/crypto/common/MemoryPool.h
     src/crypto/common/Nonce.h
     src/crypto/common/portable/mm_malloc.h
@@ -116,10 +112,7 @@ set(SOURCES_CRYPTO
     src/crypto/cn/c_skein.c
     src/crypto/cn/CnCtx.cpp
     src/crypto/cn/CnHash.cpp
-    src/crypto/common/Algorithm.cpp
-    src/crypto/common/Coin.cpp
     src/crypto/common/HugePagesInfo.cpp
-    src/crypto/common/keccak.cpp
     src/crypto/common/MemoryPool.cpp
     src/crypto/common/Nonce.cpp
     src/crypto/common/VirtualMemory.cpp
diff --git a/README.md b/README.md
index a628ca8ac..798dadcd9 100644
--- a/README.md
+++ b/README.md
@@ -68,6 +68,7 @@ CPU backend:
       --randomx-wrmsr=N         write custom value (0-15) to Intel MSR register 0x1a4 or disable MSR mod (-1)
       --randomx-no-rdmsr        disable reverting initial MSR values on exit
       --astrobwt-max-size=N     skip hashes with large stage 2 size, default: 550, min: 400, max: 1200
+      --astrobwt-avx2           enable AVX2 optimizations for AstroBWT algorithm
 
 API:
       --api-worker-id=ID        custom worker-id for API
@@ -93,6 +94,15 @@ CUDA backend:
       --cuda-bsleep-hint=N      bsleep hint for autoconfig
       --no-nvml                 disable NVML (NVIDIA Management Library) support
 
+TLS:
+      --tls-gen=HOSTNAME        generate TLS certificate for specific hostname
+      --tls-cert=FILE           load TLS certificate chain from a file in the PEM format
+      --tls-cert-key=FILE       load TLS certificate private key from a file in the PEM format
+      --tls-dhparam=FILE        load DH parameters for DHE ciphers from a file in the PEM format
+      --tls-protocols=N         enable specified TLS protocols, example: "TLSv1 TLSv1.1 TLSv1.2 TLSv1.3"
+      --tls-ciphers=S           set list of available ciphers (TLSv1.2 and below)
+      --tls-ciphersuites=S      set list of available TLSv1.3 ciphersuites
+
 Logging:
   -S, --syslog                  use system log for output messages
   -l, --log-file=FILE           log all output to a file
diff --git a/cmake/OpenSSL.cmake b/cmake/OpenSSL.cmake
index 7ff839951..53e970dfe 100644
--- a/cmake/OpenSSL.cmake
+++ b/cmake/OpenSSL.cmake
@@ -13,11 +13,30 @@ if (WITH_TLS)
     find_package(OpenSSL)
 
     if (OPENSSL_FOUND)
-        set(TLS_SOURCES src/base/net/stratum/Tls.h src/base/net/stratum/Tls.cpp)
+        set(TLS_SOURCES
+            src/base/net/stratum/Tls.cpp
+            src/base/net/stratum/Tls.h
+            src/base/net/tls/ServerTls.cpp
+            src/base/net/tls/ServerTls.h
+            src/base/net/tls/TlsConfig.cpp
+            src/base/net/tls/TlsConfig.h
+            src/base/net/tls/TlsContext.cpp
+            src/base/net/tls/TlsContext.h
+            src/base/net/tls/TlsGen.cpp
+            src/base/net/tls/TlsGen.h
+            )
+
         include_directories(${OPENSSL_INCLUDE_DIR})
 
         if (WITH_HTTP)
-            set(TLS_SOURCES ${TLS_SOURCES} src/base/net/http/HttpsClient.h src/base/net/http/HttpsClient.cpp)
+            set(TLS_SOURCES ${TLS_SOURCES}
+                src/base/net/https/HttpsClient.cpp
+                src/base/net/https/HttpsClient.h
+                src/base/net/https/HttpsContext.cpp
+                src/base/net/https/HttpsContext.h
+                src/base/net/https/HttpsServer.cpp
+                src/base/net/https/HttpsServer.h
+                )
         endif()
     else()
         message(FATAL_ERROR "OpenSSL NOT found: use `-DWITH_TLS=OFF` to build without TLS support")
@@ -29,5 +48,12 @@ else()
     set(OPENSSL_LIBRARIES "")
     remove_definitions(/DXMRIG_FEATURE_TLS)
 
+    if (WITH_HTTP)
+        set(TLS_SOURCES ${TLS_SOURCES}
+            src/base/net/http/HttpServer.cpp
+            src/base/net/http/HttpServer.h
+            )
+    endif()
+
     set(CMAKE_PROJECT_NAME "${CMAKE_PROJECT_NAME}-notls")
 endif()
diff --git a/cmake/astrobwt.cmake b/cmake/astrobwt.cmake
index 8c89da00d..9ba06e0c4 100644
--- a/cmake/astrobwt.cmake
+++ b/cmake/astrobwt.cmake
@@ -23,6 +23,16 @@ if (WITH_ASTROBWT)
             src/crypto/astrobwt/salsa20_ref/salsa20.c
         )
     else()
+        if (CMAKE_SIZEOF_VOID_P EQUAL 8)
+            enable_language(ASM_MASM)
+            add_definitions(/DASTROBWT_AVX2)
+            if (CMAKE_C_COMPILER_ID MATCHES MSVC)
+                list(APPEND SOURCES_CRYPTO src/crypto/astrobwt/sha3_256_avx2.asm)
+            else()
+                list(APPEND SOURCES_CRYPTO src/crypto/astrobwt/sha3_256_avx2.S)
+            endif()
+        endif()
+
         list(APPEND HEADERS_CRYPTO
             src/crypto/astrobwt/Salsa20.hpp
         )
diff --git a/src/backend/common/Threads.cpp b/src/backend/common/Threads.cpp
index f85e18f3d..a72f8026d 100644
--- a/src/backend/common/Threads.cpp
+++ b/src/backend/common/Threads.cpp
@@ -5,8 +5,8 @@
  * 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>
+ * Copyright 2018-2020 SChernykh   <https://github.com/SChernykh>
+ * Copyright 2016-2020 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
@@ -25,7 +25,7 @@
 
 #include "backend/common/Threads.h"
 #include "backend/cpu/CpuThreads.h"
-#include "crypto/cn/CnAlgo.h"
+#include "base/crypto/CnAlgo.h"
 #include "rapidjson/document.h"
 
 
diff --git a/src/backend/common/Threads.h b/src/backend/common/Threads.h
index 59b04fc9e..a21fe13b5 100644
--- a/src/backend/common/Threads.h
+++ b/src/backend/common/Threads.h
@@ -5,8 +5,8 @@
  * 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>
+ * Copyright 2018-2020 SChernykh   <https://github.com/SChernykh>
+ * Copyright 2016-2020 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
@@ -30,8 +30,8 @@
 #include <set>
 
 
+#include "base/crypto/Algorithm.h"
 #include "base/tools/String.h"
-#include "crypto/common/Algorithm.h"
 #include "rapidjson/fwd.h"
 
 
diff --git a/src/backend/cpu/CpuConfig.cpp b/src/backend/cpu/CpuConfig.cpp
index 0f156e926..4c7a630f6 100644
--- a/src/backend/cpu/CpuConfig.cpp
+++ b/src/backend/cpu/CpuConfig.cpp
@@ -52,6 +52,7 @@ static const char *kArgon2Impl = "argon2-impl";
 
 #ifdef XMRIG_ALGO_ASTROBWT
 static const char* kAstroBWTMaxSize = "astrobwt-max-size";
+static const char* kAstroBWTAVX2    = "astrobwt-avx2";
 #endif
 
 
@@ -93,7 +94,8 @@ rapidjson::Value xmrig::CpuConfig::toJSON(rapidjson::Document &doc) const
 #   endif
 
 #   ifdef XMRIG_ALGO_ASTROBWT
-    obj.AddMember(StringRef(kAstroBWTMaxSize), m_astrobwtMaxSize, allocator);
+    obj.AddMember(StringRef(kAstroBWTMaxSize),  m_astrobwtMaxSize, allocator);
+    obj.AddMember(StringRef(kAstroBWTAVX2),     m_astrobwtAVX2, allocator);
 #   endif
 
     m_threads.toJSON(obj, doc);
@@ -148,12 +150,20 @@ void xmrig::CpuConfig::read(const rapidjson::Value &value)
 #       endif
 
 #       ifdef XMRIG_ALGO_ASTROBWT
-        const auto& obj = Json::getValue(value, kAstroBWTMaxSize);
-        if (obj.IsNull() || !obj.IsInt()) {
+        const auto& astroBWTMaxSize = Json::getValue(value, kAstroBWTMaxSize);
+        if (astroBWTMaxSize.IsNull() || !astroBWTMaxSize.IsInt()) {
             m_shouldSave = true;
         }
         else {
-            m_astrobwtMaxSize = std::min(std::max(obj.GetInt(), 400), 1200);
+            m_astrobwtMaxSize = std::min(std::max(astroBWTMaxSize.GetInt(), 400), 1200);
+        }
+
+        const auto& astroBWTAVX2 = Json::getValue(value, kAstroBWTAVX2);
+        if (astroBWTAVX2.IsNull() || !astroBWTAVX2.IsBool()) {
+            m_shouldSave = true;
+        }
+        else {
+            m_astrobwtAVX2 = astroBWTAVX2.GetBool();
         }
 #       endif
 
diff --git a/src/backend/cpu/CpuConfig.h b/src/backend/cpu/CpuConfig.h
index c294f0697..30166215f 100644
--- a/src/backend/cpu/CpuConfig.h
+++ b/src/backend/cpu/CpuConfig.h
@@ -60,6 +60,7 @@ public:
     inline const String &argon2Impl() const             { return m_argon2Impl; }
     inline const Threads<CpuThreads> &threads() const   { return m_threads; }
     inline int astrobwtMaxSize() const                  { return m_astrobwtMaxSize; }
+    inline bool astrobwtAVX2() const                    { return m_astrobwtAVX2; }
     inline int priority() const                         { return m_priority; }
     inline uint32_t limit() const                       { return m_limit; }
 
@@ -72,6 +73,7 @@ private:
 
     AesMode m_aes           = AES_AUTO;
     Assembly m_assembly;
+    bool m_astrobwtAVX2     = false;
     bool m_enabled          = true;
     bool m_hugePages        = true;
     bool m_shouldSave       = false;
diff --git a/src/backend/cpu/CpuLaunchData.cpp b/src/backend/cpu/CpuLaunchData.cpp
index dbc7e5c5c..b0090a212 100644
--- a/src/backend/cpu/CpuLaunchData.cpp
+++ b/src/backend/cpu/CpuLaunchData.cpp
@@ -35,10 +35,11 @@
 xmrig::CpuLaunchData::CpuLaunchData(const Miner *miner, const Algorithm &algorithm, const CpuConfig &config, const CpuThread &thread) :
     algorithm(algorithm),
     assembly(config.assembly()),
+    astrobwtAVX2(config.astrobwtAVX2()),
     hugePages(config.isHugePages()),
     hwAES(config.isHwAES()),
     yield(config.isYield()),
-    astrobwtMaxSize(config.astrobwtMaxSize()),
+    astrobwtMaxSize(config.astrobwtMaxSize()),    
     priority(config.priority()),
     affinity(thread.affinity()),
     miner(miner),
diff --git a/src/backend/cpu/CpuLaunchData.h b/src/backend/cpu/CpuLaunchData.h
index 0ba8ad7f9..7728d1d34 100644
--- a/src/backend/cpu/CpuLaunchData.h
+++ b/src/backend/cpu/CpuLaunchData.h
@@ -27,8 +27,8 @@
 #define XMRIG_CPULAUNCHDATA_H
 
 
+#include "base/crypto/Algorithm.h"
 #include "crypto/cn/CnHash.h"
-#include "crypto/common/Algorithm.h"
 #include "crypto/common/Assembly.h"
 #include "crypto/common/Nonce.h"
 
@@ -58,6 +58,7 @@ public:
 
     const Algorithm algorithm;
     const Assembly assembly;
+    const bool astrobwtAVX2;
     const bool hugePages;
     const bool hwAES;
     const bool yield;
diff --git a/src/backend/cpu/CpuWorker.cpp b/src/backend/cpu/CpuWorker.cpp
index 0740cca2c..968978382 100644
--- a/src/backend/cpu/CpuWorker.cpp
+++ b/src/backend/cpu/CpuWorker.cpp
@@ -77,6 +77,7 @@ xmrig::CpuWorker<N>::CpuWorker(size_t id, const CpuLaunchData &data) :
     Worker(id, data.affinity, data.priority),
     m_algorithm(data.algorithm),
     m_assembly(data.assembly),
+    m_astrobwtAVX2(data.astrobwtAVX2),
     m_hwAES(data.hwAES),
     m_yield(data.yield),
     m_av(data.av()),
@@ -262,7 +263,7 @@ void xmrig::CpuWorker<N>::start()
             {
 #               ifdef XMRIG_ALGO_ASTROBWT
                 if (job.algorithm().family() == Algorithm::ASTROBWT) {
-                    if (!astrobwt::astrobwt_dero(m_job.blob(), job.size(), m_ctx[0]->memory, m_hash, m_astrobwtMaxSize))
+                    if (!astrobwt::astrobwt_dero(m_job.blob(), job.size(), m_ctx[0]->memory, m_hash, m_astrobwtMaxSize, m_astrobwtAVX2))
                         valid = false;
                 }
                 else
diff --git a/src/backend/cpu/CpuWorker.h b/src/backend/cpu/CpuWorker.h
index 8d2c583fe..8d539126c 100644
--- a/src/backend/cpu/CpuWorker.h
+++ b/src/backend/cpu/CpuWorker.h
@@ -70,6 +70,7 @@ private:
 
     const Algorithm m_algorithm;
     const Assembly m_assembly;
+    const bool m_astrobwtAVX2;
     const bool m_hwAES;
     const bool m_yield;
     const CnHash::AlgoVariant m_av;
diff --git a/src/backend/cpu/interfaces/ICpuInfo.h b/src/backend/cpu/interfaces/ICpuInfo.h
index 4aad69447..f5a35b2d0 100644
--- a/src/backend/cpu/interfaces/ICpuInfo.h
+++ b/src/backend/cpu/interfaces/ICpuInfo.h
@@ -27,8 +27,8 @@
 
 
 #include "backend/cpu/CpuThreads.h"
+#include "base/crypto/Algorithm.h"
 #include "crypto/common/Assembly.h"
-#include "crypto/common/Algorithm.h"
 
 
 namespace xmrig {
diff --git a/src/backend/cuda/CudaLaunchData.h b/src/backend/cuda/CudaLaunchData.h
index 33173ffb7..8bf2dbeba 100644
--- a/src/backend/cuda/CudaLaunchData.h
+++ b/src/backend/cuda/CudaLaunchData.h
@@ -28,7 +28,7 @@
 
 
 #include "backend/cuda/CudaThread.h"
-#include "crypto/common/Algorithm.h"
+#include "base/crypto/Algorithm.h"
 #include "crypto/common/Nonce.h"
 
 
diff --git a/src/backend/cuda/CudaThread.cpp b/src/backend/cuda/CudaThread.cpp
index d98989ab6..eb65dc2c4 100644
--- a/src/backend/cuda/CudaThread.cpp
+++ b/src/backend/cuda/CudaThread.cpp
@@ -5,8 +5,8 @@
  * 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>
+ * Copyright 2018-2020 SChernykh   <https://github.com/SChernykh>
+ * Copyright 2016-2020 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
diff --git a/src/backend/cuda/CudaThread.h b/src/backend/cuda/CudaThread.h
index 8943ac228..3588e846d 100644
--- a/src/backend/cuda/CudaThread.h
+++ b/src/backend/cuda/CudaThread.h
@@ -5,8 +5,8 @@
  * 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>
+ * Copyright 2018-2020 SChernykh   <https://github.com/SChernykh>
+ * Copyright 2016-2020 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
@@ -29,7 +29,6 @@
 using nvid_ctx = struct nvid_ctx;
 
 
-#include "crypto/common/Algorithm.h"
 #include "rapidjson/fwd.h"
 
 
diff --git a/src/backend/cuda/wrappers/CudaDevice.cpp b/src/backend/cuda/wrappers/CudaDevice.cpp
index 93234d536..daa160745 100644
--- a/src/backend/cuda/wrappers/CudaDevice.cpp
+++ b/src/backend/cuda/wrappers/CudaDevice.cpp
@@ -5,8 +5,8 @@
  * 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>
+ * Copyright 2018-2020 SChernykh   <https://github.com/SChernykh>
+ * Copyright 2016-2020 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
@@ -26,8 +26,8 @@
 #include "backend/cuda/wrappers/CudaDevice.h"
 #include "backend/cuda/CudaThreads.h"
 #include "backend/cuda/wrappers/CudaLib.h"
+#include "base/crypto/Algorithm.h"
 #include "base/io/log/Log.h"
-#include "crypto/common/Algorithm.h"
 #include "rapidjson/document.h"
 
 #ifdef XMRIG_FEATURE_NVML
diff --git a/src/backend/cuda/wrappers/CudaLib.h b/src/backend/cuda/wrappers/CudaLib.h
index 99824f809..b48e720cd 100644
--- a/src/backend/cuda/wrappers/CudaLib.h
+++ b/src/backend/cuda/wrappers/CudaLib.h
@@ -5,8 +5,8 @@
  * 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>
+ * Copyright 2018-2020 SChernykh   <https://github.com/SChernykh>
+ * Copyright 2016-2020 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
@@ -31,7 +31,6 @@ using nvid_ctx = struct nvid_ctx;
 
 #include "backend/cuda/wrappers/CudaDevice.h"
 #include "base/tools/String.h"
-#include "crypto/common/Algorithm.h"
 
 
 #include <vector>
diff --git a/src/backend/opencl/OclCache.cpp b/src/backend/opencl/OclCache.cpp
index 7e5504c08..e93019c88 100644
--- a/src/backend/opencl/OclCache.cpp
+++ b/src/backend/opencl/OclCache.cpp
@@ -5,8 +5,8 @@
  * 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>
+ * Copyright 2018-2020 SChernykh   <https://github.com/SChernykh>
+ * Copyright 2016-2020 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
@@ -29,15 +29,15 @@
 #include <sstream>
 
 
+#include "backend/opencl/OclCache.h"
 #include "3rdparty/base32/base32.h"
 #include "backend/common/Tags.h"
 #include "backend/opencl/interfaces/IOclRunner.h"
-#include "backend/opencl/OclCache.h"
 #include "backend/opencl/OclLaunchData.h"
 #include "backend/opencl/wrappers/OclLib.h"
+#include "base/crypto/keccak.h"
 #include "base/io/log/Log.h"
 #include "base/tools/Chrono.h"
-#include "crypto/common/keccak.h"
 
 
 namespace xmrig {
diff --git a/src/backend/opencl/OclCache.h b/src/backend/opencl/OclCache.h
index e3eea5c3f..5f17bfca9 100644
--- a/src/backend/opencl/OclCache.h
+++ b/src/backend/opencl/OclCache.h
@@ -5,8 +5,8 @@
  * 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>
+ * Copyright 2018-2020 SChernykh   <https://github.com/SChernykh>
+ * Copyright 2016-2020 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
diff --git a/src/backend/opencl/OclLaunchData.cpp b/src/backend/opencl/OclLaunchData.cpp
index 2af6d1019..48c380f45 100644
--- a/src/backend/opencl/OclLaunchData.cpp
+++ b/src/backend/opencl/OclLaunchData.cpp
@@ -6,8 +6,8 @@
  * 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>
+ * Copyright 2018-2020 SChernykh   <https://github.com/SChernykh>
+ * Copyright 2016-2020 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
diff --git a/src/backend/opencl/OclLaunchData.h b/src/backend/opencl/OclLaunchData.h
index 644023be8..73716b840 100644
--- a/src/backend/opencl/OclLaunchData.h
+++ b/src/backend/opencl/OclLaunchData.h
@@ -6,8 +6,8 @@
  * 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>
+ * Copyright 2018-2020 SChernykh   <https://github.com/SChernykh>
+ * Copyright 2016-2020 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
@@ -31,7 +31,7 @@
 #include "backend/opencl/runners/tools/OclSharedData.h"
 #include "backend/opencl/wrappers/OclDevice.h"
 #include "backend/opencl/wrappers/OclPlatform.h"
-#include "crypto/common/Algorithm.h"
+#include "base/crypto/Algorithm.h"
 #include "crypto/common/Nonce.h"
 
 
diff --git a/src/backend/opencl/OclThread.cpp b/src/backend/opencl/OclThread.cpp
index 8ca4574f7..e94eb876b 100644
--- a/src/backend/opencl/OclThread.cpp
+++ b/src/backend/opencl/OclThread.cpp
@@ -5,8 +5,8 @@
  * 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>
+ * Copyright 2018-2020 SChernykh   <https://github.com/SChernykh>
+ * Copyright 2016-2020 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
@@ -24,7 +24,6 @@
 
 
 #include "backend/opencl/OclThread.h"
-
 #include "base/io/json/Json.h"
 #include "rapidjson/document.h"
 
diff --git a/src/backend/opencl/OclThread.h b/src/backend/opencl/OclThread.h
index 1882abf7a..4febb7a03 100644
--- a/src/backend/opencl/OclThread.h
+++ b/src/backend/opencl/OclThread.h
@@ -5,8 +5,8 @@
  * 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>
+ * Copyright 2018-2020 SChernykh   <https://github.com/SChernykh>
+ * Copyright 2016-2020 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
@@ -26,7 +26,6 @@
 #define XMRIG_OCLTHREAD_H
 
 
-#include "crypto/common/Algorithm.h"
 #include "rapidjson/fwd.h"
 
 
diff --git a/src/backend/opencl/cl/OclSource.cpp b/src/backend/opencl/cl/OclSource.cpp
index 5f569d496..b30e8a8f4 100644
--- a/src/backend/opencl/cl/OclSource.cpp
+++ b/src/backend/opencl/cl/OclSource.cpp
@@ -5,8 +5,8 @@
  * 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>
+ * Copyright 2018-2020 SChernykh   <https://github.com/SChernykh>
+ * Copyright 2016-2020 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
@@ -24,9 +24,8 @@
 
 
 #include "backend/opencl/cl/OclSource.h"
-
 #include "backend/opencl/cl/cn/cryptonight_cl.h"
-#include "crypto/common/Algorithm.h"
+#include "base/crypto/Algorithm.h"
 
 
 #ifdef XMRIG_ALGO_CN_GPU
diff --git a/src/backend/opencl/cl/OclSource.h b/src/backend/opencl/cl/OclSource.h
index 40b70810a..6f41d1eb5 100644
--- a/src/backend/opencl/cl/OclSource.h
+++ b/src/backend/opencl/cl/OclSource.h
@@ -5,8 +5,8 @@
  * 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>
+ * Copyright 2018-2020 SChernykh   <https://github.com/SChernykh>
+ * Copyright 2016-2020 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
diff --git a/src/backend/opencl/generators/ocl_generic_cn_generator.cpp b/src/backend/opencl/generators/ocl_generic_cn_generator.cpp
index 5fb91ebfa..90e80e6fd 100644
--- a/src/backend/opencl/generators/ocl_generic_cn_generator.cpp
+++ b/src/backend/opencl/generators/ocl_generic_cn_generator.cpp
@@ -6,8 +6,8 @@
  * 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>
+ * Copyright 2018-2020 SChernykh   <https://github.com/SChernykh>
+ * Copyright 2016-2020 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
@@ -26,8 +26,8 @@
 
 #include "backend/opencl/OclThreads.h"
 #include "backend/opencl/wrappers/OclDevice.h"
-#include "crypto/cn/CnAlgo.h"
-#include "crypto/common/Algorithm.h"
+#include "base/crypto/Algorithm.h"
+#include "base/crypto/CnAlgo.h"
 
 
 #include <algorithm>
diff --git a/src/backend/opencl/generators/ocl_generic_cn_gpu_generator.cpp b/src/backend/opencl/generators/ocl_generic_cn_gpu_generator.cpp
index 338a7a78c..9a6a8952c 100644
--- a/src/backend/opencl/generators/ocl_generic_cn_gpu_generator.cpp
+++ b/src/backend/opencl/generators/ocl_generic_cn_gpu_generator.cpp
@@ -6,8 +6,8 @@
  * 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>
+ * Copyright 2018-2020 SChernykh   <https://github.com/SChernykh>
+ * Copyright 2016-2020 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
@@ -26,7 +26,7 @@
 
 #include "backend/opencl/OclThreads.h"
 #include "backend/opencl/wrappers/OclDevice.h"
-#include "crypto/common/Algorithm.h"
+#include "base/crypto/Algorithm.h"
 
 
 #include <algorithm>
diff --git a/src/backend/opencl/generators/ocl_generic_rx_generator.cpp b/src/backend/opencl/generators/ocl_generic_rx_generator.cpp
index 27124acef..49a73f407 100644
--- a/src/backend/opencl/generators/ocl_generic_rx_generator.cpp
+++ b/src/backend/opencl/generators/ocl_generic_rx_generator.cpp
@@ -26,7 +26,7 @@
 
 #include "backend/opencl/OclThreads.h"
 #include "backend/opencl/wrappers/OclDevice.h"
-#include "crypto/common/Algorithm.h"
+#include "base/crypto/Algorithm.h"
 #include "crypto/randomx/randomx.h"
 #include "crypto/rx/RxAlgo.h"
 
diff --git a/src/backend/opencl/generators/ocl_vega_cn_generator.cpp b/src/backend/opencl/generators/ocl_vega_cn_generator.cpp
index dbaba1c53..0e14dad90 100644
--- a/src/backend/opencl/generators/ocl_vega_cn_generator.cpp
+++ b/src/backend/opencl/generators/ocl_vega_cn_generator.cpp
@@ -26,8 +26,8 @@
 
 #include "backend/opencl/OclThreads.h"
 #include "backend/opencl/wrappers/OclDevice.h"
-#include "crypto/cn/CnAlgo.h"
-#include "crypto/common/Algorithm.h"
+#include "base/crypto/Algorithm.h"
+#include "base/crypto/CnAlgo.h"
 
 
 #include <algorithm>
diff --git a/src/backend/opencl/kernels/rx/RxRunKernel.cpp b/src/backend/opencl/kernels/rx/RxRunKernel.cpp
index ff2a3299c..a88068d77 100644
--- a/src/backend/opencl/kernels/rx/RxRunKernel.cpp
+++ b/src/backend/opencl/kernels/rx/RxRunKernel.cpp
@@ -25,7 +25,7 @@
 
 #include "backend/opencl/kernels/rx/RxRunKernel.h"
 #include "backend/opencl/wrappers/OclLib.h"
-#include "crypto/common/Algorithm.h"
+#include "base/crypto/Algorithm.h"
 #include "crypto/randomx/randomx.h"
 #include "crypto/rx/RxAlgo.h"
 
diff --git a/src/backend/opencl/runners/OclBaseRunner.cpp b/src/backend/opencl/runners/OclBaseRunner.cpp
index 5c498dbd1..9e2a48a9f 100644
--- a/src/backend/opencl/runners/OclBaseRunner.cpp
+++ b/src/backend/opencl/runners/OclBaseRunner.cpp
@@ -5,8 +5,8 @@
  * 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>
+ * Copyright 2018-2020 SChernykh   <https://github.com/SChernykh>
+ * Copyright 2016-2020 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
diff --git a/src/backend/opencl/runners/OclBaseRunner.h b/src/backend/opencl/runners/OclBaseRunner.h
index 6abbb2b72..68a20f251 100644
--- a/src/backend/opencl/runners/OclBaseRunner.h
+++ b/src/backend/opencl/runners/OclBaseRunner.h
@@ -5,8 +5,8 @@
  * 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>
+ * Copyright 2018-2020 SChernykh   <https://github.com/SChernykh>
+ * Copyright 2016-2020 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
@@ -31,7 +31,7 @@
 
 #include "3rdparty/cl.h"
 #include "backend/opencl/interfaces/IOclRunner.h"
-#include "crypto/common/Algorithm.h"
+#include "base/crypto/Algorithm.h"
 
 
 namespace xmrig {
diff --git a/src/backend/opencl/runners/OclCnRunner.cpp b/src/backend/opencl/runners/OclCnRunner.cpp
index a1f4d5cb2..67cc4027b 100644
--- a/src/backend/opencl/runners/OclCnRunner.cpp
+++ b/src/backend/opencl/runners/OclCnRunner.cpp
@@ -5,8 +5,8 @@
  * 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>
+ * Copyright 2018-2020 SChernykh   <https://github.com/SChernykh>
+ * Copyright 2016-2020 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
@@ -24,7 +24,6 @@
 
 
 #include "backend/opencl/runners/OclCnRunner.h"
-
 #include "backend/opencl/kernels/Cn0Kernel.h"
 #include "backend/opencl/kernels/Cn1Kernel.h"
 #include "backend/opencl/kernels/Cn2Kernel.h"
@@ -32,9 +31,9 @@
 #include "backend/opencl/OclLaunchData.h"
 #include "backend/opencl/runners/tools/OclCnR.h"
 #include "backend/opencl/wrappers/OclLib.h"
+#include "base/crypto/CnAlgo.h"
 #include "base/io/log/Log.h"
 #include "base/net/stratum/Job.h"
-#include "crypto/cn/CnAlgo.h"
 
 
 xmrig::OclCnRunner::OclCnRunner(size_t index, const OclLaunchData &data) : OclBaseRunner(index, data)
diff --git a/src/backend/opencl/runners/OclCnRunner.h b/src/backend/opencl/runners/OclCnRunner.h
index bd20019fc..bae581cea 100644
--- a/src/backend/opencl/runners/OclCnRunner.h
+++ b/src/backend/opencl/runners/OclCnRunner.h
@@ -5,8 +5,8 @@
  * 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>
+ * Copyright 2018-2020 SChernykh   <https://github.com/SChernykh>
+ * Copyright 2016-2020 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
diff --git a/src/backend/opencl/runners/OclRyoRunner.cpp b/src/backend/opencl/runners/OclRyoRunner.cpp
index 0907903e5..8d494a261 100644
--- a/src/backend/opencl/runners/OclRyoRunner.cpp
+++ b/src/backend/opencl/runners/OclRyoRunner.cpp
@@ -5,8 +5,8 @@
  * 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>
+ * Copyright 2018-2020 SChernykh   <https://github.com/SChernykh>
+ * Copyright 2016-2020 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
@@ -24,7 +24,6 @@
 
 
 #include "backend/opencl/runners/OclRyoRunner.h"
-
 #include "backend/opencl/kernels/Cn00RyoKernel.h"
 #include "backend/opencl/kernels/Cn0Kernel.h"
 #include "backend/opencl/kernels/Cn1RyoKernel.h"
@@ -32,9 +31,9 @@
 #include "backend/opencl/kernels/CnBranchKernel.h"
 #include "backend/opencl/OclLaunchData.h"
 #include "backend/opencl/wrappers/OclLib.h"
+#include "base/crypto/CnAlgo.h"
 #include "base/io/log/Log.h"
 #include "base/net/stratum/Job.h"
-#include "crypto/cn/CnAlgo.h"
 
 
 xmrig::OclRyoRunner::OclRyoRunner(size_t index, const OclLaunchData &data) : OclBaseRunner(index, data)
diff --git a/src/backend/opencl/runners/OclRyoRunner.h b/src/backend/opencl/runners/OclRyoRunner.h
index fd9f41c31..4cf6245f9 100644
--- a/src/backend/opencl/runners/OclRyoRunner.h
+++ b/src/backend/opencl/runners/OclRyoRunner.h
@@ -5,8 +5,8 @@
  * 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>
+ * Copyright 2018-2020 SChernykh   <https://github.com/SChernykh>
+ * Copyright 2016-2020 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
diff --git a/src/backend/opencl/wrappers/OclDevice.cpp b/src/backend/opencl/wrappers/OclDevice.cpp
index 766e70e59..bd51d0f3f 100644
--- a/src/backend/opencl/wrappers/OclDevice.cpp
+++ b/src/backend/opencl/wrappers/OclDevice.cpp
@@ -28,8 +28,6 @@
 #include "backend/opencl/OclThreads.h"
 #include "backend/opencl/wrappers/OclLib.h"
 #include "base/io/log/Log.h"
-#include "crypto/cn/CnAlgo.h"
-#include "crypto/common/Algorithm.h"
 #include "rapidjson/document.h"
 
 #ifdef XMRIG_FEATURE_ADL
diff --git a/src/base/api/Api.cpp b/src/base/api/Api.cpp
index dfd785657..535875fb2 100644
--- a/src/base/api/Api.cpp
+++ b/src/base/api/Api.cpp
@@ -5,8 +5,8 @@
  * 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>
+ * Copyright 2018-2020 SChernykh   <https://github.com/SChernykh>
+ * Copyright 2016-2020 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
@@ -30,6 +30,7 @@
 #include "3rdparty/http-parser/http_parser.h"
 #include "base/api/interfaces/IApiListener.h"
 #include "base/api/requests/HttpApiRequest.h"
+#include "base/crypto/keccak.h"
 #include "base/io/json/Json.h"
 #include "base/kernel/Base.h"
 #include "base/kernel/Env.h"
@@ -37,7 +38,6 @@
 #include "base/tools/Chrono.h"
 #include "core/config/Config.h"
 #include "core/Controller.h"
-#include "crypto/common/keccak.h"
 #include "version.h"
 
 
diff --git a/src/base/api/Httpd.cpp b/src/base/api/Httpd.cpp
index 37db1ad67..1aba8796d 100644
--- a/src/base/api/Httpd.cpp
+++ b/src/base/api/Httpd.cpp
@@ -29,12 +29,18 @@
 #include "base/io/log/Log.h"
 #include "base/net/http/HttpApiResponse.h"
 #include "base/net/http/HttpData.h"
-#include "base/net/http/HttpServer.h"
 #include "base/net/tools/TcpServer.h"
 #include "core/config/Config.h"
 #include "core/Controller.h"
 
 
+#ifdef XMRIG_FEATURE_TLS
+#   include "base/net/https/HttpsServer.h"
+#else
+#   include "base/net/http/HttpServer.h"
+#endif
+
+
 namespace xmrig {
 
 static const char *kAuthorization = "authorization";
@@ -48,10 +54,7 @@ static size_t faviconSize  = 0;
 
 
 xmrig::Httpd::Httpd(Base *base) :
-    m_base(base),
-    m_http(nullptr),
-    m_server(nullptr),
-    m_port(0)
+    m_base(base)
 {
     m_httpListener = std::make_shared<HttpListener>(this);
 
@@ -64,18 +67,27 @@ xmrig::Httpd::~Httpd() = default;
 
 bool xmrig::Httpd::start()
 {
-    const Http &config = m_base->config()->http();
+    const auto &config = m_base->config()->http();
 
     if (!config.isEnabled()) {
         return true;
     }
 
-    m_http   = new HttpServer(m_httpListener);
+    bool tls = false;
+
+#   ifdef XMRIG_FEATURE_TLS
+    m_http = new HttpsServer(m_httpListener);
+    tls = m_http->setTls(m_base->config()->tls());
+#   else
+    m_http = new HttpServer(m_httpListener);
+#   endif
+
     m_server = new TcpServer(config.host(), config.port(), m_http);
 
     const int rc = m_server->bind();
-    Log::print(GREEN_BOLD(" * ") WHITE_BOLD("%-13s") BLUE_BOLD("%s:%d") " " RED_BOLD("%s"),
+    Log::print(GREEN_BOLD(" * ") WHITE_BOLD("%-13s") CSI "1;%dm%s:%d" " " RED_BOLD("%s"),
                "HTTP API",
+               tls ? 32 : 36,
                config.host().data(),
                rc < 0 ? config.port() : rc,
                rc < 0 ? uv_strerror(rc) : ""
@@ -143,7 +155,7 @@ void xmrig::Httpd::onHttpData(const HttpData &data)
         }
 #       endif
 
-        return HttpResponse(data.id(), 404).end();
+        return HttpResponse(data.id(), HTTP_STATUS_NOT_FOUND).end();
     }
 
     if (data.method > 4) {
diff --git a/src/base/api/Httpd.h b/src/base/api/Httpd.h
index 25d88577e..462a06711 100644
--- a/src/base/api/Httpd.h
+++ b/src/base/api/Httpd.h
@@ -40,6 +40,7 @@ namespace xmrig {
 
 class Base;
 class HttpServer;
+class HttpsServer;
 class TcpServer;
 
 
@@ -61,11 +62,16 @@ protected:
 private:
     int auth(const HttpData &req) const;
 
-    Base *m_base;
-    HttpServer *m_http;
+    const Base *m_base;
     std::shared_ptr<IHttpListener> m_httpListener;
-    TcpServer *m_server;
-    uint16_t m_port;
+    TcpServer *m_server     = nullptr;
+    uint16_t m_port         = 0;
+
+#   ifdef XMRIG_FEATURE_TLS
+    HttpsServer *m_http     = nullptr;
+#   else
+    HttpServer *m_http      = nullptr;
+#   endif
 };
 
 
diff --git a/src/base/base.cmake b/src/base/base.cmake
index 871b045d4..5116da065 100644
--- a/src/base/base.cmake
+++ b/src/base/base.cmake
@@ -1,5 +1,9 @@
 set(HEADERS_BASE
     src/base/api/interfaces/IApiListener.h
+    src/base/crypto/Algorithm.h
+    src/base/crypto/CnAlgo.h
+    src/base/crypto/Coin.h
+    src/base/crypto/keccak.h
     src/base/io/Console.h
     src/base/io/json/Json.h
     src/base/io/json/JsonChain.h
@@ -49,7 +53,9 @@ set(HEADERS_BASE
     src/base/net/stratum/strategies/StrategyProxy.h
     src/base/net/stratum/SubmitResult.h
     src/base/net/stratum/Url.h
-    src/base/net/tools/RecvBuf.h
+    src/base/net/tools/LineReader.h
+    src/base/net/tools/MemPool.h
+    src/base/net/tools/NetBuffer.h
     src/base/net/tools/Storage.h
     src/base/tools/Arguments.h
     src/base/tools/Baton.h
@@ -61,6 +67,9 @@ set(HEADERS_BASE
    )
 
 set(SOURCES_BASE
+    src/base/crypto/Algorithm.cpp
+    src/base/crypto/Coin.cpp
+    src/base/crypto/keccak.cpp
     src/base/io/Console.cpp
     src/base/io/json/Json.cpp
     src/base/io/json/JsonChain.cpp
@@ -92,6 +101,8 @@ set(SOURCES_BASE
     src/base/net/stratum/strategies/FailoverStrategy.cpp
     src/base/net/stratum/strategies/SinglePoolStrategy.cpp
     src/base/net/stratum/Url.cpp
+    src/base/net/tools/LineReader.cpp
+    src/base/net/tools/NetBuffer.cpp
     src/base/tools/Arguments.cpp
     src/base/tools/Buffer.cpp
     src/base/tools/String.cpp
@@ -150,7 +161,6 @@ if (WITH_HTTP)
         src/base/net/http/HttpContext.h
         src/base/net/http/HttpData.h
         src/base/net/http/HttpResponse.h
-        src/base/net/http/HttpServer.h
         src/base/net/stratum/DaemonClient.h
         src/base/net/stratum/SelfSelectClient.h
         src/base/net/tools/TcpServer.h
@@ -169,7 +179,6 @@ if (WITH_HTTP)
         src/base/net/http/HttpData.cpp
         src/base/net/http/HttpListener.cpp
         src/base/net/http/HttpResponse.cpp
-        src/base/net/http/HttpServer.cpp
         src/base/net/stratum/DaemonClient.cpp
         src/base/net/stratum/SelfSelectClient.cpp
         src/base/net/tools/TcpServer.cpp
diff --git a/src/crypto/common/Algorithm.cpp b/src/base/crypto/Algorithm.cpp
similarity index 99%
rename from src/crypto/common/Algorithm.cpp
rename to src/base/crypto/Algorithm.cpp
index ef438ab91..529719668 100644
--- a/src/crypto/common/Algorithm.cpp
+++ b/src/base/crypto/Algorithm.cpp
@@ -24,8 +24,8 @@
  */
 
 
-#include "crypto/common/Algorithm.h"
-#include "crypto/cn/CnAlgo.h"
+#include "base/crypto/Algorithm.h"
+#include "base/crypto/CnAlgo.h"
 #include "rapidjson/document.h"
 
 
diff --git a/src/crypto/common/Algorithm.h b/src/base/crypto/Algorithm.h
similarity index 100%
rename from src/crypto/common/Algorithm.h
rename to src/base/crypto/Algorithm.h
diff --git a/src/crypto/cn/CnAlgo.h b/src/base/crypto/CnAlgo.h
similarity index 98%
rename from src/crypto/cn/CnAlgo.h
rename to src/base/crypto/CnAlgo.h
index 0b115c34e..155618067 100644
--- a/src/crypto/cn/CnAlgo.h
+++ b/src/base/crypto/CnAlgo.h
@@ -6,8 +6,8 @@
  * Copyright 2016      Jay D Dee   <jayddee246@gmail.com>
  * Copyright 2017-2019 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>
+ * Copyright 2018-2020 SChernykh   <https://github.com/SChernykh>
+ * Copyright 2016-2020 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
@@ -31,7 +31,7 @@
 #include <cstdint>
 
 
-#include "crypto/common/Algorithm.h"
+#include "base/crypto/Algorithm.h"
 
 
 namespace xmrig
diff --git a/src/crypto/common/Coin.cpp b/src/base/crypto/Coin.cpp
similarity index 98%
rename from src/crypto/common/Coin.cpp
rename to src/base/crypto/Coin.cpp
index b17b340e7..8b32e4fc2 100644
--- a/src/crypto/common/Coin.cpp
+++ b/src/base/crypto/Coin.cpp
@@ -24,7 +24,7 @@
  */
 
 
-#include "crypto/common/Coin.h"
+#include "base/crypto/Coin.h"
 #include "rapidjson/document.h"
 
 
diff --git a/src/crypto/common/Coin.h b/src/base/crypto/Coin.h
similarity index 98%
rename from src/crypto/common/Coin.h
rename to src/base/crypto/Coin.h
index 9e57a8e95..3197c46dc 100644
--- a/src/crypto/common/Coin.h
+++ b/src/base/crypto/Coin.h
@@ -27,7 +27,7 @@
 #define XMRIG_COIN_H
 
 
-#include "crypto/common/Algorithm.h"
+#include "base/crypto/Algorithm.h"
 #include "rapidjson/fwd.h"
 
 
diff --git a/src/crypto/common/keccak.cpp b/src/base/crypto/keccak.cpp
similarity index 97%
rename from src/crypto/common/keccak.cpp
rename to src/base/crypto/keccak.cpp
index 132ae0a86..f7940dfbc 100644
--- a/src/crypto/common/keccak.cpp
+++ b/src/base/crypto/keccak.cpp
@@ -6,7 +6,8 @@
  * 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 2016-2018 XMRig                     <https://github.com/xmrig>, <support@xmrig.com>
+ * Copyright 2018-2020 SChernykh                 <https://github.com/SChernykh>
+ * Copyright 2016-2020 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
@@ -23,11 +24,10 @@
  */
 
 
-#include <stdint.h>
 #include <memory.h>
 
 
-#include "crypto/common/keccak.h"
+#include "base/crypto/keccak.h"
 
 
 #define HASH_DATA_AREA 136
diff --git a/src/crypto/common/keccak.h b/src/base/crypto/keccak.h
similarity index 91%
rename from src/crypto/common/keccak.h
rename to src/base/crypto/keccak.h
index 6121044aa..2b039c909 100644
--- a/src/crypto/common/keccak.h
+++ b/src/base/crypto/keccak.h
@@ -6,7 +6,8 @@
  * 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 2016-2018 XMRig                     <https://github.com/xmrig>, <support@xmrig.com>
+ * Copyright 2018-2020 SChernykh                 <https://github.com/SChernykh>
+ * Copyright 2016-2020 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
@@ -26,8 +27,8 @@
 #ifndef XMRIG_KECCAK_H
 #define XMRIG_KECCAK_H
 
-#include <stdint.h>
-#include <string.h>
+#include <cstdint>
+#include <cstring>
 
 
 namespace xmrig {
diff --git a/src/base/kernel/Base.cpp b/src/base/kernel/Base.cpp
index 42d274676..34f6dbfd6 100644
--- a/src/base/kernel/Base.cpp
+++ b/src/base/kernel/Base.cpp
@@ -5,8 +5,8 @@
  * 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>
+ * Copyright 2018-2020 SChernykh   <https://github.com/SChernykh>
+ * Copyright 2016-2020 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
@@ -27,16 +27,17 @@
 #include <memory>
 
 
+#include "base/kernel/Base.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/Log.h"
 #include "base/io/Watcher.h"
-#include "base/kernel/Base.h"
 #include "base/kernel/interfaces/IBaseListener.h"
 #include "base/kernel/Platform.h"
 #include "base/kernel/Process.h"
+#include "base/net/tools/NetBuffer.h"
 #include "core/config/Config.h"
 #include "core/config/ConfigTransform.h"
 
@@ -84,6 +85,8 @@ public:
 
         delete config;
         delete watcher;
+
+        NetBuffer::destroy();
     }
 
 
@@ -127,7 +130,7 @@ private:
             return config.release();
         }
 
-        chain.addFile(Process::location(Process::ExeLocation, "config.json"));
+        chain.addFile(Process::location(Process::DataLocation, "config.json"));
 
         if (read(chain, config)) {
             return config.release();
diff --git a/src/base/kernel/Base.h b/src/base/kernel/Base.h
index ef850eddf..756b6cafc 100644
--- a/src/base/kernel/Base.h
+++ b/src/base/kernel/Base.h
@@ -5,8 +5,8 @@
  * 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>
+ * Copyright 2018-2020 SChernykh   <https://github.com/SChernykh>
+ * Copyright 2016-2020 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
diff --git a/src/base/kernel/Env.cpp b/src/base/kernel/Env.cpp
index 3498f2ec5..9b018e6ed 100644
--- a/src/base/kernel/Env.cpp
+++ b/src/base/kernel/Env.cpp
@@ -5,8 +5,8 @@
  * 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>
+ * Copyright 2018-2020 SChernykh   <https://github.com/SChernykh>
+ * Copyright 2016-2020 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
@@ -56,9 +56,13 @@ static std::map<String, String> variables;
 
 static void createVariables()
 {
-    variables.insert({ "XMRIG_VERSION", APP_VERSION });
-    variables.insert({ "XMRIG_EXE_DIR", Process::location(Process::ExeLocation, "") });
-    variables.insert({ "XMRIG_CWD",     Process::location(Process::CwdLocation, "") });
+    variables.insert({ "XMRIG_VERSION",  APP_VERSION });
+    variables.insert({ "XMRIG_EXE",      Process::exepath() });
+    variables.insert({ "XMRIG_EXE_DIR",  Process::location(Process::ExeLocation) });
+    variables.insert({ "XMRIG_CWD",      Process::location(Process::CwdLocation) });
+    variables.insert({ "XMRIG_HOME_DIR", Process::location(Process::HomeLocation) });
+    variables.insert({ "XMRIG_TEMP_DIR", Process::location(Process::TempLocation) });
+    variables.insert({ "XMRIG_DATA_DIR", Process::location(Process::DataLocation) });
 }
 #endif
 
diff --git a/src/base/kernel/Env.h b/src/base/kernel/Env.h
index 2f33abf94..dd06297d0 100644
--- a/src/base/kernel/Env.h
+++ b/src/base/kernel/Env.h
@@ -5,8 +5,8 @@
  * 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>
+ * Copyright 2018-2020 SChernykh   <https://github.com/SChernykh>
+ * Copyright 2016-2020 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
diff --git a/src/base/kernel/Process.cpp b/src/base/kernel/Process.cpp
index 4fc3ea3a3..34f5d02b1 100644
--- a/src/base/kernel/Process.cpp
+++ b/src/base/kernel/Process.cpp
@@ -5,8 +5,8 @@
  * 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>
+ * Copyright 2018-2020 SChernykh   <https://github.com/SChernykh>
+ * Copyright 2016-2020 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
@@ -24,6 +24,7 @@
 
 
 #include <ctime>
+#include <string>
 #include <uv.h>
 
 
@@ -34,20 +35,75 @@
 namespace xmrig {
 
 
-static size_t getLocation(Process::Location location, char *buf, size_t max)
-{
-    using namespace xmrig;
+static char pathBuf[520];
+static std::string dataDir;
+
+
+static std::string getPath(Process::Location location)
+{
+    size_t size = sizeof(pathBuf);
+
+    if (location == Process::DataLocation) {
+        if (!dataDir.empty()) {
+            return dataDir;
+        }
+
+        location = Process::ExeLocation;
+    }
+
+    if (location == Process::HomeLocation) {
+#       if UV_VERSION_HEX >= 0x010600
+        return uv_os_homedir(pathBuf, &size) < 0 ? "" : std::string(pathBuf, size);
+#       else
+        location = Process::ExeLocation;
+#       endif
+    }
+
+    if (location == Process::TempLocation) {
+#       if UV_VERSION_HEX >= 0x010900
+        return uv_os_tmpdir(pathBuf, &size) < 0 ? "" : std::string(pathBuf, size);
+#       else
+        location = Process::ExeLocation;
+#       endif
+    }
 
-    size_t size = max;
     if (location == Process::ExeLocation) {
-        return uv_exepath(buf, &size) < 0 ? 0 : size;
+        if (uv_exepath(pathBuf, &size) < 0) {
+            return {};
+        }
+
+        const auto path = std::string(pathBuf, size);
+        const auto pos  = path.rfind(Process::kDirSeparator);
+
+        if (pos != std::string::npos) {
+            return path.substr(0, pos);
+        }
+
+        return path;
     }
 
     if (location == Process::CwdLocation) {
-        return uv_cwd(buf, &size) < 0 ? 0 : size;
+        return uv_cwd(pathBuf, &size) < 0 ? "" : std::string(pathBuf, size);
     }
 
-    return 0;
+    return {};
+}
+
+
+static void setDataDir(const char *path)
+{
+    if (path == nullptr) {
+        return;
+    }
+
+    std::string dir = path;
+    if (!dir.empty() && (dir.back() == '/' || dir.back() == '\\')) {
+        dir.pop_back();
+    }
+
+    if (!dir.empty() && uv_chdir(dir.c_str()) == 0) {
+        dataDir = dir;
+    }
 }
 
 
@@ -58,46 +114,25 @@ xmrig::Process::Process(int argc, char **argv) :
     m_arguments(argc, argv)
 {
     srand(static_cast<unsigned int>(Chrono::currentMSecsSinceEpoch() ^ reinterpret_cast<uintptr_t>(this)));
+
+    setDataDir(m_arguments.value("--data-dir"));
+}
+
+
+xmrig::String xmrig::Process::exepath()
+{
+    size_t size = sizeof(pathBuf);
+
+    return uv_exepath(pathBuf, &size) < 0 ? "" : String(pathBuf, size);
 }
 
 
 xmrig::String xmrig::Process::location(Location location, const char *fileName)
 {
-    constexpr const size_t max = 520;
-
-    char *buf   = new char[max]();
-    size_t size = getLocation(location, buf, max);
-
-    if (size == 0) {
-        delete [] buf;
-
-        return String();
+    auto path = getPath(location);
+    if (path.empty() || fileName == nullptr) {
+        return path.c_str();
     }
 
-    if (fileName == nullptr) {
-        return buf;
-    }
-
-    if (location == ExeLocation) {
-        char *p = strrchr(buf, kDirSeparator);
-
-        if (p == nullptr) {
-            delete [] buf;
-
-            return String();
-        }
-
-        size = static_cast<size_t>(p - buf);
-    }
-
-    if ((size + strlen(fileName) + 2) >= max) {
-        delete [] buf;
-
-        return String();
-    }
-
-    buf[size] = kDirSeparator;
-    strcpy(buf + size + 1, fileName);
-
-    return buf;
+    return (path + kDirSeparator + fileName).c_str();
 }
diff --git a/src/base/kernel/Process.h b/src/base/kernel/Process.h
index 12cfc904c..29f247f2b 100644
--- a/src/base/kernel/Process.h
+++ b/src/base/kernel/Process.h
@@ -5,8 +5,8 @@
  * 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>
+ * Copyright 2018-2020 SChernykh   <https://github.com/SChernykh>
+ * Copyright 2016-2020 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
@@ -37,7 +37,10 @@ class Process
 public:
     enum Location {
         ExeLocation,
-        CwdLocation
+        CwdLocation,
+        DataLocation,
+        HomeLocation,
+        TempLocation
     };
 
 #   ifdef WIN32
@@ -48,6 +51,7 @@ public:
 
     Process(int argc, char **argv);
 
+    static String exepath();
     static String location(Location location, const char *fileName = nullptr);
 
     inline const Arguments &arguments() const { return m_arguments; }
diff --git a/src/base/kernel/config/BaseConfig.cpp b/src/base/kernel/config/BaseConfig.cpp
index 9150dbb1c..2b5a7120e 100644
--- a/src/base/kernel/config/BaseConfig.cpp
+++ b/src/base/kernel/config/BaseConfig.cpp
@@ -66,6 +66,11 @@ const char *BaseConfig::kVerbose        = "verbose";
 const char *BaseConfig::kWatch          = "watch";
 
 
+#ifdef XMRIG_FEATURE_TLS
+const char *BaseConfig::kTls            = "tls";
+#endif
+
+
 } // namespace xmrig
 
 
@@ -85,11 +90,15 @@ bool xmrig::BaseConfig::read(const IJsonReader &reader, const char *fileName)
     m_logFile      = reader.getString(kLogFile);
     m_userAgent    = reader.getString(kUserAgent);
 
+#   ifdef XMRIG_FEATURE_TLS
+    m_tls = reader.getValue(kTls);
+#   endif
+
     Log::setColors(reader.getBool(kColors, Log::isColors()));
     setPrintTime(reader.getUint(kPrintTime, 60));
     setVerbose(reader.getValue(kVerbose));
 
-    const rapidjson::Value &api = reader.getObject(kApi);
+    const auto &api = reader.getObject(kApi);
     if (api.IsObject()) {
         m_apiId       = Json::getString(api, kApiId);
         m_apiWorkerId = Json::getString(api, kApiWorkerId);
diff --git a/src/base/kernel/config/BaseConfig.h b/src/base/kernel/config/BaseConfig.h
index ac0478e13..c7e693084 100644
--- a/src/base/kernel/config/BaseConfig.h
+++ b/src/base/kernel/config/BaseConfig.h
@@ -31,6 +31,11 @@
 #include "base/net/stratum/Pools.h"
 
 
+#ifdef XMRIG_FEATURE_TLS
+#   include "base/net/tls/TlsConfig.h"
+#endif
+
+
 namespace xmrig {
 
 
@@ -55,23 +60,31 @@ public:
     static const char *kVerbose;
     static const char *kWatch;
 
+#   ifdef XMRIG_FEATURE_TLS
+    static const char *kTls;
+#   endif
+
     BaseConfig() = default;
 
-    inline bool isAutoSave() const                 { return m_autoSave; }
-    inline bool isBackground() const               { return m_background; }
-    inline bool isDryRun() const                   { return m_dryRun; }
-    inline bool isSyslog() const                   { return m_syslog; }
-    inline const char *logFile() const             { return m_logFile.data(); }
-    inline const char *userAgent() const           { return m_userAgent.data(); }
-    inline const Http &http() const                { return m_http; }
-    inline const Pools &pools() const              { return m_pools; }
-    inline const String &apiId() const             { return m_apiId; }
-    inline const String &apiWorkerId() const       { return m_apiWorkerId; }
-    inline uint32_t printTime() const              { return m_printTime; }
+    inline bool isAutoSave() const                          { return m_autoSave; }
+    inline bool isBackground() const                        { return m_background; }
+    inline bool isDryRun() const                            { return m_dryRun; }
+    inline bool isSyslog() const                            { return m_syslog; }
+    inline const char *logFile() const                      { return m_logFile.data(); }
+    inline const char *userAgent() const                    { return m_userAgent.data(); }
+    inline const Http &http() const                         { return m_http; }
+    inline const Pools &pools() const                       { return m_pools; }
+    inline const String &apiId() const                      { return m_apiId; }
+    inline const String &apiWorkerId() const                { return m_apiWorkerId; }
+    inline uint32_t printTime() const                       { return m_printTime; }
 
-    inline bool isWatch() const override                   { return m_watch && !m_fileName.isNull(); }
-    inline const String &fileName() const override         { return m_fileName; }
-    inline void setFileName(const char *fileName) override { m_fileName = fileName; }
+#   ifdef XMRIG_FEATURE_TLS
+    inline const TlsConfig &tls() const                     { return m_tls; }
+#   endif
+
+    inline bool isWatch() const override                    { return m_watch && !m_fileName.isNull(); }
+    inline const String &fileName() const override          { return m_fileName; }
+    inline void setFileName(const char *fileName) override  { m_fileName = fileName; }
 
     bool read(const IJsonReader &reader, const char *fileName) override;
     bool save() override;
@@ -94,6 +107,10 @@ protected:
     String m_userAgent;
     uint32_t m_printTime = 60;
 
+#   ifdef XMRIG_FEATURE_TLS
+    TlsConfig m_tls;
+#   endif
+
 private:
     inline void setPrintTime(uint32_t printTime) { if (printTime <= 3600) { m_printTime = printTime; } }
 
diff --git a/src/base/kernel/config/BaseTransform.cpp b/src/base/kernel/config/BaseTransform.cpp
index 1894f0c6d..8adebc23e 100644
--- a/src/base/kernel/config/BaseTransform.cpp
+++ b/src/base/kernel/config/BaseTransform.cpp
@@ -44,6 +44,11 @@
 #include "core/config/Config_platform.h"
 
 
+#ifdef XMRIG_FEATURE_TLS
+#   include "base/net/tls/TlsConfig.h"
+#endif
+
+
 void xmrig::BaseTransform::load(JsonChain &chain, Process *process, IConfigTransform &transform)
 {
     using namespace rapidjson;
@@ -199,6 +204,29 @@ void xmrig::BaseTransform::transform(rapidjson::Document &doc, int key, const ch
     case IConfig::UserAgentKey: /* --user-agent */
         return set(doc, BaseConfig::kUserAgent, arg);
 
+#   ifdef XMRIG_FEATURE_TLS
+    case IConfig::TlsCertKey: /* --tls-cert */
+        return set(doc, BaseConfig::kTls, TlsConfig::kCert, arg);
+
+    case IConfig::TlsCertKeyKey: /* --tls-cert-key */
+        return set(doc, BaseConfig::kTls, TlsConfig::kCertKey, arg);
+
+    case IConfig::TlsDHparamKey: /* --tls-dhparam */
+        return set(doc, BaseConfig::kTls, TlsConfig::kDhparam, arg);
+
+    case IConfig::TlsCiphersKey: /* --tls-ciphers */
+        return set(doc, BaseConfig::kTls, TlsConfig::kCiphers, arg);
+
+    case IConfig::TlsCipherSuitesKey: /* --tls-ciphersuites */
+        return set(doc, BaseConfig::kTls, TlsConfig::kCipherSuites, arg);
+
+    case IConfig::TlsProtocolsKey: /* --tls-protocols */
+        return set(doc, BaseConfig::kTls, TlsConfig::kProtocols, arg);
+
+    case IConfig::TlsGenKey: /* --tls-gen */
+        return set(doc, BaseConfig::kTls, TlsConfig::kGen, arg);
+#   endif
+
     case IConfig::RetriesKey:     /* --retries */
     case IConfig::RetryPauseKey:  /* --retry-pause */
     case IConfig::PrintTimeKey:   /* --print-time */
diff --git a/src/base/kernel/config/BaseTransform.h b/src/base/kernel/config/BaseTransform.h
index 16ad843fe..9550328ae 100644
--- a/src/base/kernel/config/BaseTransform.h
+++ b/src/base/kernel/config/BaseTransform.h
@@ -26,8 +26,8 @@
 #define XMRIG_BASETRANSFORM_H
 
 
+#include "base/crypto/Coin.h"
 #include "base/kernel/interfaces/IConfigTransform.h"
-#include "crypto/common/Coin.h"
 #include "rapidjson/document.h"
 
 
diff --git a/src/base/kernel/interfaces/IConfig.h b/src/base/kernel/interfaces/IConfig.h
index af1c3d169..32f4b29b4 100644
--- a/src/base/kernel/interfaces/IConfig.h
+++ b/src/base/kernel/interfaces/IConfig.h
@@ -26,7 +26,6 @@
 #define XMRIG_ICONFIG_H
 
 
-#include "crypto/common/Algorithm.h"
 #include "rapidjson/fwd.h"
 
 
@@ -74,6 +73,7 @@ public:
         DaemonKey            = 1018,
         DaemonPollKey        = 1019,
         SelfSelectKey        = 1028,
+        DataDirKey           = 1035,
 
         // xmrig common
         CPUPriorityKey       = 1021,
@@ -98,6 +98,7 @@ public:
         MemoryPoolKey        = 1027,
         YieldKey             = 1030,
         AstroBWTMaxSizeKey   = 1034,
+        AstroBWTAVX2Key      = 1036,
 
         // xmrig amd
         OclPlatformKey       = 1400,
@@ -131,6 +132,7 @@ public:
         TlsCiphersKey        = 1112,
         TlsCipherSuitesKey   = 1113,
         TlsProtocolsKey      = 1114,
+        TlsGenKey            = 1117,
         AlgoExtKey           = 1115,
         ProxyPasswordKey     = 1116,
         LoginFileKey         = 'L',
diff --git a/src/base/kernel/interfaces/IConfigTransform.h b/src/base/kernel/interfaces/IConfigTransform.h
index 8afe82217..571d3e5a7 100644
--- a/src/base/kernel/interfaces/IConfigTransform.h
+++ b/src/base/kernel/interfaces/IConfigTransform.h
@@ -5,8 +5,8 @@
  * 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>
+ * Copyright 2018-2020 SChernykh   <https://github.com/SChernykh>
+ * Copyright 2016-2020 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
@@ -26,7 +26,6 @@
 #define XMRIG_ICONFIGTRANSFORM_H
 
 
-#include "crypto/common/Algorithm.h"
 #include "rapidjson/fwd.h"
 
 
diff --git a/src/base/kernel/interfaces/ILineListener.h b/src/base/kernel/interfaces/ILineListener.h
index 1a6d49142..2759dcecb 100644
--- a/src/base/kernel/interfaces/ILineListener.h
+++ b/src/base/kernel/interfaces/ILineListener.h
@@ -5,8 +5,8 @@
  * 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>
+ * Copyright 2018-2020 SChernykh   <https://github.com/SChernykh>
+ * Copyright 2016-2020 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
@@ -26,15 +26,12 @@
 #define XMRIG_ILINELISTENER_H
 
 
-#include <stdint.h>
+#include <cstdint>
 
 
 namespace xmrig {
 
 
-class String;
-
-
 class ILineListener
 {
 public:
diff --git a/src/base/net/http/Fetch.cpp b/src/base/net/http/Fetch.cpp
index 361769e9d..a0eb2b555 100644
--- a/src/base/net/http/Fetch.cpp
+++ b/src/base/net/http/Fetch.cpp
@@ -27,7 +27,7 @@
 
 
 #ifdef XMRIG_FEATURE_TLS
-#   include "base/net/http/HttpsClient.h"
+#   include "base/net/https/HttpsClient.h"
 #endif
 
 
diff --git a/src/base/net/http/HttpClient.cpp b/src/base/net/http/HttpClient.cpp
index b684ddae0..82f62c84a 100644
--- a/src/base/net/http/HttpClient.cpp
+++ b/src/base/net/http/HttpClient.cpp
@@ -29,7 +29,7 @@
 #include "base/io/log/Log.h"
 #include "base/kernel/Platform.h"
 #include "base/net/dns/Dns.h"
-#include "base/tools/Baton.h"
+#include "base/net/tools/NetBuffer.h"
 
 
 #include <sstream>
@@ -41,31 +41,6 @@ namespace xmrig {
 static const char *kCRLF = "\r\n";
 
 
-class HttpClientWriteBaton : public Baton<uv_write_t>
-{
-public:
-    inline HttpClientWriteBaton(const std::string &header, std::string &&body) :
-        m_body(std::move(body)),
-        m_header(header)
-    {
-        m_bufs[0] = uv_buf_init(const_cast<char *>(m_header.c_str()), m_header.size());
-        m_bufs[1] = m_body.empty() ? uv_buf_init(nullptr, 0) : uv_buf_init(const_cast<char *>(m_body.c_str()), m_body.size());
-    }
-
-    void write(uv_stream_t *stream)
-    {
-        uv_write(&req, stream, m_bufs, nbufs(), [](uv_write_t *req, int) { delete reinterpret_cast<HttpClientWriteBaton *>(req->data); });
-    }
-
-private:
-    inline size_t nbufs() const { return m_bufs[1].len > 0 ? 2 : 1; }
-
-    std::string m_body;
-    std::string m_header;
-    uv_buf_t m_bufs[2]{};
-};
-
-
 } // namespace xmrig
 
 
@@ -137,7 +112,8 @@ void xmrig::HttpClient::handshake()
 
     headers.clear();
 
-    write(ss.str());
+    body.insert(0, ss.str());
+    write(std::move(body), false);
 }
 
 
@@ -149,13 +125,6 @@ void xmrig::HttpClient::read(const char *data, size_t size)
 }
 
 
-void xmrig::HttpClient::write(const std::string &header)
-{
-    auto baton = new HttpClientWriteBaton(header, std::move(body));
-    baton->write(stream());
-}
-
-
 void xmrig::HttpClient::onConnect(uv_connect_t *req, int status)
 {
     auto client = static_cast<HttpClient *>(req->data);
@@ -174,12 +143,7 @@ void xmrig::HttpClient::onConnect(uv_connect_t *req, int status)
         return;
     }
 
-    uv_read_start(client->stream(),
-        [](uv_handle_t *, size_t suggested_size, uv_buf_t *buf)
-        {
-            buf->base = new char[suggested_size];
-            buf->len  = suggested_size;
-        },
+    uv_read_start(client->stream(), NetBuffer::onAlloc,
         [](uv_stream_t *tcp, ssize_t nread, const uv_buf_t *buf)
         {
             auto client = static_cast<HttpClient*>(tcp->data);
@@ -194,7 +158,7 @@ void xmrig::HttpClient::onConnect(uv_connect_t *req, int status)
                 client->close(static_cast<int>(nread));
             }
 
-            delete [] buf->base;
+            NetBuffer::release(buf);
         });
 
     client->handshake();
diff --git a/src/base/net/http/HttpClient.h b/src/base/net/http/HttpClient.h
index b54882a0e..acfe15e2a 100644
--- a/src/base/net/http/HttpClient.h
+++ b/src/base/net/http/HttpClient.h
@@ -59,7 +59,6 @@ protected:
 
     virtual void handshake();
     virtual void read(const char *data, size_t size);
-    virtual void write(const std::string &header);
 
 protected:
     inline const FetchRequest &req() const  { return m_req; }
diff --git a/src/base/net/http/HttpContext.cpp b/src/base/net/http/HttpContext.cpp
index 66a25d6a1..441f3b825 100644
--- a/src/base/net/http/HttpContext.cpp
+++ b/src/base/net/http/HttpContext.cpp
@@ -27,6 +27,7 @@
 #include "base/net/http/HttpContext.h"
 #include "3rdparty/http-parser/http_parser.h"
 #include "base/kernel/interfaces/IHttpListener.h"
+#include "base/tools/Baton.h"
 #include "base/tools/Chrono.h"
 
 
@@ -42,6 +43,37 @@ static std::map<uint64_t, HttpContext *> storage;
 static uint64_t SEQUENCE = 0;
 
 
+class HttpWriteBaton : public Baton<uv_write_t>
+{
+public:
+    XMRIG_DISABLE_COPY_MOVE_DEFAULT(HttpWriteBaton)
+
+    inline HttpWriteBaton(std::string &&body, HttpContext *ctx) :
+        m_ctx(ctx),
+        m_body(std::move(body))
+    {
+        m_buf = uv_buf_init(const_cast<char *>(m_body.c_str()), m_body.size());
+    }
+
+    inline ~HttpWriteBaton()
+    {
+        if (m_ctx) {
+            m_ctx->close();
+        }
+    }
+
+    void write(uv_stream_t *stream)
+    {
+        uv_write(&req, stream, &m_buf, 1, [](uv_write_t *req, int) { delete reinterpret_cast<HttpWriteBaton *>(req->data); });
+    }
+
+private:
+    HttpContext *m_ctx;
+    std::string m_body;
+    uv_buf_t m_buf{};
+};
+
+
 } // namespace xmrig
 
 
@@ -75,6 +107,17 @@ xmrig::HttpContext::~HttpContext()
 }
 
 
+void xmrig::HttpContext::write(std::string &&data, bool close)
+{
+    if (uv_is_writable(stream()) != 1) {
+        return;
+    }
+
+    auto baton = new HttpWriteBaton(std::move(data), close ? this : nullptr);
+    baton->write(stream());
+}
+
+
 bool xmrig::HttpContext::isRequest() const
 {
     return m_parser->type == HTTP_REQUEST;
diff --git a/src/base/net/http/HttpContext.h b/src/base/net/http/HttpContext.h
index 784bb7ed1..a75546790 100644
--- a/src/base/net/http/HttpContext.h
+++ b/src/base/net/http/HttpContext.h
@@ -65,6 +65,8 @@ public:
     inline const char *tlsVersion() const override      { return nullptr; }
     inline uint16_t port() const override               { return 0; }
 
+    void write(std::string &&data, bool close) override;
+
     bool isRequest() const override;
     size_t parse(const char *data, size_t size);
     std::string ip() const override;
diff --git a/src/base/net/http/HttpData.h b/src/base/net/http/HttpData.h
index cd852639c..82a8ee8f8 100644
--- a/src/base/net/http/HttpData.h
+++ b/src/base/net/http/HttpData.h
@@ -53,12 +53,13 @@ public:
 
     inline uint64_t id() const { return m_id; }
 
-    virtual bool isRequest() const              = 0;
-    virtual const char *host() const            = 0;
-    virtual const char *tlsFingerprint() const  = 0;
-    virtual const char *tlsVersion() const      = 0;
-    virtual std::string ip() const              = 0;
-    virtual uint16_t port() const               = 0;
+    virtual bool isRequest() const                      = 0;
+    virtual const char *host() const                    = 0;
+    virtual const char *tlsFingerprint() const          = 0;
+    virtual const char *tlsVersion() const              = 0;
+    virtual std::string ip() const                      = 0;
+    virtual uint16_t port() const                       = 0;
+    virtual void write(std::string &&data, bool close)  = 0;
 
     int method      = 0;
     int status      = 0;
diff --git a/src/base/net/http/HttpResponse.cpp b/src/base/net/http/HttpResponse.cpp
index ebd0bcf98..89e224319 100644
--- a/src/base/net/http/HttpResponse.cpp
+++ b/src/base/net/http/HttpResponse.cpp
@@ -6,8 +6,8 @@
  * Copyright 2016      Jay D Dee   <jayddee246@gmail.com>
  * Copyright 2017-2018 XMR-Stak    <https://github.com/fireice-uk>, <https://github.com/psychocrypt>
  * Copyright 2014-2019 heapwolf    <https://github.com/heapwolf>
- * Copyright 2018-2019 SChernykh   <https://github.com/SChernykh>
- * Copyright 2016-2019 XMRig       <https://github.com/xmrig>, <support@xmrig.com>
+ * Copyright 2018-2020 SChernykh   <https://github.com/SChernykh>
+ * Copyright 2016-2020 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
@@ -28,8 +28,6 @@
 #include "3rdparty/http-parser/http_parser.h"
 #include "base/io/log/Log.h"
 #include "base/net/http/HttpContext.h"
-#include "base/tools/Baton.h"
-#include "base/tools/Object.h"
 
 
 #include <cinttypes>
@@ -45,52 +43,6 @@ static const char *kCRLF      = "\r\n";
 static const char *kUserAgent = "user-agent";
 
 
-class WriteBaton : public Baton<uv_write_t>
-{
-public:
-    XMRIG_DISABLE_COPY_MOVE_DEFAULT(WriteBaton)
-
-    inline WriteBaton(const std::stringstream &ss, const char *data, size_t size, HttpContext *ctx) :
-        m_ctx(ctx),
-        m_header(ss.str())
-    {
-        bufs[0].len  = m_header.size();
-        bufs[0].base = const_cast<char *>(m_header.c_str());
-
-        if (data) {
-            bufs[1].len  = size;
-            bufs[1].base = new char[size];
-            memcpy(bufs[1].base, data, size);
-        }
-        else {
-            bufs[1].base = nullptr;
-            bufs[1].len  = 0;
-        }
-    }
-
-
-    inline ~WriteBaton()
-    {
-        if (count() == 2) {
-            delete [] bufs[1].base;
-        }
-
-        m_ctx->close();
-    }
-
-
-    inline size_t count() const                      { return bufs[1].base == nullptr ? 1 : 2; }
-    inline size_t size() const                       { return bufs[0].len + bufs[1].len; }
-    inline static void onWrite(uv_write_t *req, int) { delete reinterpret_cast<WriteBaton *>(req->data); }
-
-
-    uv_buf_t bufs[2]{};
-
-private:
-    HttpContext *m_ctx;
-    std::string m_header;
-};
-
 } // namespace xmrig
 
 
@@ -134,8 +86,8 @@ void xmrig::HttpResponse::end(const char *data, size_t size)
 
     ss << kCRLF;
 
-    auto ctx   = HttpContext::get(m_id);
-    auto baton = new WriteBaton(ss, data, size, ctx);
+    auto ctx         = HttpContext::get(m_id);
+    std::string body = data ? (ss.str() + std::string(data, size)) : ss.str();
 
 #   ifndef APP_DEBUG
     if (statusCode() >= 400)
@@ -149,11 +101,11 @@ void xmrig::HttpResponse::end(const char *data, size_t size)
                    ctx->url.c_str(),
                    err ? 31 : 32,
                    statusCode(),
-                   baton->size(),
+                   body.size(),
                    ctx->elapsed(),
                    ctx->headers.count(kUserAgent) ? ctx->headers.at(kUserAgent).c_str() : nullptr
                    );
     }
 
-    uv_write(&baton->req, ctx->stream(), baton->bufs, baton->count(), WriteBaton::onWrite);
+    ctx->write(std::move(body), true);
 }
diff --git a/src/base/net/http/HttpResponse.h b/src/base/net/http/HttpResponse.h
index c2bc90011..1891ad7ef 100644
--- a/src/base/net/http/HttpResponse.h
+++ b/src/base/net/http/HttpResponse.h
@@ -6,8 +6,8 @@
  * Copyright 2016      Jay D Dee   <jayddee246@gmail.com>
  * Copyright 2017-2018 XMR-Stak    <https://github.com/fireice-uk>, <https://github.com/psychocrypt>
  * Copyright 2014-2019 heapwolf    <https://github.com/heapwolf>
- * Copyright 2018-2019 SChernykh   <https://github.com/SChernykh>
- * Copyright 2016-2019 XMRig       <https://github.com/xmrig>, <support@xmrig.com>
+ * Copyright 2018-2020 SChernykh   <https://github.com/SChernykh>
+ * Copyright 2016-2020 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
diff --git a/src/base/net/http/HttpServer.cpp b/src/base/net/http/HttpServer.cpp
index 4af39c2eb..80377f772 100644
--- a/src/base/net/http/HttpServer.cpp
+++ b/src/base/net/http/HttpServer.cpp
@@ -28,11 +28,10 @@
 #include <uv.h>
 
 
-#include "3rdparty/http-parser/http_parser.h"
-#include "base/kernel/interfaces/IHttpListener.h"
-#include "base/net/http/HttpContext.h"
-#include "base/net/http/HttpResponse.h"
 #include "base/net/http/HttpServer.h"
+#include "3rdparty/http-parser/http_parser.h"
+#include "base/net/http/HttpContext.h"
+#include "base/net/tools/NetBuffer.h"
 
 
 xmrig::HttpServer::HttpServer(const std::shared_ptr<IHttpListener> &listener) :
@@ -52,17 +51,7 @@ void xmrig::HttpServer::onConnection(uv_stream_t *stream, uint16_t)
     auto ctx = new HttpContext(HTTP_REQUEST, m_listener);
     uv_accept(stream, ctx->stream());
 
-    uv_read_start(ctx->stream(),
-        [](uv_handle_t *, size_t suggested_size, uv_buf_t *buf)
-        {
-            buf->base = new char[suggested_size];
-
-#           ifdef _WIN32
-            buf->len = static_cast<unsigned int>(suggested_size);
-#           else
-            buf->len = suggested_size;
-#           endif
-        },
+    uv_read_start(ctx->stream(), NetBuffer::onAlloc,
         [](uv_stream_t *tcp, ssize_t nread, const uv_buf_t *buf)
         {
             auto ctx = static_cast<HttpContext*>(tcp->data);
@@ -78,6 +67,6 @@ void xmrig::HttpServer::onConnection(uv_stream_t *stream, uint16_t)
                 ctx->close();
             }
 
-            delete [] buf->base;
+            NetBuffer::release(buf);
         });
 }
diff --git a/src/base/net/http/HttpsClient.cpp b/src/base/net/https/HttpsClient.cpp
similarity index 81%
rename from src/base/net/http/HttpsClient.cpp
rename to src/base/net/https/HttpsClient.cpp
index 96162e9c4..28b5a5efe 100644
--- a/src/base/net/http/HttpsClient.cpp
+++ b/src/base/net/https/HttpsClient.cpp
@@ -29,7 +29,7 @@
 #include <uv.h>
 
 
-#include "base/net/http/HttpsClient.h"
+#include "base/net/https/HttpsClient.h"
 #include "base/io/log/Log.h"
 #include "base/tools/Buffer.h"
 
@@ -49,8 +49,8 @@ xmrig::HttpsClient::HttpsClient(FetchRequest &&req, const std::weak_ptr<IHttpLis
         return;
     }
 
-    m_writeBio = BIO_new(BIO_s_mem());
-    m_readBio  = BIO_new(BIO_s_mem());
+    m_write = BIO_new(BIO_s_mem());
+    m_read  = BIO_new(BIO_s_mem());
     SSL_CTX_set_options(m_ctx, SSL_OP_NO_SSLv2 | SSL_OP_NO_SSLv3);
 }
 
@@ -89,24 +89,24 @@ void xmrig::HttpsClient::handshake()
     }
 
     SSL_set_connect_state(m_ssl);
-    SSL_set_bio(m_ssl, m_readBio, m_writeBio);
+    SSL_set_bio(m_ssl, m_read, m_write);
     SSL_set_tlsext_host_name(m_ssl, host());
 
     SSL_do_handshake(m_ssl);
 
-    flush();
+    flush(false);
 }
 
 
 void xmrig::HttpsClient::read(const char *data, size_t size)
 {
-    BIO_write(m_readBio, data, size);
+    BIO_write(m_read, data, size);
 
     if (!SSL_is_init_finished(m_ssl)) {
         const int rc = SSL_connect(m_ssl);
 
         if (rc < 0 && SSL_get_error(m_ssl, rc) == SSL_ERROR_WANT_READ) {
-            flush();
+            flush(false);
         } else if (rc == 1) {
             X509 *cert = SSL_get_peer_certificate(m_ssl);
             if (!verify(cert)) {
@@ -123,19 +123,25 @@ void xmrig::HttpsClient::read(const char *data, size_t size)
       return;
     }
 
-    int bytes_read = 0;
-    while ((bytes_read = SSL_read(m_ssl, m_buf, sizeof(m_buf))) > 0) {
-        HttpClient::read(m_buf, static_cast<size_t>(bytes_read));
+    static char buf[16384]{};
+
+    int rc = 0;
+    while ((rc = SSL_read(m_ssl, buf, sizeof(buf))) > 0) {
+        HttpClient::read(buf, static_cast<size_t>(rc));
+    }
+
+    if (rc == 0) {
+        close(UV_EOF);
     }
 }
 
 
-void xmrig::HttpsClient::write(const std::string &header)
+void xmrig::HttpsClient::write(std::string &&data, bool close)
 {
-    SSL_write(m_ssl, (header + body).c_str(), header.size() + body.size());
-    body.clear();
+    const std::string body = std::move(data);
+    SSL_write(m_ssl, body.data(), body.size());
 
-    flush();
+    flush(close);
 }
 
 
@@ -182,23 +188,17 @@ bool xmrig::HttpsClient::verifyFingerprint(X509 *cert)
 }
 
 
-void xmrig::HttpsClient::flush()
+void xmrig::HttpsClient::flush(bool close)
 {
-    uv_buf_t buf;
-    buf.len = BIO_get_mem_data(m_writeBio, &buf.base);
-
-    if (buf.len == 0) {
+    if (uv_is_writable(stream()) != 1) {
         return;
     }
 
-    bool result = false;
-    if (uv_is_writable(stream())) {
-        result = uv_try_write(stream(), &buf, 1) == static_cast<int>(buf.len);
+    char *data        = nullptr;
+    const size_t size = BIO_get_mem_data(m_write, &data);
+    std::string body(data, size);
 
-        if (!result) {
-            close(UV_EIO);
-        }
-    }
+    (void) BIO_reset(m_write);
 
-    (void) BIO_reset(m_writeBio);
+    HttpContext::write(std::move(body), close);
 }
diff --git a/src/base/net/http/HttpsClient.h b/src/base/net/https/HttpsClient.h
similarity index 92%
rename from src/base/net/http/HttpsClient.h
rename to src/base/net/https/HttpsClient.h
index afac6e018..eeeec7473 100644
--- a/src/base/net/http/HttpsClient.h
+++ b/src/base/net/https/HttpsClient.h
@@ -55,17 +55,17 @@ public:
 protected:
     void handshake() override;
     void read(const char *data, size_t size) override;
-    void write(const std::string &header) override;
 
 private:
+    void write(std::string &&data, bool close) override;
+
     bool verify(X509 *cert);
     bool verifyFingerprint(X509 *cert);
-    void flush();
+    void flush(bool close);
 
-    BIO *m_readBio                      = nullptr;
-    BIO *m_writeBio                     = nullptr;
+    BIO *m_read                         = nullptr;
+    BIO *m_write                        = nullptr;
     bool m_ready                        = false;
-    char m_buf[1024 * 2]{};
     char m_fingerprint[32 * 2 + 8]{};
     SSL *m_ssl                          = nullptr;
     SSL_CTX *m_ctx                      = nullptr;
diff --git a/src/base/net/https/HttpsContext.cpp b/src/base/net/https/HttpsContext.cpp
new file mode 100644
index 000000000..8db31812e
--- /dev/null
+++ b/src/base/net/https/HttpsContext.cpp
@@ -0,0 +1,99 @@
+/* XMRig
+ * Copyright 2018-2020 SChernykh   <https://github.com/SChernykh>
+ * Copyright 2016-2020 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 "base/net/https/HttpsContext.h"
+#include "3rdparty/http-parser/http_parser.h"
+#include "base/net/tls/TlsContext.h"
+
+
+#include <openssl/bio.h>
+#include <uv.h>
+
+
+xmrig::HttpsContext::HttpsContext(TlsContext *tls, const std::weak_ptr<IHttpListener> &listener) :
+    HttpContext(HTTP_REQUEST, listener),
+    ServerTls(tls ? tls->ctx() : nullptr)
+{
+    if (!tls) {
+        m_mode = TLS_OFF;
+    }
+}
+
+
+xmrig::HttpsContext::~HttpsContext() = default;
+
+
+void xmrig::HttpsContext::append(char *data, size_t size)
+{
+    if (m_mode == TLS_AUTO) {
+        m_mode = isTLS(data, size) ? TLS_ON : TLS_OFF;
+    }
+
+    if (m_mode == TLS_ON) {
+        read(data, size);
+    }
+    else {
+        parse(data, size);
+    }
+}
+
+
+bool xmrig::HttpsContext::write(BIO *bio)
+{
+    if (uv_is_writable(stream()) != 1) {
+        return false;
+    }
+
+    char *data        = nullptr;
+    const size_t size = BIO_get_mem_data(bio, &data);
+    std::string body(data, size);
+
+    (void) BIO_reset(bio);
+
+    HttpContext::write(std::move(body), m_close);
+
+    return true;
+}
+
+
+void xmrig::HttpsContext::parse(char *data, size_t size)
+{
+    if (HttpContext::parse(data, size) < size) {
+        close();
+    }
+}
+
+
+void xmrig::HttpsContext::shutdown()
+{
+    close();
+}
+
+
+void xmrig::HttpsContext::write(std::string &&data, bool close)
+{
+    m_close = close;
+
+    if (m_mode == TLS_ON) {
+        send(data.data(), data.size());
+    }
+    else {
+        HttpContext::write(std::move(data), close);
+    }
+}
diff --git a/src/base/net/https/HttpsContext.h b/src/base/net/https/HttpsContext.h
new file mode 100644
index 000000000..af57b6b4f
--- /dev/null
+++ b/src/base/net/https/HttpsContext.h
@@ -0,0 +1,73 @@
+/* XMRig
+ * Copyright 2018-2020 SChernykh   <https://github.com/SChernykh>
+ * Copyright 2016-2020 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_HTTPSCONTEXT_H
+#define XMRIG_HTTPSCONTEXT_H
+
+
+using BIO = struct bio_st;
+using SSL = struct ssl_st;
+
+
+#include "base/net/http/HttpContext.h"
+#include "base/net/tls/ServerTls.h"
+
+
+namespace xmrig {
+
+
+class TlsContext;
+
+
+class HttpsContext : public HttpContext, public ServerTls
+{
+public:
+    XMRIG_DISABLE_COPY_MOVE_DEFAULT(HttpsContext)
+
+    HttpsContext(TlsContext *tls, const std::weak_ptr<IHttpListener> &listener);
+    ~HttpsContext() override;
+
+    void append(char *data, size_t size);
+
+protected:
+    // ServerTls
+    bool write(BIO *bio) override;
+    void parse(char *data, size_t size) override;
+    void shutdown() override;
+
+    // HttpContext
+    void write(std::string &&data, bool close) override;
+
+private:
+    enum TlsMode : uint32_t {
+      TLS_AUTO,
+      TLS_OFF,
+      TLS_ON
+    };
+
+    bool m_close    = false;
+    TlsMode m_mode  = TLS_AUTO;
+};
+
+
+} // namespace xmrig
+
+
+#endif // XMRIG_HTTPSCONTEXT_H
+
diff --git a/src/base/net/https/HttpsServer.cpp b/src/base/net/https/HttpsServer.cpp
new file mode 100644
index 000000000..3a6fb0801
--- /dev/null
+++ b/src/base/net/https/HttpsServer.cpp
@@ -0,0 +1,71 @@
+/* XMRig
+ * Copyright 2018-2020 SChernykh   <https://github.com/SChernykh>
+ * Copyright 2016-2020 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 <uv.h>
+
+
+#include "base/net/https/HttpsServer.h"
+#include "base/net/https/HttpsContext.h"
+#include "base/net/tls/TlsContext.h"
+#include "base/net/tools/NetBuffer.h"
+
+
+xmrig::HttpsServer::HttpsServer(const std::shared_ptr<IHttpListener> &listener) :
+    m_listener(listener)
+{
+}
+
+
+xmrig::HttpsServer::~HttpsServer()
+{
+    HttpContext::closeAll();
+
+    delete m_tls;
+}
+
+
+bool xmrig::HttpsServer::setTls(const TlsConfig &config)
+{
+    m_tls = TlsContext::create(config);
+
+    return m_tls != nullptr;
+}
+
+
+void xmrig::HttpsServer::onConnection(uv_stream_t *stream, uint16_t)
+{
+    auto ctx = new HttpsContext(m_tls, m_listener);
+    uv_accept(stream, ctx->stream());
+
+    uv_read_start(ctx->stream(), NetBuffer::onAlloc, onRead);
+}
+
+
+void xmrig::HttpsServer::onRead(uv_stream_t *stream, ssize_t nread, const uv_buf_t *buf)
+{
+    auto ctx = static_cast<HttpsContext*>(stream->data);
+    if (nread >= 0) {
+        ctx->append(buf->base, static_cast<size_t>(nread));
+    }
+    else {
+        ctx->close();
+    }
+
+    NetBuffer::release(buf);
+}
diff --git a/src/base/net/https/HttpsServer.h b/src/base/net/https/HttpsServer.h
new file mode 100644
index 000000000..7f567625b
--- /dev/null
+++ b/src/base/net/https/HttpsServer.h
@@ -0,0 +1,72 @@
+/* XMRig
+ * Copyright 2018-2020 SChernykh   <https://github.com/SChernykh>
+ * Copyright 2016-2020 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_HTTPSSERVER_H
+#define XMRIG_HTTPSSERVER_H
+
+
+using uv_tcp_t  = struct uv_tcp_s;
+
+struct http_parser;
+struct http_parser_settings;
+struct uv_buf_t;
+
+
+#include "base/kernel/interfaces/ITcpServerListener.h"
+#include "base/tools/Object.h"
+
+
+#include <memory>
+
+
+namespace xmrig {
+
+
+class IHttpListener;
+class TlsContext;
+class TlsConfig;
+
+
+class HttpsServer : public ITcpServerListener
+{
+public:
+    XMRIG_DISABLE_COPY_MOVE_DEFAULT(HttpsServer)
+
+    HttpsServer(const std::shared_ptr<IHttpListener> &listener);
+    ~HttpsServer() override;
+
+    bool setTls(const TlsConfig &config);
+
+protected:
+    void onConnection(uv_stream_t *stream, uint16_t port) override;
+
+private:
+    static void onRead(uv_stream_t *stream, ssize_t nread, const uv_buf_t *buf);
+
+    std::weak_ptr<IHttpListener> m_listener;
+    TlsContext *m_tls   = nullptr;
+    uv_tcp_t *m_tcp     = nullptr;
+};
+
+
+} // namespace xmrig
+
+
+#endif // XMRIG_HTTPSSERVER_H
+
diff --git a/src/base/net/stratum/Client.cpp b/src/base/net/stratum/Client.cpp
index bd7b22192..16a5f79c9 100644
--- a/src/base/net/stratum/Client.cpp
+++ b/src/base/net/stratum/Client.cpp
@@ -38,13 +38,14 @@
 #endif
 
 
+#include "base/net/stratum/Client.h"
 #include "base/io/json/Json.h"
 #include "base/io/json/JsonRequest.h"
 #include "base/io/log/Log.h"
 #include "base/kernel/interfaces/IClientListener.h"
 #include "base/net/dns/Dns.h"
-#include "base/net/stratum/Client.h"
 #include "base/net/stratum/Socks5.h"
+#include "base/net/tools/NetBuffer.h"
 #include "base/tools/Buffer.h"
 #include "base/tools/Chrono.h"
 #include "net/JobResult.h"
@@ -83,6 +84,7 @@ xmrig::Client::Client(int id, const char *agent, IClientListener *listener) :
     m_agent(agent),
     m_sendBuf(1024)
 {
+    m_reader.setListener(this);
     m_key = m_storage.add(this);
     m_dns = new Dns(this);
 }
@@ -542,7 +544,7 @@ int xmrig::Client::resolve(const String &host)
 {
     setState(HostLookupState);
 
-    m_recvBuf.reset();
+    m_reader.reset();
 
     if (m_failures == -1) {
         m_failures = 0;
@@ -837,14 +839,10 @@ void xmrig::Client::ping()
 }
 
 
-void xmrig::Client::read(ssize_t nread)
+void xmrig::Client::read(ssize_t nread, const uv_buf_t *buf)
 {
     const auto size = static_cast<size_t>(nread);
 
-    if (nread > 0 && size > m_recvBuf.available()) {
-        nread = UV_ENOBUFS;
-    }
-
     if (nread < 0) {
         if (!isQuiet()) {
             LOG_ERR("[%s] read error: \"%s\"", url(), uv_strerror(static_cast<int>(nread)));
@@ -859,12 +857,8 @@ void xmrig::Client::read(ssize_t nread)
         return reconnect();
     }
 
-    m_recvBuf.nread(size);
-
     if (m_socks5) {
-        if (m_socks5->read(m_recvBuf.base(), m_recvBuf.pos())) {
-            m_recvBuf.reset();
-        }
+        m_socks5->read(buf->base, size);
 
         if (m_socks5->isReady()) {
             delete m_socks5;
@@ -886,13 +880,12 @@ void xmrig::Client::read(ssize_t nread)
     if (isTLS()) {
         LOG_DEBUG("[%s] TLS received (%d bytes)", url(), static_cast<int>(nread));
 
-        m_tls->read(m_recvBuf.base(), m_recvBuf.pos());
-        m_recvBuf.reset();
+        m_tls->read(buf->base, size);
     }
     else
 #   endif
     {
-        m_recvBuf.getline(this);
+        m_reader.parse(buf->base, size);
     }
 }
 
@@ -959,23 +952,6 @@ void xmrig::Client::startTimeout()
 }
 
 
-void xmrig::Client::onAllocBuffer(uv_handle_t *handle, size_t, uv_buf_t *buf)
-{
-    auto client = getClient(handle->data);
-    if (!client) {
-        return;
-    }
-
-    buf->base = client->m_recvBuf.current();
-
-#   ifdef _WIN32
-    buf->len = static_cast<ULONG>(client->m_recvBuf.available());
-#   else
-    buf->len = client->m_recvBuf.available();
-#   endif
-}
-
-
 void xmrig::Client::onClose(uv_handle_t *handle)
 {
     auto client = getClient(handle->data);
@@ -1027,17 +1003,19 @@ void xmrig::Client::onConnect(uv_connect_t *req, int status)
     client->m_stream->data = req->data;
     client->setState(ConnectedState);
 
-    uv_read_start(client->m_stream, onAllocBuffer, onRead);
+    uv_read_start(client->m_stream, NetBuffer::onAlloc, onRead);
     delete req;
 
     client->handshake();
 }
 
 
-void xmrig::Client::onRead(uv_stream_t *stream, ssize_t nread, const uv_buf_t *)
+void xmrig::Client::onRead(uv_stream_t *stream, ssize_t nread, const uv_buf_t *buf)
 {
     auto client = getClient(stream->data);
     if (client) {
-        client->read(nread);
+        client->read(nread, buf);
     }
+
+    NetBuffer::release(buf);
 }
diff --git a/src/base/net/stratum/Client.h b/src/base/net/stratum/Client.h
index e26eaa7b7..d6ebf396d 100644
--- a/src/base/net/stratum/Client.h
+++ b/src/base/net/stratum/Client.h
@@ -39,10 +39,9 @@
 #include "base/net/stratum/Job.h"
 #include "base/net/stratum/Pool.h"
 #include "base/net/stratum/SubmitResult.h"
-#include "base/net/tools/RecvBuf.h"
+#include "base/net/tools/LineReader.h"
 #include "base/net/tools/Storage.h"
 #include "base/tools/Object.h"
-#include "crypto/common/Algorithm.h"
 
 
 using BIO = struct bio_st;
@@ -62,7 +61,6 @@ public:
 
     constexpr static uint64_t kConnectTimeout   = 20 * 1000;
     constexpr static uint64_t kResponseTimeout  = 20 * 1000;
-    constexpr static size_t kInputBufferSize    = 1024 * 16;
     constexpr static size_t kMaxSendBufferSize  = 1024 * 16;
 
     Client(int id, const char *agent, IClientListener *listener);
@@ -109,7 +107,7 @@ private:
     void parseNotification(const char *method, const rapidjson::Value &params, const rapidjson::Value &error);
     void parseResponse(int64_t id, const rapidjson::Value &result, const rapidjson::Value &error);
     void ping();
-    void read(ssize_t nread);
+    void read(ssize_t nread, const uv_buf_t *buf);
     void reconnect();
     void setState(SocketState state);
     void startTimeout();
@@ -119,7 +117,6 @@ private:
     inline void setExtension(Extension ext, bool enable) noexcept { m_extensions.set(ext, enable); }
     template<Extension ext> inline bool has() const noexcept      { return m_extensions.test(ext); }
 
-    static void onAllocBuffer(uv_handle_t *handle, size_t suggested_size, uv_buf_t *buf);
     static void onClose(uv_handle_t *handle);
     static void onConnect(uv_connect_t *req, int status);
     static void onRead(uv_stream_t *stream, ssize_t nread, const uv_buf_t *buf);
@@ -128,7 +125,7 @@ private:
 
     const char *m_agent;
     Dns *m_dns;
-    RecvBuf<kInputBufferSize> m_recvBuf;
+    LineReader m_reader;
     Socks5 *m_socks5            = nullptr;
     std::bitset<EXT_MAX> m_extensions;
     std::vector<char> m_sendBuf;
diff --git a/src/base/net/stratum/Job.h b/src/base/net/stratum/Job.h
index ed369a163..a4ecd3e10 100644
--- a/src/base/net/stratum/Job.h
+++ b/src/base/net/stratum/Job.h
@@ -6,9 +6,9 @@
  * 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 2019      Howard Chu  <https://github.com/hyc>
- * Copyright 2016-2019 XMRig       <https://github.com/xmrig>, <support@xmrig.com>
+ * Copyright 2018-2020 SChernykh   <https://github.com/SChernykh>
+ * Copyright 2016-2020 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
@@ -32,9 +32,9 @@
 #include <cstdint>
 
 
+#include "base/crypto/Algorithm.h"
 #include "base/tools/Buffer.h"
 #include "base/tools/String.h"
-#include "crypto/common/Algorithm.h"
 
 
 namespace xmrig {
diff --git a/src/base/net/stratum/NetworkState.h b/src/base/net/stratum/NetworkState.h
index 479b184cd..fef3ad446 100644
--- a/src/base/net/stratum/NetworkState.h
+++ b/src/base/net/stratum/NetworkState.h
@@ -26,9 +26,9 @@
 #define XMRIG_NETWORKSTATE_H
 
 
+#include "base/crypto/Algorithm.h"
 #include "base/net/stratum/strategies/StrategyProxy.h"
 #include "base/tools/String.h"
-#include "crypto/common/Algorithm.h"
 
 
 #include <array>
diff --git a/src/base/net/stratum/Pool.h b/src/base/net/stratum/Pool.h
index 352387717..02855200c 100644
--- a/src/base/net/stratum/Pool.h
+++ b/src/base/net/stratum/Pool.h
@@ -31,8 +31,8 @@
 #include <vector>
 
 
+#include "base/crypto/Coin.h"
 #include "base/net/stratum/ProxyUrl.h"
-#include "crypto/common/Coin.h"
 #include "rapidjson/fwd.h"
 
 
diff --git a/src/base/net/stratum/Socks5.cpp b/src/base/net/stratum/Socks5.cpp
index f27ee0d04..9577906fe 100644
--- a/src/base/net/stratum/Socks5.cpp
+++ b/src/base/net/stratum/Socks5.cpp
@@ -78,7 +78,7 @@ void xmrig::Client::Socks5::connect()
 
     const auto &host = m_client->pool().host();
     std::vector<uint8_t> buf;
-    sockaddr_storage addr;
+    sockaddr_storage addr{};
 
     if (isIPv4(host, &addr)) {
         buf.resize(10);
diff --git a/src/base/net/stratum/Tls.cpp b/src/base/net/stratum/Tls.cpp
index 8916579b4..5915fad9d 100644
--- a/src/base/net/stratum/Tls.cpp
+++ b/src/base/net/stratum/Tls.cpp
@@ -6,8 +6,8 @@
  * 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>
+ * Copyright 2018-2020 SChernykh   <https://github.com/SChernykh>
+ * Copyright 2016-2020 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
@@ -24,12 +24,9 @@
  */
 
 
-#include <assert.h>
-
-
+#include "base/net/stratum/Tls.h"
 #include "base/io/log/Log.h"
 #include "base/net/stratum/Client.h"
-#include "base/net/stratum/Tls.h"
 #include "base/tools/Buffer.h"
 
 
@@ -38,12 +35,12 @@
 #endif
 
 
+#include <cassert>
+#include <openssl/ssl.h>
+
+
 xmrig::Client::Tls::Tls(Client *client) :
-    m_ready(false),
-    m_buf(),
-    m_fingerprint(),
-    m_client(client),
-    m_ssl(nullptr)
+    m_client(client)
 {
     m_ctx = SSL_CTX_new(SSLv23_method());
     assert(m_ctx != nullptr);
@@ -52,8 +49,8 @@ xmrig::Client::Tls::Tls(Client *client) :
         return;
     }
 
-    m_writeBio = BIO_new(BIO_s_mem());
-    m_readBio  = BIO_new(BIO_s_mem());
+    m_write = BIO_new(BIO_s_mem());
+    m_read  = BIO_new(BIO_s_mem());
     SSL_CTX_set_options(m_ctx, SSL_OP_NO_SSLv2 | SSL_OP_NO_SSLv3);
 }
 
@@ -80,7 +77,7 @@ bool xmrig::Client::Tls::handshake()
     }
 
     SSL_set_connect_state(m_ssl);
-    SSL_set_bio(m_ssl, m_readBio, m_writeBio);
+    SSL_set_bio(m_ssl, m_read, m_write);
     SSL_do_handshake(m_ssl);
 
     return send();
@@ -109,7 +106,7 @@ const char *xmrig::Client::Tls::version() const
 
 void xmrig::Client::Tls::read(const char *data, size_t size)
 {
-    BIO_write(m_readBio, data, size);
+    BIO_write(m_read, data, size);
 
     if (!SSL_is_init_finished(m_ssl)) {
         const int rc = SSL_connect(m_ssl);
@@ -133,17 +130,18 @@ void xmrig::Client::Tls::read(const char *data, size_t size)
       return;
     }
 
+    static char buf[16384]{};
     int bytes_read = 0;
-    while ((bytes_read = SSL_read(m_ssl, m_buf, sizeof(m_buf))) > 0) {
-        m_buf[bytes_read - 1] = '\0';
-        m_client->parse(m_buf, static_cast<size_t>(bytes_read));
+
+    while ((bytes_read = SSL_read(m_ssl, buf, sizeof(buf))) > 0) {
+        m_client->m_reader.parse(buf, static_cast<size_t>(bytes_read));
     }
 }
 
 
 bool xmrig::Client::Tls::send()
 {
-    return m_client->send(m_writeBio);
+    return m_client->send(m_write);
 }
 
 
diff --git a/src/base/net/stratum/Tls.h b/src/base/net/stratum/Tls.h
index e070be526..38cf2f9e6 100644
--- a/src/base/net/stratum/Tls.h
+++ b/src/base/net/stratum/Tls.h
@@ -5,8 +5,8 @@
  * 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>
+ * Copyright 2018-2020 SChernykh   <https://github.com/SChernykh>
+ * Copyright 2016-2020 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
@@ -26,10 +26,14 @@
 #define XMRIG_CLIENT_TLS_H
 
 
-#include <openssl/ssl.h>
+using BIO       = struct bio_st;
+using SSL       = struct ssl_st;
+using SSL_CTX   = struct ssl_ctx_st;
+using X509      = struct x509_st;
 
 
 #include "base/net/stratum/Client.h"
+#include "base/tools/Object.h"
 
 
 namespace xmrig {
@@ -38,6 +42,8 @@ namespace xmrig {
 class Client::Tls
 {
 public:
+    XMRIG_DISABLE_COPY_MOVE_DEFAULT(Tls)
+
     Tls(Client *client);
     ~Tls();
 
@@ -52,13 +58,12 @@ private:
     bool verify(X509 *cert);
     bool verifyFingerprint(X509 *cert);
 
-    BIO *m_readBio;
-    BIO *m_writeBio;
-    bool m_ready;
-    char m_buf[1024 * 2];
-    char m_fingerprint[32 * 2 + 8];
+    BIO *m_read     = nullptr;
+    BIO *m_write    = nullptr;
+    bool m_ready    = false;
+    char m_fingerprint[32 * 2 + 8]{};
     Client *m_client;
-    SSL *m_ssl;
+    SSL *m_ssl      = nullptr;
     SSL_CTX *m_ctx;
 };
 
diff --git a/src/base/net/tls/ServerTls.cpp b/src/base/net/tls/ServerTls.cpp
new file mode 100644
index 000000000..e76d58622
--- /dev/null
+++ b/src/base/net/tls/ServerTls.cpp
@@ -0,0 +1,103 @@
+/* XMRig
+ * Copyright 2018-2020 SChernykh   <https://github.com/SChernykh>
+ * Copyright 2016-2020 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 "base/net/tls/ServerTls.h"
+
+
+#include <cassert>
+#include <cstring>
+#include <openssl/ssl.h>
+
+
+xmrig::ServerTls::ServerTls(SSL_CTX *ctx) :
+    m_ctx(ctx)
+{
+}
+
+
+xmrig::ServerTls::~ServerTls()
+{
+    if (m_ssl) {
+        SSL_free(m_ssl);
+    }
+}
+
+
+bool xmrig::ServerTls::isTLS(const char *data, size_t size)
+{
+    static const uint8_t test[3] = { 0x16, 0x03, 0x01 };
+
+    return size >= sizeof(test) && memcmp(data, test, sizeof(test)) == 0;
+}
+
+
+bool xmrig::ServerTls::send(const char *data, size_t size)
+{
+    SSL_write(m_ssl, data, size);
+
+    return write(m_write);
+}
+
+
+void xmrig::ServerTls::read(const char *data, size_t size)
+{
+    if (!m_ssl) {
+        m_ssl = SSL_new(m_ctx);
+
+        m_write = BIO_new(BIO_s_mem());
+        m_read  = BIO_new(BIO_s_mem());
+
+        SSL_set_accept_state(m_ssl);
+        SSL_set_bio(m_ssl, m_read, m_write);
+    }
+
+
+    BIO_write(m_read, data, size);
+
+    if (!SSL_is_init_finished(m_ssl)) {
+        const int rc = SSL_do_handshake(m_ssl);
+
+        if (rc < 0 && SSL_get_error(m_ssl, rc) == SSL_ERROR_WANT_READ) {
+            write(m_write);
+        } else if (rc == 1) {
+            write(m_write);
+
+            m_ready = true;
+            read();
+        }
+        else {
+            shutdown();
+        }
+
+      return;
+    }
+
+    read();
+}
+
+
+void xmrig::ServerTls::read()
+{
+    static char buf[16384]{};
+
+    int bytes_read = 0;
+    while ((bytes_read = SSL_read(m_ssl, buf, sizeof(buf))) > 0) {
+        parse(buf, bytes_read);
+    }
+}
diff --git a/src/base/net/tls/ServerTls.h b/src/base/net/tls/ServerTls.h
new file mode 100644
index 000000000..892bed2b3
--- /dev/null
+++ b/src/base/net/tls/ServerTls.h
@@ -0,0 +1,68 @@
+/* XMRig
+ * Copyright 2018-2020 SChernykh   <https://github.com/SChernykh>
+ * Copyright 2016-2020 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_SERVERTLS_H
+#define XMRIG_SERVERTLS_H
+
+
+using BIO       = struct bio_st;
+using SSL       = struct ssl_st;
+using SSL_CTX   = struct ssl_ctx_st;
+
+
+
+#include "base/tools/Object.h"
+
+
+namespace xmrig {
+
+
+class ServerTls
+{
+public:
+    XMRIG_DISABLE_COPY_MOVE_DEFAULT(ServerTls)
+
+    ServerTls(SSL_CTX *ctx);
+    virtual ~ServerTls();
+
+    static bool isTLS(const char *data, size_t size);
+
+    bool send(const char *data, size_t size);
+    void read(const char *data, size_t size);
+
+protected:
+    virtual bool write(BIO *bio)                = 0;
+    virtual void parse(char *data, size_t size) = 0;
+    virtual void shutdown()                     = 0;
+
+private:
+    void read();
+
+    BIO *m_read     = nullptr;
+    BIO *m_write    = nullptr;
+    bool m_ready    = false;
+    SSL *m_ssl      = nullptr;
+    SSL_CTX *m_ctx;
+};
+
+
+} // namespace xmrig
+
+
+#endif /* XMRIG_SERVERTLS_H */
diff --git a/src/base/net/tls/TlsConfig.cpp b/src/base/net/tls/TlsConfig.cpp
new file mode 100644
index 000000000..49b1970d0
--- /dev/null
+++ b/src/base/net/tls/TlsConfig.cpp
@@ -0,0 +1,200 @@
+/* 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-2020 SChernykh   <https://github.com/SChernykh>
+ * Copyright 2016-2020 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 "base/net/tls/TlsConfig.h"
+#include "base/io/json/Json.h"
+#include "base/io/log/Log.h"
+#include "base/net/tls/TlsGen.h"
+#include "rapidjson/document.h"
+
+
+namespace xmrig {
+
+
+const char *TlsConfig::kCert            = "cert";
+const char *TlsConfig::kEnabled         = "enabled";
+const char *TlsConfig::kCertKey         = "cert_key";
+const char *TlsConfig::kCiphers         = "ciphers";
+const char *TlsConfig::kCipherSuites    = "ciphersuites";
+const char *TlsConfig::kDhparam         = "dhparam";
+const char *TlsConfig::kGen             = "gen";
+const char *TlsConfig::kProtocols       = "protocols";
+
+static const char *kTLSv1               = "TLSv1";
+static const char *kTLSv1_1             = "TLSv1.1";
+static const char *kTLSv1_2             = "TLSv1.2";
+static const char *kTLSv1_3             = "TLSv1.3";
+
+
+} // namespace xmrig
+
+
+/**
+ * "cert"         load TLS certificate chain from file.
+ * "cert_key"     load TLS private key from file.
+ * "ciphers"      set list of available ciphers (TLSv1.2 and below).
+ * "ciphersuites" set list of available TLSv1.3 ciphersuites.
+ * "dhparam"      load DH parameters for DHE ciphers from file.
+ */
+xmrig::TlsConfig::TlsConfig(const rapidjson::Value &value)
+{
+    if (value.IsObject()) {
+        m_enabled = Json::getBool(value, kEnabled, m_enabled);
+
+        setProtocols(Json::getString(value, kProtocols));
+        setCert(Json::getString(value, kCert));
+        setKey(Json::getString(value, kCertKey));
+        setCiphers(Json::getString(value, kCiphers));
+        setCipherSuites(Json::getString(value, kCipherSuites));
+        setDH(Json::getString(value, kDhparam));
+
+        if (m_key.isNull()) {
+            setKey(Json::getString(value, "cert-key"));
+        }
+
+        if (m_enabled && !isValid()) {
+            generate(Json::getString(value, kGen));
+        }
+    }
+    else if (value.IsBool()) {
+        m_enabled = value.GetBool();
+
+        if (m_enabled) {
+            generate();
+        }
+    }
+#   ifdef XMRIG_PROXY_PROJECT
+    else if (value.IsNull()) {
+        generate();
+    }
+#   endif
+    else if (value.IsString()) {
+        generate(value.GetString());
+    }
+    else {
+        m_enabled = false;
+    }
+}
+
+
+bool xmrig::TlsConfig::generate(const char *commonName)
+{
+    TlsGen gen;
+
+    try {
+        gen.generate(commonName);
+    }
+    catch (std::exception &ex) {
+        LOG_ERR("%s", ex.what());
+
+        return false;
+    }
+
+    setCert(gen.cert());
+    setKey(gen.certKey());
+
+    m_enabled = true;
+
+    return true;
+}
+
+
+rapidjson::Value xmrig::TlsConfig::toJSON(rapidjson::Document &doc) const
+{
+    using namespace rapidjson;
+
+    auto &allocator = doc.GetAllocator();
+    Value obj(kObjectType);
+    obj.AddMember(StringRef(kEnabled), m_enabled, allocator);
+
+    if (m_protocols > 0) {
+        std::vector<String> protocols;
+
+        if (m_protocols & TLSv1) {
+            protocols.emplace_back(kTLSv1);
+        }
+
+        if (m_protocols & TLSv1_1) {
+            protocols.emplace_back(kTLSv1_1);
+        }
+
+        if (m_protocols & TLSv1_2) {
+            protocols.emplace_back(kTLSv1_2);
+        }
+
+        if (m_protocols & TLSv1_3) {
+            protocols.emplace_back(kTLSv1_3);
+        }
+
+        obj.AddMember(StringRef(kProtocols), String::join(protocols, ' ').toJSON(doc), allocator);
+    }
+    else {
+        obj.AddMember(StringRef(kProtocols), kNullType, allocator);
+    }
+
+    obj.AddMember(StringRef(kCert),         m_cert.toJSON(), allocator);
+    obj.AddMember(StringRef(kCertKey),      m_key.toJSON(), allocator);
+    obj.AddMember(StringRef(kCiphers),      m_ciphers.toJSON(), allocator);
+    obj.AddMember(StringRef(kCipherSuites), m_cipherSuites.toJSON(), allocator);
+    obj.AddMember(StringRef(kDhparam),      m_dhparam.toJSON(), allocator);
+
+    return obj;
+}
+
+
+void xmrig::TlsConfig::setProtocols(const char *protocols)
+{
+    const std::vector<String> vec = String(protocols).split(' ');
+
+    for (const String &value : vec) {
+        if (value == kTLSv1) {
+            m_protocols |= TLSv1;
+        }
+        else if (value == kTLSv1_1) {
+            m_protocols |= TLSv1_1;
+        }
+        else if (value == kTLSv1_2) {
+            m_protocols |= TLSv1_2;
+        }
+        else if (value == kTLSv1_3) {
+            m_protocols |= TLSv1_3;
+        }
+    }
+}
+
+
+void xmrig::TlsConfig::setProtocols(const rapidjson::Value &protocols)
+{
+    m_protocols = 0;
+
+    if (protocols.IsUint()) {
+        return setProtocols(protocols.GetUint());
+    }
+
+    if (protocols.IsString()) {
+        return setProtocols(protocols.GetString());
+    }
+}
diff --git a/src/base/net/tls/TlsConfig.h b/src/base/net/tls/TlsConfig.h
new file mode 100644
index 000000000..4e0fe7879
--- /dev/null
+++ b/src/base/net/tls/TlsConfig.h
@@ -0,0 +1,92 @@
+/* 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-2020 SChernykh   <https://github.com/SChernykh>
+ * Copyright 2016-2020 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_TLSCONFIG_H
+#define XMRIG_TLSCONFIG_H
+
+
+#include "base/tools/String.h"
+#include "rapidjson/fwd.h"
+
+
+namespace xmrig {
+
+
+class TlsConfig
+{
+public:
+    static const char *kCert;
+    static const char *kCertKey;
+    static const char *kCiphers;
+    static const char *kCipherSuites;
+    static const char *kDhparam;
+    static const char *kEnabled;
+    static const char *kGen;
+    static const char *kProtocols;
+
+    enum Versions {
+        TLSv1   = 1,
+        TLSv1_1 = 2,
+        TLSv1_2 = 4,
+        TLSv1_3 = 8
+    };
+
+    TlsConfig() = default;
+    TlsConfig(const rapidjson::Value &object);
+
+    inline bool isEnabled() const                    { return m_enabled && isValid(); }
+    inline bool isValid() const                      { return !m_cert.isEmpty() && !m_key.isEmpty(); }
+    inline const char *cert() const                  { return m_cert.data(); }
+    inline const char *ciphers() const               { return m_ciphers.isEmpty() ? nullptr : m_ciphers.data(); }
+    inline const char *cipherSuites() const          { return m_cipherSuites.isEmpty() ? nullptr : m_cipherSuites.data(); }
+    inline const char *dhparam() const               { return m_dhparam.isEmpty() ? nullptr : m_dhparam.data(); }
+    inline const char *key() const                   { return m_key.data(); }
+    inline uint32_t protocols() const                { return m_protocols; }
+    inline void setCert(const char *cert)            { m_cert = cert; }
+    inline void setCiphers(const char *ciphers)      { m_ciphers = ciphers; }
+    inline void setCipherSuites(const char *ciphers) { m_cipherSuites = ciphers; }
+    inline void setDH(const char *dhparam)           { m_dhparam = dhparam; }
+    inline void setKey(const char *key)              { m_key = key; }
+    inline void setProtocols(uint32_t protocols)     { m_protocols = protocols; }
+
+    bool generate(const char *commonName = nullptr);
+    rapidjson::Value toJSON(rapidjson::Document &doc) const;
+    void setProtocols(const char *protocols);
+    void setProtocols(const rapidjson::Value &protocols);
+
+private:
+    bool m_enabled       = true;
+    uint32_t m_protocols = 0;
+    String m_cert;
+    String m_ciphers;
+    String m_cipherSuites;
+    String m_dhparam;
+    String m_key;
+};
+
+
+} /* namespace xmrig */
+
+#endif /* XMRIG_TLSCONFIG_H */
diff --git a/src/base/net/tls/TlsContext.cpp b/src/base/net/tls/TlsContext.cpp
new file mode 100644
index 000000000..d29c744b4
--- /dev/null
+++ b/src/base/net/tls/TlsContext.cpp
@@ -0,0 +1,270 @@
+/* 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-2020 SChernykh   <https://github.com/SChernykh>
+ * Copyright 2016-2020 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 "base/net/tls/TlsContext.h"
+#include "base/io/log/Log.h"
+#include "base/kernel/Env.h"
+#include "base/net/tls/TlsConfig.h"
+
+
+#include <openssl/ssl.h>
+#include <openssl/err.h>
+
+
+// https://wiki.openssl.org/index.php/OpenSSL_1.1.0_Changes#Compatibility_Layer
+#if OPENSSL_VERSION_NUMBER < 0x10100000L
+int DH_set0_pqg(DH *dh, BIGNUM *p, BIGNUM *q, BIGNUM *g)
+{
+    assert(q == nullptr);
+
+    dh->p = p;
+    dh->g = g;
+
+    return 1;
+ }
+#endif
+
+
+namespace xmrig {
+
+
+// https://wiki.openssl.org/index.php/Diffie-Hellman_parameters
+static DH *get_dh2048()
+{
+    static unsigned char dhp_2048[] = {
+        0xB2, 0x91, 0xA7, 0x05, 0x31, 0xCE, 0x12, 0x9D, 0x03, 0x43,
+        0xAF, 0x13, 0xAF, 0x4B, 0x8E, 0x4C, 0x04, 0x13, 0x4F, 0x72,
+        0x00, 0x73, 0x2C, 0x67, 0xC3, 0xE0, 0x50, 0xBF, 0x72, 0x5E,
+        0xBE, 0x45, 0x89, 0x4C, 0x01, 0x45, 0xA6, 0x5E, 0xA7, 0xA8,
+        0xDC, 0x2F, 0x1D, 0x91, 0x2D, 0x58, 0x0D, 0x71, 0x97, 0x3D,
+        0xAE, 0xFE, 0x86, 0x29, 0x37, 0x5F, 0x5E, 0x6D, 0x81, 0x56,
+        0x07, 0x83, 0xF2, 0xF8, 0xEC, 0x4E, 0xF8, 0x7A, 0xEC, 0xEA,
+        0xD9, 0xEA, 0x61, 0x3C, 0xAF, 0x51, 0x30, 0xB7, 0xA7, 0x67,
+        0x3F, 0x59, 0xAD, 0x2E, 0x23, 0x57, 0x64, 0xA2, 0x99, 0x15,
+        0xBD, 0xD9, 0x8D, 0xBA, 0xE6, 0x8F, 0xFB, 0xB3, 0x77, 0x3B,
+        0xE6, 0x5C, 0xC1, 0x03, 0xCF, 0x38, 0xD4, 0xF6, 0x2E, 0x0B,
+        0xF3, 0x20, 0xBE, 0xF0, 0xFC, 0x85, 0xEF, 0x5F, 0xCE, 0x0E,
+        0x42, 0x17, 0x3B, 0x72, 0x43, 0x4C, 0x3A, 0xF5, 0xC8, 0xB4,
+        0x40, 0x52, 0x03, 0x72, 0x9A, 0x2C, 0xA4, 0x23, 0x2A, 0xA2,
+        0x52, 0xA3, 0xC2, 0x76, 0x08, 0x1C, 0x2E, 0x60, 0x44, 0xE4,
+        0x12, 0x5D, 0x80, 0x47, 0x6C, 0x7A, 0x5A, 0x8E, 0x18, 0xC9,
+        0x8C, 0x22, 0xC8, 0x07, 0x75, 0xE2, 0x77, 0x3A, 0x90, 0x2E,
+        0x79, 0xC3, 0xF5, 0x4E, 0x4E, 0xDE, 0x14, 0x29, 0xA4, 0x5B,
+        0x32, 0xCC, 0xE5, 0x05, 0x09, 0x2A, 0xC9, 0x1C, 0xB4, 0x8E,
+        0x99, 0xCF, 0x57, 0xF2, 0x1B, 0x5F, 0x18, 0x89, 0x29, 0xF2,
+        0xB0, 0xF3, 0xAC, 0x67, 0x16, 0x90, 0x4A, 0x1D, 0xD6, 0xF5,
+        0x84, 0x71, 0x1D, 0x0E, 0x61, 0x5F, 0xE2, 0x2D, 0x52, 0x87,
+        0x0D, 0x8F, 0x84, 0xCB, 0xFC, 0xF0, 0x5D, 0x4C, 0x9F, 0x59,
+        0xA9, 0xD6, 0x83, 0x70, 0x4B, 0x98, 0x6A, 0xCA, 0x78, 0x53,
+        0x27, 0x32, 0x59, 0x35, 0x0A, 0xB8, 0x29, 0x18, 0xAF, 0x58,
+        0x45, 0x63, 0xEB, 0x43, 0x28, 0x7B
+    };
+
+    static unsigned char dhg_2048[] = { 0x02 };
+
+    auto dh = DH_new();
+    if (dh == nullptr) {
+        return nullptr;
+    }
+
+    auto p = BN_bin2bn(dhp_2048, sizeof(dhp_2048), nullptr);
+    auto g = BN_bin2bn(dhg_2048, sizeof(dhg_2048), nullptr);
+
+    if (p == nullptr || g == nullptr || !DH_set0_pqg(dh, p, nullptr, g)) {
+        DH_free(dh);
+        BN_free(p);
+        BN_free(g);
+
+        return nullptr;
+    }
+
+    return dh;
+}
+
+} // namespace xmrig
+
+
+xmrig::TlsContext::~TlsContext()
+{
+    SSL_CTX_free(m_ctx);
+}
+
+
+xmrig::TlsContext *xmrig::TlsContext::create(const TlsConfig &config)
+{
+    if (!config.isEnabled()) {
+        return nullptr;
+    }
+
+    auto tls = new TlsContext();
+    if (!tls->load(config)) {
+        delete tls;
+
+        return nullptr;
+    }
+
+    return tls;
+}
+
+
+bool xmrig::TlsContext::load(const TlsConfig &config)
+{
+    m_ctx = SSL_CTX_new(SSLv23_server_method());
+    if (m_ctx == nullptr) {
+        LOG_ERR("Unable to create SSL context");
+
+        return false;
+    }
+
+    const auto cert = Env::expand(config.cert());
+    if (SSL_CTX_use_certificate_chain_file(m_ctx, cert) <= 0) {
+        LOG_ERR("SSL_CTX_use_certificate_chain_file(\"%s\") failed.", config.cert());
+
+        return false;
+    }
+
+    const auto key = Env::expand(config.key());
+    if (SSL_CTX_use_PrivateKey_file(m_ctx, key, SSL_FILETYPE_PEM) <= 0) {
+        LOG_ERR("SSL_CTX_use_PrivateKey_file(\"%s\") failed.", config.key());
+
+        return false;
+    }
+
+    SSL_CTX_set_options(m_ctx, SSL_OP_NO_SSLv2 | SSL_OP_NO_SSLv3);
+    SSL_CTX_set_options(m_ctx, SSL_OP_CIPHER_SERVER_PREFERENCE);
+
+#   if OPENSSL_VERSION_NUMBER >= 0x1010100fL
+    SSL_CTX_set_max_early_data(m_ctx, 0);
+#   endif
+
+    setProtocols(config.protocols());
+
+    return setCiphers(config.ciphers()) && setCipherSuites(config.cipherSuites()) && setDH(config.dhparam());
+}
+
+
+bool xmrig::TlsContext::setCiphers(const char *ciphers)
+{
+    if (ciphers == nullptr || SSL_CTX_set_cipher_list(m_ctx, ciphers) == 1) {
+        return true;
+    }
+
+    LOG_ERR("SSL_CTX_set_cipher_list(\"%s\") failed.", ciphers);
+
+    return true;
+}
+
+
+bool xmrig::TlsContext::setCipherSuites(const char *ciphersuites)
+{
+    if (ciphersuites == nullptr) {
+        return true;
+    }
+
+#   if OPENSSL_VERSION_NUMBER >= 0x1010100fL
+    if (SSL_CTX_set_ciphersuites(m_ctx, ciphersuites) == 1) {
+        return true;
+    }
+#   endif
+
+    LOG_ERR("SSL_CTX_set_ciphersuites(\"%s\") failed.", ciphersuites);
+
+    return false;
+}
+
+
+bool xmrig::TlsContext::setDH(const char *dhparam)
+{
+    DH *dh = nullptr;
+
+    if (dhparam != nullptr) {
+        BIO *bio = BIO_new_file(Env::expand(dhparam), "r");
+        if (bio == nullptr) {
+            LOG_ERR("BIO_new_file(\"%s\") failed.", dhparam);
+
+            return false;
+        }
+
+        dh = PEM_read_bio_DHparams(bio, nullptr, nullptr, nullptr);
+        if (dh == nullptr) {
+            LOG_ERR("PEM_read_bio_DHparams(\"%s\") failed.", dhparam);
+
+            BIO_free(bio);
+
+            return false;
+        }
+
+        BIO_free(bio);
+    }
+    else {
+        dh = get_dh2048();
+    }
+
+    const int rc = SSL_CTX_set_tmp_dh(m_ctx, dh);
+
+    DH_free(dh);
+
+    if (rc == 0) {
+        LOG_ERR("SSL_CTX_set_tmp_dh(\"%s\") failed.", dhparam);
+
+        return false;
+    }
+
+    return true;
+}
+
+
+void xmrig::TlsContext::setProtocols(uint32_t protocols)
+{
+    if (protocols == 0) {
+        return;
+    }
+
+    if (!(protocols & TlsConfig::TLSv1)) {
+        SSL_CTX_set_options(m_ctx, SSL_OP_NO_TLSv1);
+    }
+
+#   ifdef SSL_OP_NO_TLSv1_1
+    SSL_CTX_clear_options(m_ctx, SSL_OP_NO_TLSv1_1);
+    if (!(protocols & TlsConfig::TLSv1_1)) {
+        SSL_CTX_set_options(m_ctx, SSL_OP_NO_TLSv1_1);
+    }
+#   endif
+
+#   ifdef SSL_OP_NO_TLSv1_2
+    SSL_CTX_clear_options(m_ctx, SSL_OP_NO_TLSv1_2);
+    if (!(protocols & TlsConfig::TLSv1_2)) {
+        SSL_CTX_set_options(m_ctx, SSL_OP_NO_TLSv1_2);
+    }
+#   endif
+
+#   ifdef SSL_OP_NO_TLSv1_3
+    SSL_CTX_clear_options(m_ctx, SSL_OP_NO_TLSv1_3);
+    if (!(protocols & TlsConfig::TLSv1_3)) {
+        SSL_CTX_set_options(m_ctx, SSL_OP_NO_TLSv1_3);
+    }
+#   endif
+}
diff --git a/src/base/net/tls/TlsContext.h b/src/base/net/tls/TlsContext.h
new file mode 100644
index 000000000..b87798c5b
--- /dev/null
+++ b/src/base/net/tls/TlsContext.h
@@ -0,0 +1,71 @@
+/* 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-2020 SChernykh   <https://github.com/SChernykh>
+ * Copyright 2016-2020 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_TLSCONTEXT_H
+#define XMRIG_TLSCONTEXT_H
+
+
+#include "base/tools/Object.h"
+
+
+#include <cstdint>
+
+
+using SSL_CTX = struct ssl_ctx_st;
+
+
+namespace xmrig {
+
+
+class TlsConfig;
+
+
+class TlsContext
+{
+public:
+    XMRIG_DISABLE_COPY_MOVE(TlsContext)
+
+    ~TlsContext();
+
+    static TlsContext *create(const TlsConfig &config);
+
+    inline SSL_CTX *ctx() const { return m_ctx; }
+
+private:
+    TlsContext() = default;
+
+    bool load(const TlsConfig &config);
+    bool setCiphers(const char *ciphers);
+    bool setCipherSuites(const char *ciphersuites);
+    bool setDH(const char *dhparam);
+    void setProtocols(uint32_t protocols);
+
+    SSL_CTX *m_ctx = nullptr;
+};
+
+
+} /* namespace xmrig */
+
+#endif /* XMRIG_TLSCONTEXT_H */
diff --git a/src/base/net/tls/TlsGen.cpp b/src/base/net/tls/TlsGen.cpp
new file mode 100644
index 000000000..c56ef2a21
--- /dev/null
+++ b/src/base/net/tls/TlsGen.cpp
@@ -0,0 +1,144 @@
+/* XMRig
+ * Copyright 2018-2020 SChernykh   <https://github.com/SChernykh>
+ * Copyright 2016-2020 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 "base/net/tls/TlsGen.h"
+
+
+#include <openssl/ssl.h>
+#include <openssl/err.h>
+#include <stdexcept>
+#include <fstream>
+
+
+namespace xmrig {
+
+
+static const char *kLocalhost = "localhost";
+
+
+static EVP_PKEY *generate_pkey()
+{
+    auto pkey = EVP_PKEY_new();
+    if (!pkey) {
+        return nullptr;
+    }
+
+    auto exponent = BN_new();
+    auto rsa      = RSA_new();
+    if (!exponent || !rsa || !BN_set_word(exponent, RSA_F4) || !RSA_generate_key_ex(rsa, 2048, exponent, nullptr) || !EVP_PKEY_assign_RSA(pkey, rsa)) {
+        EVP_PKEY_free(pkey);
+        BN_free(exponent);
+        RSA_free(rsa);
+
+        return nullptr;
+    }
+
+    BN_free(exponent);
+
+    return pkey;
+}
+
+
+bool isFileExist(const char *fileName)
+{
+    std::ifstream in(fileName);
+
+    return in.good();
+}
+
+
+} // namespace xmrig
+
+
+xmrig::TlsGen::~TlsGen()
+{
+    EVP_PKEY_free(m_pkey);
+    X509_free(m_x509);
+}
+
+
+void xmrig::TlsGen::generate(const char *commonName)
+{
+    if (isFileExist(m_cert) && isFileExist(m_certKey)) {
+        return;
+    }
+
+    m_pkey = generate_pkey();
+    if (!m_pkey) {
+        throw std::runtime_error("RSA key generation failed.");
+    }
+
+    if (!generate_x509(commonName == nullptr || strlen(commonName) == 0 ? kLocalhost : commonName)) {
+        throw std::runtime_error("x509 certificate generation failed.");
+    }
+
+    if (!write()) {
+        throw std::runtime_error("unable to write certificate to disk.");
+    }
+}
+
+
+bool xmrig::TlsGen::generate_x509(const char *commonName)
+{
+    m_x509 = X509_new();
+    if (!m_x509) {
+        return false;
+    }
+
+    if (!X509_set_pubkey(m_x509, m_pkey)) {
+        return false;
+    }
+
+    ASN1_INTEGER_set(X509_get_serialNumber(m_x509), 1);
+    X509_gmtime_adj(X509_get_notBefore(m_x509), 0);
+    X509_gmtime_adj(X509_get_notAfter(m_x509), 315360000L);
+
+    auto name = X509_get_subject_name(m_x509);
+    X509_NAME_add_entry_by_txt(name, "CN", MBSTRING_ASC, reinterpret_cast<const uint8_t *>(commonName), -1, -1, 0);
+
+    X509_set_issuer_name(m_x509, name);
+
+    return X509_sign(m_x509, m_pkey, EVP_sha256());
+}
+
+
+bool xmrig::TlsGen::write()
+{
+    auto pkey_file = fopen(m_certKey, "wb");
+    if (!pkey_file) {
+        return false;
+    }
+
+    bool ret = PEM_write_PrivateKey(pkey_file, m_pkey, nullptr, nullptr, 0, nullptr, nullptr);
+    fclose(pkey_file);
+
+    if (!ret) {
+        return false;
+    }
+
+    auto x509_file = fopen(m_cert, "wb");
+    if (!x509_file) {
+        return false;
+    }
+
+    ret = PEM_write_X509(x509_file, m_x509);
+    fclose(x509_file);
+
+    return ret;
+}
diff --git a/src/base/net/tls/TlsGen.h b/src/base/net/tls/TlsGen.h
new file mode 100644
index 000000000..9386e88ca
--- /dev/null
+++ b/src/base/net/tls/TlsGen.h
@@ -0,0 +1,61 @@
+/* XMRig
+ * Copyright 2018-2020 SChernykh   <https://github.com/SChernykh>
+ * Copyright 2016-2020 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_TLSGEN_H
+#define XMRIG_TLSGEN_H
+
+
+#include "base/tools/Object.h"
+#include "base/tools/String.h"
+
+
+using EVP_PKEY  = struct evp_pkey_st;
+using X509      = struct x509_st;
+
+
+namespace xmrig {
+
+
+class TlsGen
+{
+public:
+    XMRIG_DISABLE_COPY_MOVE(TlsGen)
+
+    TlsGen() : m_cert("cert.pem"), m_certKey("cert_key.pem") {}
+    ~TlsGen();
+
+    inline const String &cert() const       { return m_cert; }
+    inline const String &certKey() const    { return m_certKey; }
+
+    void generate(const char *commonName = nullptr);
+
+private:
+    bool generate_x509(const char *commonName);
+    bool write();
+
+    const String m_cert;
+    const String m_certKey;
+    EVP_PKEY *m_pkey    = nullptr;
+    X509 *m_x509        = nullptr;
+};
+
+
+} /* namespace xmrig */
+
+
+#endif /* XMRIG_TLSGEN_H */
diff --git a/src/base/net/tools/LineReader.cpp b/src/base/net/tools/LineReader.cpp
new file mode 100644
index 000000000..646852bf6
--- /dev/null
+++ b/src/base/net/tools/LineReader.cpp
@@ -0,0 +1,103 @@
+/* XMRig
+ * Copyright 2018-2020 SChernykh   <https://github.com/SChernykh>
+ * Copyright 2016-2020 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 "base/net/tools/LineReader.h"
+#include "base/net/tools/NetBuffer.h"
+#include "base/kernel/interfaces/ILineListener.h"
+
+#include <cassert>
+#include <cstring>
+
+
+xmrig::LineReader::~LineReader()
+{
+    NetBuffer::release(m_buf);
+}
+
+
+void xmrig::LineReader::parse(char *data, size_t size)
+{
+    assert(m_listener != nullptr && size > 0);
+    if (!m_listener || size == 0) {
+        return;
+    }
+
+    if (!m_buf) {
+        return getline(data, size);
+    }
+
+    add(data, size);
+    getline(m_buf, m_pos);
+}
+
+
+void xmrig::LineReader::reset()
+{
+    if (m_buf) {
+        NetBuffer::release(m_buf);
+        m_buf = nullptr;
+        m_pos = 0;
+    }
+}
+
+
+void xmrig::LineReader::add(const char *data, size_t size)
+{
+    if (size > NetBuffer::kChunkSize - m_pos) {
+        return;
+    }
+
+    if (!m_buf) {
+        m_buf = NetBuffer::allocate();
+        m_pos = 0;
+    }
+
+    memcpy(m_buf + m_pos, data, size);
+    m_pos += size;
+}
+
+
+void xmrig::LineReader::getline(char *data, size_t size)
+{
+    char *end        = nullptr;
+    char *start      = data;
+    size_t remaining = size;
+
+    while ((end = static_cast<char*>(memchr(start, '\n', remaining))) != nullptr) {
+        *end = '\0';
+
+        end++;
+
+        const auto len = static_cast<size_t>(end - start);
+        if (len > 1) {
+            m_listener->onLine(start, len - 1);
+        }
+
+        remaining -= len;
+        start = end;
+    }
+
+    if (remaining == 0) {
+        return reset();
+    }
+
+    if (!m_buf || m_buf != data) {
+        add(start, remaining);
+    }
+}
diff --git a/src/base/net/tools/LineReader.h b/src/base/net/tools/LineReader.h
new file mode 100644
index 000000000..601f5cdbc
--- /dev/null
+++ b/src/base/net/tools/LineReader.h
@@ -0,0 +1,62 @@
+/* XMRig
+ * Copyright 2018-2020 SChernykh   <https://github.com/SChernykh>
+ * Copyright 2016-2020 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_LINEREADER_H
+#define XMRIG_LINEREADER_H
+
+
+#include "base/tools/Object.h"
+
+
+#include <cstddef>
+
+
+namespace xmrig {
+
+
+class ILineListener;
+
+
+class LineReader
+{
+public:
+    XMRIG_DISABLE_COPY_MOVE(LineReader)
+
+    LineReader() = default;
+    LineReader(ILineListener *listener) : m_listener(listener) {}
+    ~LineReader();
+
+    inline void setListener(ILineListener *listener) { m_listener = listener; }
+
+    void parse(char *data, size_t size);
+    void reset();
+
+private:
+    void add(const char *data, size_t size);
+    void getline(char *data, size_t size);
+
+    char *m_buf                 = nullptr;
+    ILineListener *m_listener   = nullptr;
+    size_t m_pos                = 0;
+};
+
+
+} /* namespace xmrig */
+
+
+#endif /* XMRIG_NETBUFFER_H */
diff --git a/src/base/net/tools/MemPool.h b/src/base/net/tools/MemPool.h
new file mode 100644
index 000000000..3b8a8ef41
--- /dev/null
+++ b/src/base/net/tools/MemPool.h
@@ -0,0 +1,96 @@
+/* XMRig
+ * Copyright 2018-2020 SChernykh   <https://github.com/SChernykh>
+ * Copyright 2016-2020 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_MEMPOOL_H
+#define XMRIG_MEMPOOL_H
+
+
+#include <map>
+#include <set>
+#include <array>
+#include <cassert>
+
+
+namespace xmrig {
+
+
+template<size_t CHUNK_SIZE, size_t INIT_SIZE>
+class MemPool
+{
+public:
+    MemPool() = default;
+
+
+    constexpr size_t chunkSize() const  { return CHUNK_SIZE; }
+    inline size_t freeSize() const      { return m_free.size() * CHUNK_SIZE; }
+    inline size_t size() const          { return m_data.size() * CHUNK_SIZE * INIT_SIZE; }
+
+
+    inline char *allocate()
+    {
+        if (m_free.empty()) {
+            resize();
+        }
+
+        const size_t i = *m_free.begin();
+        const size_t r = i / INIT_SIZE;
+
+        char *ptr = m_data[r].data() + (i - r * INIT_SIZE) * CHUNK_SIZE;
+
+        m_used.insert({ ptr, i });
+        m_free.erase(i);
+
+        return ptr;
+    }
+
+
+    inline void deallocate(const char *ptr)
+    {
+        if (ptr == nullptr) {
+            return;
+        }
+
+        assert(m_used.count(ptr));
+
+        m_free.emplace(m_used[ptr]);
+        m_used.erase(ptr);
+    }
+
+
+private:
+    inline void resize()
+    {
+        const size_t index = m_data.size();
+        m_data[index];
+
+        for (size_t i = 0; i < INIT_SIZE; ++i) {
+            m_free.emplace((index * INIT_SIZE) + i);
+        }
+    }
+
+
+    std::map<const char *, size_t> m_used;
+    std::map<size_t, std::array<char, CHUNK_SIZE * INIT_SIZE> > m_data;
+    std::set<size_t> m_free;
+};
+
+
+} /* namespace xmrig */
+
+
+#endif /* XMRIG_MEMPOOL_H */
diff --git a/src/base/net/tools/NetBuffer.cpp b/src/base/net/tools/NetBuffer.cpp
new file mode 100644
index 000000000..3303d9715
--- /dev/null
+++ b/src/base/net/tools/NetBuffer.cpp
@@ -0,0 +1,83 @@
+/* XMRig
+ * Copyright 2018-2020 SChernykh   <https://github.com/SChernykh>
+ * Copyright 2016-2020 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 "base/net/tools/MemPool.h"
+#include "base/net/tools/NetBuffer.h"
+
+
+#include <cassert>
+#include <uv.h>
+
+
+namespace xmrig {
+
+
+static constexpr size_t kInitSize                       = 4;
+static MemPool<NetBuffer::kChunkSize, kInitSize> *pool  = nullptr;
+
+
+inline MemPool<NetBuffer::kChunkSize, kInitSize> *getPool()
+{
+    if (!pool) {
+        pool = new MemPool<NetBuffer::kChunkSize, kInitSize>();
+    }
+
+    return pool;
+}
+
+
+} // namespace xmrig
+
+
+char *xmrig::NetBuffer::allocate()
+{
+    return getPool()->allocate();
+}
+
+
+void xmrig::NetBuffer::destroy()
+{
+    if (!pool) {
+        return;
+    }
+
+    assert(pool->freeSize() == pool->size());
+
+    delete pool;
+    pool = nullptr;
+}
+
+
+void xmrig::NetBuffer::onAlloc(uv_handle_t *, size_t, uv_buf_t *buf)
+{
+    buf->base = getPool()->allocate();
+    buf->len  = kChunkSize;
+}
+
+
+void xmrig::NetBuffer::release(const char *buf)
+{
+    getPool()->deallocate(buf);
+}
+
+
+void xmrig::NetBuffer::release(const uv_buf_t *buf)
+{
+    getPool()->deallocate(buf->base);
+}
diff --git a/src/base/net/tools/NetBuffer.h b/src/base/net/tools/NetBuffer.h
new file mode 100644
index 000000000..14255bb0b
--- /dev/null
+++ b/src/base/net/tools/NetBuffer.h
@@ -0,0 +1,49 @@
+/* XMRig
+ * Copyright 2018-2020 SChernykh   <https://github.com/SChernykh>
+ * Copyright 2016-2020 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_NETBUFFER_H
+#define XMRIG_NETBUFFER_H
+
+
+struct uv_buf_t;
+using uv_handle_t = struct uv_handle_s;
+
+
+#include <cstddef>
+
+
+namespace xmrig {
+
+
+class NetBuffer
+{
+public:
+    static constexpr size_t kChunkSize = 16 * 1024;
+
+    static char *allocate();
+    static void destroy();
+    static void onAlloc(uv_handle_t *handle, size_t suggested_size, uv_buf_t *buf);
+    static void release(const char *buf);
+    static void release(const uv_buf_t *buf);
+};
+
+
+} /* namespace xmrig */
+
+
+#endif /* XMRIG_NETBUFFER_H */
diff --git a/src/base/net/tools/RecvBuf.h b/src/base/net/tools/RecvBuf.h
deleted file mode 100644
index 5122c9804..000000000
--- a/src/base/net/tools/RecvBuf.h
+++ /dev/null
@@ -1,99 +0,0 @@
-/* XMRig
- * Copyright 2010      Jeff Garzik <jgarzik@pobox.com>
- * Copyright 2012-2014 pooler      <pooler@litecoinpool.org>
- * Copyright 2014      Lucas Jones <https://github.com/lucasjones>
- * Copyright 2014-2016 Wolf9466    <https://github.com/OhGodAPet>
- * Copyright 2016      Jay D Dee   <jayddee246@gmail.com>
- * Copyright 2017-2018 XMR-Stak    <https://github.com/fireice-uk>, <https://github.com/psychocrypt>
- * Copyright 2018-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_RECVBUF_H
-#define XMRIG_RECVBUF_H
-
-
-#include <string.h>
-
-
-#include "base/kernel/interfaces/ILineListener.h"
-
-
-namespace xmrig {
-
-
-template<size_t N>
-class RecvBuf
-{
-public:
-    inline RecvBuf() :
-        m_buf(),
-        m_pos(0)
-    {
-    }
-
-    inline char *base()                { return m_buf; }
-    inline char *current()             { return m_buf + m_pos; }
-    inline const char *base() const    { return m_buf; }
-    inline const char *current() const { return m_buf + m_pos; }
-    inline size_t available() const    { return N - m_pos; }
-    inline size_t pos() const          { return m_pos; }
-    inline void nread(size_t size)     { m_pos += size; }
-    inline void reset()                { m_pos = 0; }
-
-    constexpr inline size_t size() const { return N; }
-
-    inline void getline(ILineListener *listener)
-    {
-        char *end;
-        char *start = m_buf;
-        size_t remaining = m_pos;
-
-        while ((end = static_cast<char*>(memchr(start, '\n', remaining))) != nullptr) {
-            *end = '\0';
-
-            end++;
-            const size_t len = static_cast<size_t>(end - start);
-
-            listener->onLine(start, len - 1);
-
-            remaining -= len;
-            start = end;
-        }
-
-        if (remaining == 0) {
-            m_pos = 0;
-            return;
-        }
-
-        if (start == m_buf) {
-            return;
-        }
-
-        memcpy(m_buf, start, remaining);
-        m_pos = remaining;
-    }
-
-private:
-    char m_buf[N];
-    size_t m_pos;
-};
-
-
-} /* namespace xmrig */
-
-
-#endif /* XMRIG_RECVBUF_H */
diff --git a/src/base/net/tools/TcpServer.cpp b/src/base/net/tools/TcpServer.cpp
index e5e6e4e18..06d4033a7 100644
--- a/src/base/net/tools/TcpServer.cpp
+++ b/src/base/net/tools/TcpServer.cpp
@@ -5,8 +5,8 @@
  * 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>
+ * Copyright 2018-2020 SChernykh   <https://github.com/SChernykh>
+ * Copyright 2016-2020 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
@@ -34,11 +34,11 @@ static const xmrig::String kLocalHost("127.0.0.1");
 
 xmrig::TcpServer::TcpServer(const String &host, uint16_t port, ITcpServerListener *listener) :
     m_host(host.isNull() ? kLocalHost : host),
-    m_version(0),
     m_listener(listener),
-    m_addr(),
     m_port(port)
 {
+    assert(m_listener != nullptr);
+
     m_tcp = new uv_tcp_t;
     uv_tcp_init(uv_default_loop(), m_tcp);
     m_tcp->data = this;
diff --git a/src/base/net/tools/TcpServer.h b/src/base/net/tools/TcpServer.h
index fc29fa2d0..de464d372 100644
--- a/src/base/net/tools/TcpServer.h
+++ b/src/base/net/tools/TcpServer.h
@@ -5,8 +5,8 @@
  * 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>
+ * Copyright 2018-2020 SChernykh   <https://github.com/SChernykh>
+ * Copyright 2016-2020 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
@@ -29,6 +29,9 @@
 #include <uv.h>
 
 
+#include "base/tools/Object.h"
+
+
 namespace xmrig {
 
 
@@ -39,6 +42,8 @@ class String;
 class TcpServer
 {
 public:
+    XMRIG_DISABLE_COPY_MOVE_DEFAULT(TcpServer)
+
     TcpServer(const String &host, uint16_t port, ITcpServerListener *listener);
     ~TcpServer();
 
@@ -50,9 +55,9 @@ private:
     static void onConnection(uv_stream_t *stream, int status);
 
     const String &m_host;
-    int m_version;
+    int m_version   = 0;
     ITcpServerListener *m_listener;
-    sockaddr_storage m_addr;
+    sockaddr_storage m_addr{};
     uint16_t m_port;
     uv_tcp_t *m_tcp;
 };
diff --git a/src/base/tools/Arguments.cpp b/src/base/tools/Arguments.cpp
index 933173aa3..d0352939b 100644
--- a/src/base/tools/Arguments.cpp
+++ b/src/base/tools/Arguments.cpp
@@ -5,8 +5,8 @@
  * 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>
+ * Copyright 2018-2020 SChernykh   <https://github.com/SChernykh>
+ * Copyright 2016-2020 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
@@ -52,6 +52,23 @@ bool xmrig::Arguments::hasArg(const char *name) const
 }
 
 
+const char *xmrig::Arguments::value(const char *key) const
+{
+    const size_t size = m_data.size();
+    if (size < 3) {
+        return nullptr;
+    }
+
+    for (size_t i = 1; i < size - 1; ++i) {
+        if (m_data[i] == key) {
+            return m_data[i + 1];
+        }
+    }
+
+    return nullptr;
+}
+
+
 void xmrig::Arguments::add(const char *arg)
 {
     if (arg == nullptr) {
diff --git a/src/base/tools/Arguments.h b/src/base/tools/Arguments.h
index e47e39e38..0016c519f 100644
--- a/src/base/tools/Arguments.h
+++ b/src/base/tools/Arguments.h
@@ -5,8 +5,8 @@
  * 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>
+ * Copyright 2018-2020 SChernykh   <https://github.com/SChernykh>
+ * Copyright 2016-2020 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
@@ -41,6 +41,7 @@ public:
     Arguments(int argc, char **argv);
 
     bool hasArg(const char *name) const;
+    const char *value(const char *key) const;
 
     inline char **argv() const                     { return m_argv; }
     inline const std::vector<String> &data() const { return m_data; }
diff --git a/src/config.json b/src/config.json
index 70096cf7c..9ef5736e4 100644
--- a/src/config.json
+++ b/src/config.json
@@ -77,6 +77,15 @@
     "retries": 5,
     "retry-pause": 5,
     "syslog": false,
+    "tls": {
+        "enabled": false,
+        "protocols": null,
+        "cert": null,
+        "cert_key": null,
+        "ciphers": null,
+        "ciphersuites": null,
+        "dhparam": null
+    },
     "user-agent": null,
     "verbose": 0,
     "watch": true
diff --git a/src/core/Miner.cpp b/src/core/Miner.cpp
index 55a448e2a..254428fbe 100644
--- a/src/core/Miner.cpp
+++ b/src/core/Miner.cpp
@@ -41,6 +41,7 @@
 #include "core/Miner.h"
 #include "crypto/common/Nonce.h"
 #include "crypto/rx/Rx.h"
+#include "crypto/astrobwt/AstroBWT.h"
 #include "rapidjson/document.h"
 #include "version.h"
 
@@ -242,6 +243,10 @@ public:
 #   endif
 
 
+#   ifdef XMRIG_ALGO_ASTROBWT
+    inline bool initAstroBWT() { return astrobwt::init(job); }
+#   endif
+
     Algorithm algorithm;
     Algorithms algorithms;
     bool active         = false;
@@ -454,10 +459,14 @@ void xmrig::Miner::setJob(const Job &job, bool donate)
         d_ptr->userJobId = job.id();
     }
 
+    bool ready = true;
+
 #   ifdef XMRIG_ALGO_RANDOMX
-    const bool ready = d_ptr->initRX();
-#   else
-    constexpr const bool ready = true;
+    ready &= d_ptr->initRX();
+#   endif
+
+#   ifdef XMRIG_ALGO_ASTROBWT
+    ready &= d_ptr->initAstroBWT();
 #   endif
 
     mutex.unlock();
diff --git a/src/core/Miner.h b/src/core/Miner.h
index 96ac6a167..b529d969c 100644
--- a/src/core/Miner.h
+++ b/src/core/Miner.h
@@ -31,10 +31,10 @@
 
 #include "backend/common/interfaces/IRxListener.h"
 #include "base/api/interfaces/IApiListener.h"
+#include "base/crypto/Algorithm.h"
 #include "base/kernel/interfaces/IBaseListener.h"
 #include "base/kernel/interfaces/ITimerListener.h"
 #include "base/tools/Object.h"
-#include "crypto/common/Algorithm.h"
 
 
 namespace xmrig {
diff --git a/src/core/config/Config.cpp b/src/core/config/Config.cpp
index d5adce4c9..fe3c8c33a 100644
--- a/src/core/config/Config.cpp
+++ b/src/core/config/Config.cpp
@@ -211,7 +211,7 @@ void xmrig::Config::getJSON(rapidjson::Document &doc) const
     auto &allocator = doc.GetAllocator();
 
     Value api(kObjectType);
-    api.AddMember(StringRef(kApiId),                m_apiId.toJSON(), allocator);
+    api.AddMember(StringRef(kApiId),                    m_apiId.toJSON(), allocator);
     api.AddMember(StringRef(kApiWorkerId),              m_apiWorkerId.toJSON(), allocator);
 
     doc.AddMember(StringRef(kApi),                      api, allocator);
@@ -245,6 +245,11 @@ void xmrig::Config::getJSON(rapidjson::Document &doc) const
     doc.AddMember(StringRef(Pools::kRetries),           m_pools.retries(), allocator);
     doc.AddMember(StringRef(Pools::kRetryPause),        m_pools.retryPause(), allocator);
     doc.AddMember(StringRef(kSyslog),                   isSyslog(), allocator);
+
+#   ifdef XMRIG_FEATURE_TLS
+    doc.AddMember(StringRef(kTls),                      m_tls.toJSON(doc), allocator);
+#   endif
+
     doc.AddMember(StringRef(kUserAgent),                m_userAgent.toJSON(), allocator);
     doc.AddMember(StringRef(kVerbose),                  Log::verbose(), allocator);
     doc.AddMember(StringRef(kWatch),                    m_watch, allocator);
diff --git a/src/core/config/ConfigTransform.cpp b/src/core/config/ConfigTransform.cpp
index ebbd7dbd7..eccbd2354 100644
--- a/src/core/config/ConfigTransform.cpp
+++ b/src/core/config/ConfigTransform.cpp
@@ -159,6 +159,9 @@ void xmrig::ConfigTransform::transform(rapidjson::Document &doc, int key, const
 #   ifdef XMRIG_ALGO_ASTROBWT
     case IConfig::AstroBWTMaxSizeKey: /* --astrobwt-max-size */
         return set(doc, kCpu, "astrobwt-max-size", static_cast<uint64_t>(strtol(arg, nullptr, 10)));
+
+    case IConfig::AstroBWTAVX2Key: /* --astrobwt-avx2 */
+        return set(doc, kCpu, "astrobwt-avx2", true);
 #   endif
 
 #   ifdef XMRIG_ALGO_RANDOMX
diff --git a/src/core/config/Config_platform.h b/src/core/config/Config_platform.h
index b6bed7f86..633973c3d 100644
--- a/src/core/config/Config_platform.h
+++ b/src/core/config/Config_platform.h
@@ -89,9 +89,17 @@ static const option options[] = {
     { "cpu-no-yield",          0, nullptr, IConfig::YieldKey              },
     { "verbose",               0, nullptr, IConfig::VerboseKey            },
     { "proxy",                 1, nullptr, IConfig::ProxyKey              },
+    { "data-dir",              1, nullptr, IConfig::DataDirKey            },
 #   ifdef XMRIG_FEATURE_TLS
     { "tls",                   0, nullptr, IConfig::TlsKey                },
     { "tls-fingerprint",       1, nullptr, IConfig::FingerprintKey        },
+    { "tls-cert",              1, nullptr, IConfig::TlsCertKey            },
+    { "tls-cert-key",          1, nullptr, IConfig::TlsCertKeyKey         },
+    { "tls-dhparam",           1, nullptr, IConfig::TlsDHparamKey         },
+    { "tls-protocols",         1, nullptr, IConfig::TlsProtocolsKey       },
+    { "tls-ciphers",           1, nullptr, IConfig::TlsCiphersKey         },
+    { "tls-ciphersuites",      1, nullptr, IConfig::TlsCipherSuitesKey    },
+    { "tls-gen",               1, nullptr, IConfig::TlsGenKey             },
 #   endif
 #   ifdef XMRIG_FEATURE_ASM
     { "asm",                   1, nullptr, IConfig::AssemblyKey           },
@@ -109,6 +117,7 @@ static const option options[] = {
 #   endif
     #ifdef XMRIG_ALGO_ASTROBWT
     { "astrobwt-max-size",     1, nullptr, IConfig::AstroBWTMaxSizeKey    },
+    { "astrobwt-avx2",         0, nullptr, IConfig::AstroBWTAVX2Key       },
     #endif
 #   ifdef XMRIG_FEATURE_OPENCL
     { "opencl",                0, nullptr, IConfig::OclKey                },
diff --git a/src/core/config/usage.h b/src/core/config/usage.h
index 0bc9db8c0..542ee4d3b 100644
--- a/src/core/config/usage.h
+++ b/src/core/config/usage.h
@@ -96,6 +96,7 @@ static inline const std::string &usage()
 
 #   ifdef XMRIG_ALGO_ASTROBWT
     u += "      --astrobwt-max-size=N     skip hashes with large stage 2 size, default: 550, min: 400, max: 1200\n";
+    u += "      --astrobwt-avx2           enable AVX2 optimizations for AstroBWT algorithm";
 #   endif
 
 #   ifdef XMRIG_FEATURE_HTTP
@@ -130,6 +131,17 @@ static inline const std::string &usage()
     u += "      --no-nvml                 disable NVML (NVIDIA Management Library) support\n";
 #   endif
 
+#   ifdef XMRIG_FEATURE_TLS
+    u += "\nTLS:\n";
+    u += "      --tls-gen=HOSTNAME        generate TLS certificate for specific hostname\n";
+    u += "      --tls-cert=FILE           load TLS certificate chain from a file in the PEM format\n";
+    u += "      --tls-cert-key=FILE       load TLS certificate private key from a file in the PEM format\n";
+    u += "      --tls-dhparam=FILE        load DH parameters for DHE ciphers from a file in the PEM format\n";
+    u += "      --tls-protocols=N         enable specified TLS protocols, example: \"TLSv1 TLSv1.1 TLSv1.2 TLSv1.3\"\n";
+    u += "      --tls-ciphers=S           set list of available ciphers (TLSv1.2 and below)\n";
+    u += "      --tls-ciphersuites=S      set list of available TLSv1.3 ciphersuites\n";
+#   endif
+
     u += "\nLogging:\n";
 
 #   ifdef HAVE_SYSLOG_H
diff --git a/src/crypto/argon2/Hash.h b/src/crypto/argon2/Hash.h
index b337f1934..194bcb584 100644
--- a/src/crypto/argon2/Hash.h
+++ b/src/crypto/argon2/Hash.h
@@ -5,8 +5,8 @@
  * 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>
+ * Copyright 2018-2020 SChernykh   <https://github.com/SChernykh>
+ * Copyright 2016-2020 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
@@ -27,8 +27,8 @@
 
 
 #include "3rdparty/argon2.h"
+#include "base/crypto/Algorithm.h"
 #include "crypto/cn/CryptoNight.h"
-#include "crypto/common/Algorithm.h"
 
 
 namespace xmrig { namespace argon2 {
diff --git a/src/crypto/astrobwt/AstroBWT.cpp b/src/crypto/astrobwt/AstroBWT.cpp
index ca325bff8..47949e4c6 100644
--- a/src/crypto/astrobwt/AstroBWT.cpp
+++ b/src/crypto/astrobwt/AstroBWT.cpp
@@ -30,6 +30,10 @@
 #include "AstroBWT.h"
 #include "sha3.h"
 #include "crypto/cn/CryptoNight.h"
+#include "base/net/stratum/Job.h"
+#include "base/crypto/Algorithm.h"
+#include "base/io/log/Log.h"
+#include "backend/cpu/Cpu.h"
 #include <limits>
 
 constexpr int STAGE1_SIZE = 147253;
@@ -38,6 +42,18 @@ constexpr int ALLOCATION_SIZE = (STAGE1_SIZE + 1048576) + (128 - (STAGE1_SIZE &
 constexpr int COUNTING_SORT_BITS = 10;
 constexpr int COUNTING_SORT_SIZE = 1 << COUNTING_SORT_BITS;
 
+static bool astrobwtInitialized = false;
+
+#ifdef ASTROBWT_AVX2
+static bool hasAVX2 = false;
+
+extern "C"
+#ifndef _MSC_VER
+__attribute__((ms_abi))
+#endif
+void SHA3_256_AVX2_ASM(const void* in, size_t inBytes, void* out);
+#endif
+
 #ifdef _MSC_VER
 
 #include <stdlib.h>
@@ -155,7 +171,25 @@ void sort_indices(int N, const uint8_t* v, uint64_t* indices, uint64_t* tmp_indi
 	}
 }
 
-bool xmrig::astrobwt::astrobwt_dero(const void* input_data, uint32_t input_size, void* scratchpad, uint8_t* output_hash, int stage2_max_size)
+bool xmrig::astrobwt::init(const xmrig::Job& job)
+{
+	if (job.algorithm().family() != xmrig::Algorithm::ASTROBWT)
+		return true;
+
+	if (astrobwtInitialized)
+		return true;
+
+#ifdef ASTROBWT_AVX2
+	if (xmrig::Cpu::info()->hasAVX2()) {
+		hasAVX2 = true;
+	}
+#endif
+
+	astrobwtInitialized = true;
+	return true;
+}
+
+bool xmrig::astrobwt::astrobwt_dero(const void* input_data, uint32_t input_size, void* scratchpad, uint8_t* output_hash, int stage2_max_size, bool avx2)
 {
 	uint8_t key[32];
 	uint8_t* scratchpad_ptr = (uint8_t*)(scratchpad) + 64;
@@ -166,7 +200,12 @@ bool xmrig::astrobwt::astrobwt_dero(const void* input_data, uint32_t input_size,
 	uint8_t* stage1_result = (uint8_t*)(tmp_indices);
 	uint8_t* stage2_result = (uint8_t*)(tmp_indices);
 
-	sha3_HashBuffer(256, SHA3_FLAGS_NONE, input_data, input_size, key, sizeof(key));
+#ifdef ASTROBWT_AVX2
+	if (hasAVX2 && avx2)
+		SHA3_256_AVX2_ASM(input_data, input_size, key);
+	else
+#endif
+		sha3_HashBuffer(256, SHA3_FLAGS_NONE, input_data, input_size, key, sizeof(key));
 
 	Salsa20_XORKeyStream(key, stage1_output, STAGE1_SIZE);
 
@@ -178,7 +217,12 @@ bool xmrig::astrobwt::astrobwt_dero(const void* input_data, uint32_t input_size,
 			stage1_result[i] = tmp[indices[i] & ((1 << 21) - 1)];
 	}
 
-	sha3_HashBuffer(256, SHA3_FLAGS_NONE, stage1_result, STAGE1_SIZE + 1, key, sizeof(key));
+#ifdef ASTROBWT_AVX2
+	if (hasAVX2 && avx2)
+		SHA3_256_AVX2_ASM(stage1_result, STAGE1_SIZE + 1, key);
+	else
+#endif
+		sha3_HashBuffer(256, SHA3_FLAGS_NONE, stage1_result, STAGE1_SIZE + 1, key, sizeof(key));
 
 	const int stage2_size = STAGE1_SIZE + (*(uint32_t*)(key) & 0xfffff);
 	if (stage2_size > stage2_max_size)
@@ -203,7 +247,12 @@ bool xmrig::astrobwt::astrobwt_dero(const void* input_data, uint32_t input_size,
 			stage2_result[i] = tmp[indices[i] & ((1 << 21) - 1)];
 	}
 
-	sha3_HashBuffer(256, SHA3_FLAGS_NONE, stage2_result, stage2_size + 1, output_hash, 32);
+#ifdef ASTROBWT_AVX2
+	if (hasAVX2 && avx2)
+		SHA3_256_AVX2_ASM(stage2_result, stage2_size + 1, output_hash);
+	else
+#endif
+		sha3_HashBuffer(256, SHA3_FLAGS_NONE, stage2_result, stage2_size + 1, output_hash, 32);
 
 	return true;
 }
@@ -211,5 +260,5 @@ bool xmrig::astrobwt::astrobwt_dero(const void* input_data, uint32_t input_size,
 template<>
 void xmrig::astrobwt::single_hash<xmrig::Algorithm::ASTROBWT_DERO>(const uint8_t* input, size_t size, uint8_t* output, cryptonight_ctx** ctx, uint64_t)
 {
-	astrobwt_dero(input, static_cast<uint32_t>(size), ctx[0]->memory, output, std::numeric_limits<int>::max());
+	astrobwt_dero(input, static_cast<uint32_t>(size), ctx[0]->memory, output, std::numeric_limits<int>::max(), true);
 }
diff --git a/src/crypto/astrobwt/AstroBWT.h b/src/crypto/astrobwt/AstroBWT.h
index 7a3734708..e10dc8a55 100644
--- a/src/crypto/astrobwt/AstroBWT.h
+++ b/src/crypto/astrobwt/AstroBWT.h
@@ -27,14 +27,20 @@
  */
 
 
-#include "crypto/common/Algorithm.h"
+#include "base/crypto/Algorithm.h"
+
 
 struct cryptonight_ctx;
 
 
-namespace xmrig { namespace astrobwt {
+namespace xmrig {
 
-bool astrobwt_dero(const void* input_data, uint32_t input_size, void* scratchpad, uint8_t* output_hash, int stage2_max_size);
+class Job;
+
+namespace astrobwt {
+
+bool init(const Job&);
+bool astrobwt_dero(const void* input_data, uint32_t input_size, void* scratchpad, uint8_t* output_hash, int stage2_max_size, bool avx2);
 
 template<Algorithm::Id ALGO>
 void single_hash(const uint8_t* input, size_t size, uint8_t* output, cryptonight_ctx** ctx, uint64_t);
@@ -43,4 +49,4 @@ template<>
 void single_hash<Algorithm::ASTROBWT_DERO>(const uint8_t* input, size_t size, uint8_t* output, cryptonight_ctx** ctx, uint64_t);
 
 
-}} // namespace xmrig::argon2
+}} // namespace xmrig::astrobwt
diff --git a/src/crypto/astrobwt/sha3.cpp b/src/crypto/astrobwt/sha3.cpp
index bc7a8dddb..db1b0554b 100644
--- a/src/crypto/astrobwt/sha3.cpp
+++ b/src/crypto/astrobwt/sha3.cpp
@@ -16,12 +16,12 @@
  * Aug 2015. Andrey Jivsov. crypto@brainhub.org
  * ---------------------------------------------------------------------- */
 
-#include <stdio.h>
-#include <stdint.h>
-#include <string.h>
+#include <cstdio>
+#include <cstdint>
+#include <cstring>
 
 #include "sha3.h"
-#include "crypto/common/keccak.h"
+#include "base/crypto/keccak.h"
 
 #define SHA3_ASSERT( x )
 #if defined(_MSC_VER)
diff --git a/src/crypto/astrobwt/sha3_256_avx2.S b/src/crypto/astrobwt/sha3_256_avx2.S
new file mode 100644
index 000000000..16dba72f1
--- /dev/null
+++ b/src/crypto/astrobwt/sha3_256_avx2.S
@@ -0,0 +1,53 @@
+;# 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-2019 XMR-Stak                 <https://github.com/fireice-uk>, <https://github.com/psychocrypt>
+;# Copyright 2018      Lee Clagett              <https://github.com/vtnerd>
+;# Copyright 2018-2019 tevador                  <tevador@gmail.com>
+;# Copyright 2000      Transmeta Corporation    <https://github.com/intel/msr-tools>
+;# Copyright 2004-2008 H. Peter Anvin           <https://github.com/intel/msr-tools>
+;# Copyright 2018-2020 SChernykh                <https://github.com/SChernykh>
+;# Copyright 2016-2020 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/>.
+;#
+
+.intel_syntax noprefix
+#if defined(__APPLE__)
+.text
+#define DECL(x) _##x
+#else
+.section .text
+#define DECL(x) x
+#endif
+
+#define ALIGN .balign
+#define dq .quad
+
+.global DECL(SHA3_256_AVX2_ASM)
+
+ALIGN 64
+DECL(SHA3_256_AVX2_ASM):
+
+#include "sha3_256_avx2.inc"
+
+KeccakF1600_AVX2_ASM:
+	lea r8,[rip+rot_left+96]
+	lea r9,[rip+rot_right+96]
+	lea r10,[rip+rndc]
+
+#include "sha3_256_keccakf1600_avx2.inc"
diff --git a/src/crypto/astrobwt/sha3_256_avx2.asm b/src/crypto/astrobwt/sha3_256_avx2.asm
new file mode 100644
index 000000000..f38e09f13
--- /dev/null
+++ b/src/crypto/astrobwt/sha3_256_avx2.asm
@@ -0,0 +1,45 @@
+;# 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-2019 XMR-Stak                 <https://github.com/fireice-uk>, <https://github.com/psychocrypt>
+;# Copyright 2018      Lee Clagett              <https://github.com/vtnerd>
+;# Copyright 2018-2019 tevador                  <tevador@gmail.com>
+;# Copyright 2000      Transmeta Corporation    <https://github.com/intel/msr-tools>
+;# Copyright 2004-2008 H. Peter Anvin           <https://github.com/intel/msr-tools>
+;# Copyright 2018-2020 SChernykh                <https://github.com/SChernykh>
+;# Copyright 2016-2020 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/>.
+;#
+
+_SHA3_256_AVX2_ASM SEGMENT PAGE READ EXECUTE
+PUBLIC SHA3_256_AVX2_ASM
+
+ALIGN 64
+SHA3_256_AVX2_ASM:
+
+include sha3_256_avx2.inc
+
+KeccakF1600_AVX2_ASM:
+	lea r8,[rot_left+96]
+	lea r9,[rot_right+96]
+	lea r10,[rndc]
+
+include sha3_256_keccakf1600_avx2.inc
+
+_SHA3_256_AVX2_ASM ENDS
+END
diff --git a/src/crypto/astrobwt/sha3_256_avx2.inc b/src/crypto/astrobwt/sha3_256_avx2.inc
new file mode 100644
index 000000000..81753dba9
--- /dev/null
+++ b/src/crypto/astrobwt/sha3_256_avx2.inc
@@ -0,0 +1,162 @@
+;# 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-2019 XMR-Stak                 <https://github.com/fireice-uk>, <https://github.com/psychocrypt>
+;# Copyright 2018      Lee Clagett              <https://github.com/vtnerd>
+;# Copyright 2018-2019 tevador                  <tevador@gmail.com>
+;# Copyright 2000      Transmeta Corporation    <https://github.com/intel/msr-tools>
+;# Copyright 2004-2008 H. Peter Anvin           <https://github.com/intel/msr-tools>
+;# Copyright 2018-2020 SChernykh                <https://github.com/SChernykh>
+;# Copyright 2016-2020 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/>.
+;#
+
+	vzeroupper
+
+	mov qword ptr [rsp+8],rbx
+	mov qword ptr [rsp+16],rsi
+	mov qword ptr [rsp+24],rdi
+	push rbp
+	push r12
+	push r13
+	push r14
+	push r15
+
+	sub rsp, 80
+	movdqu xmmword ptr [rsp+64], xmm6
+	movdqu xmmword ptr [rsp+48], xmm7
+	movdqu xmmword ptr [rsp+32], xmm8
+	movdqu xmmword ptr [rsp+16], xmm9
+	movdqu xmmword ptr [rsp+0], xmm10
+	sub rsp, 80
+	movdqu xmmword ptr [rsp+64], xmm11
+	movdqu xmmword ptr [rsp+48], xmm12
+	movdqu xmmword ptr [rsp+32], xmm13
+	movdqu xmmword ptr [rsp+16], xmm14
+	movdqu xmmword ptr [rsp+0], xmm15
+
+	sub rsp,320
+	lea rbp,[rsp+64]
+	and rbp,-32
+	vpxor xmm0,xmm0,xmm0
+	xor edi,edi
+	mov dword ptr [rbp],50462976
+	mov r12,rdx
+	mov dword ptr [rbp+4],169150212
+	mov r14,rdx
+	mov dword ptr [rbp+8],218436623
+	shr r14,3
+	and r12d,7
+	mov dword ptr [rbp+12],135009046
+	mov r13,r8
+	mov byte ptr [rbp+16],9
+	mov rsi,rcx
+	mov ebx,edi
+	vmovdqa ymmword ptr [rbp+32],ymm0
+	vmovdqa ymmword ptr [rbp+64],ymm0
+	vmovdqa ymmword ptr [rbp+96],ymm0
+	vmovdqa ymmword ptr [rbp+128],ymm0
+	vmovdqa ymmword ptr [rbp+160],ymm0
+	vmovdqa ymmword ptr [rbp+192],ymm0
+	vmovdqa ymmword ptr [rbp+224],ymm0
+	test r14,r14
+	je sha3_main_loop_end
+
+sha3_main_loop:
+	movzx eax,byte ptr [rbp+rbx]
+	lea rcx,[rbp+32]
+	lea rcx,[rcx+rax*8]
+	mov rax,qword ptr [rsi]
+	xor qword ptr [rcx],rax
+	lea r15,[rbx+1]
+	cmp rbx,16
+	jne skip_keccak
+
+	lea rcx,[rbp+32]
+	call KeccakF1600_AVX2_ASM
+
+skip_keccak:
+	cmp rbx,16
+	mov rax,rdi
+	cmovne rax,r15
+	add rsi,8
+	mov rbx,rax
+	sub r14,1
+	jne sha3_main_loop
+
+sha3_main_loop_end:
+	mov rdx,rdi
+	test r12,r12
+	je sha3_tail_loop_end
+	mov r8,rdi
+
+sha3_tail_loop:
+	movzx eax,byte ptr [rdx+rsi]
+	inc rdx
+	shlx rcx,rax,r8
+	or rdi,rcx
+	add r8,8
+	cmp rdx,r12
+	jb sha3_tail_loop
+
+sha3_tail_loop_end:
+	movzx eax,byte ptr [rbp+rbx]
+	lea rdx,[rbp+32]
+	lea rdx,[rdx+rax*8]
+	mov ecx,6
+	lea rax,[r12*8]
+	shlx rcx,rcx,rax
+	xor rcx,qword ptr [rdx]
+	mov eax,1
+	shl rax,63
+	xor rcx,rdi
+	mov qword ptr [rdx],rcx
+	xor qword ptr [rbp+104],rax
+
+	lea rcx,[rbp+32]
+	call KeccakF1600_AVX2_ASM
+
+	vmovups ymm0,ymmword ptr [rbp+32]
+	vmovups ymmword ptr [r13],ymm0
+	vzeroupper
+
+	add rsp,320
+
+	movdqu xmm15, xmmword ptr [rsp]
+	movdqu xmm14, xmmword ptr [rsp+16]
+	movdqu xmm13, xmmword ptr [rsp+32]
+	movdqu xmm12, xmmword ptr [rsp+48]
+	movdqu xmm11, xmmword ptr [rsp+64]
+	add rsp, 80
+	movdqu xmm10, xmmword ptr [rsp]
+	movdqu xmm9, xmmword ptr [rsp+16]
+	movdqu xmm8, xmmword ptr [rsp+32]
+	movdqu xmm7, xmmword ptr [rsp+48]
+	movdqu xmm6, xmmword ptr [rsp+64]
+	add rsp, 80
+
+	pop r15
+	pop r14
+	pop r13
+	pop r12
+	pop rbp
+	mov rbx,qword ptr [rsp+8]
+	mov rsi,qword ptr [rsp+16]
+	mov rdi,qword ptr [rsp+24]
+
+	ret
diff --git a/src/crypto/astrobwt/sha3_256_keccakf1600_avx2.inc b/src/crypto/astrobwt/sha3_256_keccakf1600_avx2.inc
new file mode 100644
index 000000000..a9bae47a1
--- /dev/null
+++ b/src/crypto/astrobwt/sha3_256_keccakf1600_avx2.inc
@@ -0,0 +1,203 @@
+;# 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-2019 XMR-Stak                 <https://github.com/fireice-uk>, <https://github.com/psychocrypt>
+;# Copyright 2018      Lee Clagett              <https://github.com/vtnerd>
+;# Copyright 2018-2019 tevador                  <tevador@gmail.com>
+;# Copyright 2000      Transmeta Corporation    <https://github.com/intel/msr-tools>
+;# Copyright 2004-2008 H. Peter Anvin           <https://github.com/intel/msr-tools>
+;# Copyright 2018-2020 SChernykh                <https://github.com/SChernykh>
+;# Copyright 2016-2020 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/>.
+;#
+
+	mov eax,24
+	lea rcx,[rcx+96]
+	vpbroadcastq ymm0,QWORD PTR [rcx-96]
+	vmovdqu ymm1,YMMWORD PTR [rcx-88]
+	vmovdqu ymm2,YMMWORD PTR [rcx-56]
+	vmovdqu ymm3,YMMWORD PTR [rcx-24]
+	vmovdqu ymm4,YMMWORD PTR [rcx+8]
+	vmovdqu ymm5,YMMWORD PTR [rcx+40]
+	vmovdqu ymm6,YMMWORD PTR [rcx+72]
+
+ALIGN 64
+Loop_avx2:
+	vpshufd ymm13,ymm2,78
+	vpxor ymm12,ymm5,ymm3
+	vpxor ymm9,ymm4,ymm6
+	vpxor ymm12,ymm12,ymm1
+	vpxor ymm12,ymm12,ymm9
+	vpermq ymm11,ymm12,147
+	vpxor ymm13,ymm13,ymm2
+	vpermq ymm7,ymm13,78
+	vpsrlq ymm8,ymm12,63
+	vpaddq ymm9,ymm12,ymm12
+	vpor ymm8,ymm8,ymm9
+	vpermq ymm15,ymm8,57
+	vpxor ymm14,ymm8,ymm11
+	vpermq ymm14,ymm14,0
+	vpxor ymm13,ymm13,ymm0
+	vpxor ymm13,ymm13,ymm7
+	vpsrlq ymm7,ymm13,63
+	vpaddq ymm8,ymm13,ymm13
+	vpor ymm8,ymm8,ymm7
+	vpxor ymm2,ymm2,ymm14
+	vpxor ymm0,ymm0,ymm14
+	vpblendd ymm15,ymm15,ymm8,192
+	vpblendd ymm11,ymm11,ymm13,3
+	vpxor ymm15,ymm15,ymm11
+	vpsllvq ymm10,ymm2,YMMWORD PTR [r8-96]
+	vpsrlvq ymm2,ymm2,YMMWORD PTR [r9-96]
+	vpor ymm2,ymm2,ymm10
+	vpxor ymm3,ymm3,ymm15
+	vpsllvq ymm11,ymm3,YMMWORD PTR [r8-32]
+	vpsrlvq ymm3,ymm3,YMMWORD PTR [r9-32]
+	vpor ymm3,ymm3,ymm11
+	vpxor ymm4,ymm4,ymm15
+	vpsllvq ymm12,ymm4,YMMWORD PTR [r8]
+	vpsrlvq ymm4,ymm4,YMMWORD PTR [r9]
+	vpor ymm4,ymm4,ymm12
+	vpxor ymm5,ymm5,ymm15
+	vpsllvq ymm13,ymm5,YMMWORD PTR [r8+32]
+	vpsrlvq ymm5,ymm5,YMMWORD PTR [r9+32]
+	vpor ymm5,ymm5,ymm13
+	vpxor ymm6,ymm6,ymm15
+	vpermq ymm10,ymm2,141
+	vpermq ymm11,ymm3,141
+	vpsllvq ymm14,ymm6,YMMWORD PTR [r8+64]
+	vpsrlvq ymm8,ymm6,YMMWORD PTR [r9+64]
+	vpor ymm8,ymm8,ymm14
+	vpxor ymm1,ymm1,ymm15
+	vpermq ymm12,ymm4,27
+	vpermq ymm13,ymm5,114
+	vpsllvq ymm15,ymm1,YMMWORD PTR [r8-64]
+	vpsrlvq ymm9,ymm1,YMMWORD PTR [r9-64]
+	vpor ymm9,ymm9,ymm15
+	vpsrldq ymm14,ymm8,8
+	vpandn ymm7,ymm8,ymm14
+	vpblendd ymm3,ymm9,ymm13,12
+	vpblendd ymm15,ymm11,ymm9,12
+	vpblendd ymm5,ymm10,ymm11,12
+	vpblendd ymm14,ymm9,ymm10,12
+	vpblendd ymm3,ymm3,ymm11,48
+	vpblendd ymm15,ymm15,ymm12,48
+	vpblendd ymm5,ymm5,ymm9,48
+	vpblendd ymm14,ymm14,ymm13,48
+	vpblendd ymm3,ymm3,ymm12,192
+	vpblendd ymm15,ymm15,ymm13,192
+	vpblendd ymm5,ymm5,ymm13,192
+	vpblendd ymm14,ymm14,ymm11,192
+	vpandn ymm3,ymm3,ymm15
+	vpandn ymm5,ymm5,ymm14
+	vpblendd ymm6,ymm12,ymm9,12
+	vpblendd ymm15,ymm10,ymm12,12
+	vpxor ymm3,ymm3,ymm10
+	vpblendd ymm6,ymm6,ymm10,48
+	vpblendd ymm15,ymm15,ymm11,48
+	vpxor ymm5,ymm5,ymm12
+	vpblendd ymm6,ymm6,ymm11,192
+	vpblendd ymm15,ymm15,ymm9,192
+	vpandn ymm6,ymm6,ymm15
+	vpxor ymm6,ymm6,ymm13
+	vpermq ymm4,ymm8,30
+	vpblendd ymm15,ymm4,ymm0,48
+	vpermq ymm1,ymm8,57
+	vpblendd ymm1,ymm1,ymm0,192
+	vpandn ymm1,ymm1,ymm15
+	vpblendd ymm2,ymm11,ymm12,12
+	vpblendd ymm14,ymm13,ymm11,12
+	vpblendd ymm2,ymm2,ymm13,48
+	vpblendd ymm14,ymm14,ymm10,48
+	vpblendd ymm2,ymm2,ymm10,192
+	vpblendd ymm14,ymm14,ymm12,192
+	vpandn ymm2,ymm2,ymm14
+	vpxor ymm2,ymm2,ymm9
+	vpermq ymm7,ymm7,0
+	vpermq ymm3,ymm3,27
+	vpermq ymm5,ymm5,141
+	vpermq ymm6,ymm6,114
+	vpblendd ymm4,ymm13,ymm10,12
+	vpblendd ymm14,ymm12,ymm13,12
+	vpblendd ymm4,ymm4,ymm12,48
+	vpblendd ymm14,ymm14,ymm9,48
+	vpblendd ymm4,ymm4,ymm9,192
+	vpblendd ymm14,ymm14,ymm10,192
+	vpandn ymm4,ymm4,ymm14
+	vpxor ymm0,ymm0,ymm7
+	vpxor ymm1,ymm1,ymm8
+	vpxor ymm4,ymm4,ymm11
+	vpxor ymm0,ymm0,YMMWORD PTR [r10]
+	lea r10,[r10+32]
+	dec eax
+	jnz Loop_avx2
+
+	vmovq QWORD PTR [rcx-96],xmm0
+	vmovdqu YMMWORD PTR [rcx-88],ymm1
+	vmovdqu YMMWORD PTR [rcx-56],ymm2
+	vmovdqu YMMWORD PTR [rcx-24],ymm3
+	vmovdqu YMMWORD PTR [rcx+8],ymm4
+	vmovdqu YMMWORD PTR [rcx+40],ymm5
+	vmovdqu YMMWORD PTR [rcx+72],ymm6
+
+	ret
+
+ALIGN 32
+rot_left:
+	dq 3, 18, 36, 41
+	dq 1, 62, 28, 27
+	dq 45, 6, 56, 39
+	dq 10, 61, 55, 8
+	dq 2, 15, 25, 20
+	dq 44, 43, 21, 14
+
+ALIGN 32
+rot_right:
+	dq 64-3, 64-18, 64-36, 64-41
+	dq 64-1, 64-62, 64-28, 64-27
+	dq 64-45, 64-6, 64-56, 64-39
+	dq 64-10, 64-61, 64-55, 64-8
+	dq 64-2, 64-15, 64-25, 64-20
+	dq 64-44, 64-43, 64-21, 64-14
+
+ALIGN 32
+rndc:
+        dq 1, 1, 1, 1
+        dq 32898, 32898, 32898, 32898
+        dq 9223372036854808714, 9223372036854808714, 9223372036854808714, 9223372036854808714
+        dq 9223372039002292224, 9223372039002292224, 9223372039002292224, 9223372039002292224
+        dq 32907, 32907, 32907, 32907
+        dq 2147483649, 2147483649, 2147483649, 2147483649
+        dq 9223372039002292353, 9223372039002292353, 9223372039002292353, 9223372039002292353
+        dq 9223372036854808585, 9223372036854808585, 9223372036854808585, 9223372036854808585
+        dq 138, 138, 138, 138
+        dq 136, 136, 136, 136
+        dq 2147516425, 2147516425, 2147516425, 2147516425
+        dq 2147483658, 2147483658, 2147483658, 2147483658
+        dq 2147516555, 2147516555, 2147516555, 2147516555
+        dq 9223372036854775947, 9223372036854775947, 9223372036854775947, 9223372036854775947
+        dq 9223372036854808713, 9223372036854808713, 9223372036854808713, 9223372036854808713
+        dq 9223372036854808579, 9223372036854808579, 9223372036854808579, 9223372036854808579
+        dq 9223372036854808578, 9223372036854808578, 9223372036854808578, 9223372036854808578
+        dq 9223372036854775936, 9223372036854775936, 9223372036854775936, 9223372036854775936
+        dq 32778, 32778, 32778, 32778
+        dq 9223372039002259466, 9223372039002259466, 9223372039002259466, 9223372039002259466
+        dq 9223372039002292353, 9223372039002292353, 9223372039002292353, 9223372039002292353
+        dq 9223372036854808704, 9223372036854808704, 9223372036854808704, 9223372036854808704
+        dq 2147483649, 2147483649, 2147483649, 2147483649
+        dq 9223372039002292232, 9223372039002292232, 9223372039002292232, 9223372039002292232
diff --git a/src/crypto/cn/CnCtx.cpp b/src/crypto/cn/CnCtx.cpp
index 5d41bca0d..ee151fb30 100644
--- a/src/crypto/cn/CnCtx.cpp
+++ b/src/crypto/cn/CnCtx.cpp
@@ -6,8 +6,8 @@
  * Copyright 2016      Jay D Dee   <jayddee246@gmail.com>
  * Copyright 2017-2019 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>
+ * Copyright 2018-2020 SChernykh   <https://github.com/SChernykh>
+ * Copyright 2016-2020 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
@@ -27,8 +27,8 @@
 
 
 #include "crypto/cn/CnCtx.h"
+#include "base/crypto/Algorithm.h"
 #include "crypto/cn/CryptoNight.h"
-#include "crypto/common/Algorithm.h"
 #include "crypto/common/portable/mm_malloc.h"
 #include "crypto/common/VirtualMemory.h"
 
diff --git a/src/crypto/cn/CnCtx.h b/src/crypto/cn/CnCtx.h
index 7b0adbec2..7939bf4e9 100644
--- a/src/crypto/cn/CnCtx.h
+++ b/src/crypto/cn/CnCtx.h
@@ -6,8 +6,8 @@
  * Copyright 2016      Jay D Dee   <jayddee246@gmail.com>
  * Copyright 2017-2019 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>
+ * Copyright 2018-2020 SChernykh   <https://github.com/SChernykh>
+ * Copyright 2016-2020 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
@@ -27,8 +27,8 @@
 #define XMRIG_CN_CTX_H
 
 
-#include <stddef.h>
-#include <stdint.h>
+#include <cstddef>
+#include <cstdint>
 
 
 struct cryptonight_ctx;
diff --git a/src/crypto/cn/CnHash.cpp b/src/crypto/cn/CnHash.cpp
index 309dbe3ec..846fb626f 100644
--- a/src/crypto/cn/CnHash.cpp
+++ b/src/crypto/cn/CnHash.cpp
@@ -6,8 +6,8 @@
  * Copyright 2016      Jay D Dee   <jayddee246@gmail.com>
  * Copyright 2017-2019 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>
+ * Copyright 2018-2020 SChernykh   <https://github.com/SChernykh>
+ * Copyright 2016-2020 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
diff --git a/src/crypto/cn/CnHash.h b/src/crypto/cn/CnHash.h
index 92f4df942..f0b5a7110 100644
--- a/src/crypto/cn/CnHash.h
+++ b/src/crypto/cn/CnHash.h
@@ -6,8 +6,8 @@
  * Copyright 2016      Jay D Dee   <jayddee246@gmail.com>
  * Copyright 2017-2019 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>
+ * Copyright 2018-2020 SChernykh   <https://github.com/SChernykh>
+ * Copyright 2016-2020 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
@@ -31,7 +31,7 @@
 #include <cstdint>
 
 
-#include "crypto/cn/CnAlgo.h"
+#include "base/crypto/CnAlgo.h"
 #include "crypto/common/Assembly.h"
 
 
diff --git a/src/crypto/cn/CryptoNight_arm.h b/src/crypto/cn/CryptoNight_arm.h
index 022666349..f8ddbd543 100644
--- a/src/crypto/cn/CryptoNight_arm.h
+++ b/src/crypto/cn/CryptoNight_arm.h
@@ -7,8 +7,8 @@
  * Copyright 2016      Imran Yusuff <https://github.com/imranyusuff>
  * Copyright 2017-2019 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>
+ * Copyright 2018-2020 SChernykh   <https://github.com/SChernykh>
+ * Copyright 2016-2020 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
@@ -28,11 +28,11 @@
 #define XMRIG_CRYPTONIGHT_ARM_H
 
 
-#include "crypto/cn/CnAlgo.h"
+#include "base/crypto/CnAlgo.h"
+#include "base/crypto/keccak.h"
 #include "crypto/cn/CryptoNight_monero.h"
 #include "crypto/cn/CryptoNight.h"
 #include "crypto/cn/soft_aes.h"
-#include "crypto/common/keccak.h"
 #include "crypto/common/portable/mm_malloc.h"
 
 
diff --git a/src/crypto/cn/CryptoNight_x86.h b/src/crypto/cn/CryptoNight_x86.h
index b63c32922..d71af0134 100644
--- a/src/crypto/cn/CryptoNight_x86.h
+++ b/src/crypto/cn/CryptoNight_x86.h
@@ -6,8 +6,8 @@
  * Copyright 2016      Jay D Dee   <jayddee246@gmail.com>
  * Copyright 2017-2019 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>
+ * Copyright 2018-2020 SChernykh   <https://github.com/SChernykh>
+ * Copyright 2016-2020 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
@@ -36,11 +36,11 @@
 
 
 #include "backend/cpu/Cpu.h"
-#include "crypto/cn/CnAlgo.h"
+#include "base/crypto/CnAlgo.h"
+#include "base/crypto/keccak.h"
 #include "crypto/cn/CryptoNight_monero.h"
 #include "crypto/cn/CryptoNight.h"
 #include "crypto/cn/soft_aes.h"
-#include "crypto/common/keccak.h"
 
 
 extern "C"
diff --git a/src/crypto/cn/gpu/cn_gpu_avx.cpp b/src/crypto/cn/gpu/cn_gpu_avx.cpp
index 38da97149..d3dc7b819 100644
--- a/src/crypto/cn/gpu/cn_gpu_avx.cpp
+++ b/src/crypto/cn/gpu/cn_gpu_avx.cpp
@@ -5,8 +5,8 @@
  * Copyright 2014-2016 Wolf9466    <https://github.com/OhGodAPet>
  * Copyright 2016      Jay D Dee   <jayddee246@gmail.com>
  * Copyright 2017-2019 XMR-Stak    <https://github.com/fireice-uk>, <https://github.com/psychocrypt>
- * Copyright 2018-2019 SChernykh   <https://github.com/SChernykh>
- * Copyright 2016-2019 XMRig       <support@xmrig.com>
+ * Copyright 2018-2020 SChernykh   <https://github.com/SChernykh>
+ * Copyright 2016-2020 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
@@ -23,7 +23,7 @@
  */
 
 
-#include "crypto/cn/CnAlgo.h"
+#include "base/crypto/CnAlgo.h"
 
 
 #ifdef __GNUC__
diff --git a/src/crypto/cn/gpu/cn_gpu_ssse3.cpp b/src/crypto/cn/gpu/cn_gpu_ssse3.cpp
index 7cca096ef..7e0ef5b79 100644
--- a/src/crypto/cn/gpu/cn_gpu_ssse3.cpp
+++ b/src/crypto/cn/gpu/cn_gpu_ssse3.cpp
@@ -5,8 +5,8 @@
  * Copyright 2014-2016 Wolf9466    <https://github.com/OhGodAPet>
  * Copyright 2016      Jay D Dee   <jayddee246@gmail.com>
  * Copyright 2017-2019 XMR-Stak    <https://github.com/fireice-uk>, <https://github.com/psychocrypt>
- * Copyright 2018-2019 SChernykh   <https://github.com/SChernykh>
- * Copyright 2016-2019 XMRig       <support@xmrig.com>
+ * Copyright 2018-2020 SChernykh   <https://github.com/SChernykh>
+ * Copyright 2016-2020 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
@@ -23,7 +23,7 @@
  */
 
 
-#include "crypto/cn/CnAlgo.h"
+#include "base/crypto/CnAlgo.h"
 
 
 #ifdef __GNUC__
diff --git a/src/crypto/cn/r/variant4_random_math.h b/src/crypto/cn/r/variant4_random_math.h
index 732900612..f8dfb274d 100644
--- a/src/crypto/cn/r/variant4_random_math.h
+++ b/src/crypto/cn/r/variant4_random_math.h
@@ -2,10 +2,10 @@
 #define VARIANT4_RANDOM_MATH_H
 
 
-#include <string.h>
+#include <cstring>
 
 
-#include "crypto/common/Algorithm.h"
+#include "base/crypto/Algorithm.h"
 
 
 extern "C"
diff --git a/src/crypto/rx/Rx.cpp b/src/crypto/rx/Rx.cpp
index c04254094..3971fb5b1 100644
--- a/src/crypto/rx/Rx.cpp
+++ b/src/crypto/rx/Rx.cpp
@@ -40,6 +40,7 @@ class RxPrivate;
 
 
 static bool osInitialized   = false;
+static bool msrInitialized  = false;
 static const char *tag      = BLUE_BG(WHITE_BOLD_S " rx  ") " ";
 static RxPrivate *d_ptr     = nullptr;
 
@@ -65,6 +66,10 @@ const char *xmrig::rx_tag()
 bool xmrig::Rx::init(const Job &job, const RxConfig &config, const CpuConfig &cpu)
 {
     if (job.algorithm().family() != Algorithm::RANDOM_X) {
+        if (msrInitialized) {
+            msrDestroy();
+            msrInitialized = false;
+        }
         return true;
     }
 
@@ -72,8 +77,12 @@ bool xmrig::Rx::init(const Job &job, const RxConfig &config, const CpuConfig &cp
         return true;
     }
 
-    if (!osInitialized) {
+    if (!msrInitialized) {
         msrInit(config);
+        msrInitialized = true;
+    }
+
+    if (!osInitialized) {
         setupMainLoopExceptionFrame();
         osInitialized = true;
     }
diff --git a/src/crypto/rx/RxAlgo.h b/src/crypto/rx/RxAlgo.h
index a939c27f5..81c4687c1 100644
--- a/src/crypto/rx/RxAlgo.h
+++ b/src/crypto/rx/RxAlgo.h
@@ -7,8 +7,8 @@
  * Copyright 2017-2019 XMR-Stak    <https://github.com/fireice-uk>, <https://github.com/psychocrypt>
  * Copyright 2018      Lee Clagett <https://github.com/vtnerd>
  * Copyright 2018-2019 tevador     <tevador@gmail.com>
- * Copyright 2018-2019 SChernykh   <https://github.com/SChernykh>
- * Copyright 2016-2019 XMRig       <https://github.com/xmrig>, <support@xmrig.com>
+ * Copyright 2018-2020 SChernykh   <https://github.com/SChernykh>
+ * Copyright 2016-2020 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
@@ -32,7 +32,7 @@
 #include <cstdint>
 
 
-#include "crypto/common/Algorithm.h"
+#include "base/crypto/Algorithm.h"
 
 
 struct RandomX_ConfigurationBase;
diff --git a/src/crypto/rx/RxDataset.cpp b/src/crypto/rx/RxDataset.cpp
index ba1721af7..e0e9fccff 100644
--- a/src/crypto/rx/RxDataset.cpp
+++ b/src/crypto/rx/RxDataset.cpp
@@ -7,8 +7,8 @@
  * Copyright 2017-2019 XMR-Stak    <https://github.com/fireice-uk>, <https://github.com/psychocrypt>
  * Copyright 2018      Lee Clagett <https://github.com/vtnerd>
  * Copyright 2018-2019 tevador     <tevador@gmail.com>
- * Copyright 2018-2019 SChernykh   <https://github.com/SChernykh>
- * Copyright 2016-2019 XMRig       <https://github.com/xmrig>, <support@xmrig.com>
+ * Copyright 2018-2020 SChernykh   <https://github.com/SChernykh>
+ * Copyright 2016-2020 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
diff --git a/src/crypto/rx/RxDataset.h b/src/crypto/rx/RxDataset.h
index e46a93c6f..34840fc42 100644
--- a/src/crypto/rx/RxDataset.h
+++ b/src/crypto/rx/RxDataset.h
@@ -7,8 +7,8 @@
  * Copyright 2017-2019 XMR-Stak    <https://github.com/fireice-uk>, <https://github.com/psychocrypt>
  * Copyright 2018      Lee Clagett <https://github.com/vtnerd>
  * Copyright 2018-2019 tevador     <tevador@gmail.com>
- * Copyright 2018-2019 SChernykh   <https://github.com/SChernykh>
- * Copyright 2016-2019 XMRig       <https://github.com/xmrig>, <support@xmrig.com>
+ * Copyright 2018-2020 SChernykh   <https://github.com/SChernykh>
+ * Copyright 2016-2020 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
@@ -28,8 +28,8 @@
 #define XMRIG_RX_DATASET_H
 
 
+#include "base/crypto/Algorithm.h"
 #include "base/tools/Object.h"
-#include "crypto/common/Algorithm.h"
 #include "crypto/common/HugePagesInfo.h"
 #include "crypto/randomx/configuration.h"
 #include "crypto/randomx/randomx.h"
diff --git a/src/net/strategies/DonateStrategy.cpp b/src/net/strategies/DonateStrategy.cpp
index 4559334bc..ace9cfa3f 100644
--- a/src/net/strategies/DonateStrategy.cpp
+++ b/src/net/strategies/DonateStrategy.cpp
@@ -28,6 +28,8 @@
 #include <iterator>
 
 
+#include "net/strategies/DonateStrategy.h"
+#include "base/crypto/keccak.h"
 #include "base/kernel/Platform.h"
 #include "base/net/stratum/Client.h"
 #include "base/net/stratum/Job.h"
@@ -38,9 +40,7 @@
 #include "core/config/Config.h"
 #include "core/Controller.h"
 #include "core/Miner.h"
-#include "crypto/common/keccak.h"
 #include "net/Network.h"
-#include "net/strategies/DonateStrategy.h"
 #include "rapidjson/document.h"
 
 
diff --git a/src/version.h b/src/version.h
index a770cc86c..7a304e6f9 100644
--- a/src/version.h
+++ b/src/version.h
@@ -28,14 +28,14 @@
 #define APP_ID        "xmrig"
 #define APP_NAME      "XMRig"
 #define APP_DESC      "XMRig miner"
-#define APP_VERSION   "5.9.0"
+#define APP_VERSION   "5.10.0-dev"
 #define APP_DOMAIN    "xmrig.com"
 #define APP_SITE      "www.xmrig.com"
 #define APP_COPYRIGHT "Copyright (C) 2016-2020 xmrig.com"
 #define APP_KIND      "miner"
 
 #define APP_VER_MAJOR  5
-#define APP_VER_MINOR  9
+#define APP_VER_MINOR  10
 #define APP_VER_PATCH  0
 
 #ifdef _MSC_VER