From adc7659e5588222bf5aa370e11a132606bf0a9f2 Mon Sep 17 00:00:00 2001 From: uPlexa Date: Sun, 2 Dec 2018 00:14:41 -0800 Subject: [PATCH] Add UPX Support --- README.md | 3 +- multihashing.cc | 96 ++++++++++++++++++++++++++++ xmrig/common/xmrig.h | 1 + xmrig/crypto/CryptoNight_constants.h | 16 +++++ 4 files changed, 115 insertions(+), 1 deletion(-) diff --git a/README.md b/README.md index ec405085..3e9b8d03 100644 --- a/README.md +++ b/README.md @@ -9,6 +9,7 @@ Algorithms * cryptonight (v0, v1, v2, xtl, msr, rto, xao) * cryptonight-light (v0, v1) * cryptonight-heavy (v0, xhv, tube) +* cryptonight-upx Usage ----- @@ -24,7 +25,7 @@ So far this native Node.js addon can do the following hashing algos ```javascript var multiHashing = require('cryptonight-hashing'); -var algorithms = ['cryptonight', 'cryptonight_light', 'cryptonight_heavy' ]; +var algorithms = ['cryptonight', 'cryptonight_light', 'cryptonight_heavy', 'cryptonight-upx' ]; var data = new Buffer("7000000001e980924e4e1109230383e66d62945ff8e749903bea4336755c00000000000051928aff1b4d72416173a8c3948159a09a73ac3bb556aa6bfbcad1a85da7f4c1d13350531e24031b939b9e2b", "hex"); diff --git a/multihashing.cc b/multihashing.cc index cede960f..50455073 100644 --- a/multihashing.cc +++ b/multihashing.cc @@ -88,6 +88,33 @@ NAN_METHOD(cryptonight) { info.GetReturnValue().Set(returnValue); } +NAN_METHOD(cryptonight_upx) { + if (info.Length() < 1) return THROW_ERROR_EXCEPTION("You must provide one argument."); + + Local target = info[0]->ToObject(); + if (!Buffer::HasInstance(target)) return THROW_ERROR_EXCEPTION("Argument 1 should be a buffer object."); + + int variant = 0; + + if (info.Length() >= 2) { + if (!info[1]->IsNumber()) return THROW_ERROR_EXCEPTION("Argument 2 should be a number"); + variant = Nan::To(info[1]).FromMaybe(0); + } + + char output[32]; + init_ctx(); + switch (variant) { + case 0: cryptonight_single_hash(reinterpret_cast(Buffer::Data(target)), Buffer::Length(target), reinterpret_cast(output), &ctx); + break; + case 1: cryptonight_single_hash(reinterpret_cast(Buffer::Data(target)), Buffer::Length(target), reinterpret_cast(output), &ctx); + break; + default: cryptonight_single_hash(reinterpret_cast(Buffer::Data(target)), Buffer::Length(target), reinterpret_cast(output), &ctx); + } + + v8::Local returnValue = Nan::CopyBuffer(output, 32).ToLocalChecked(); + info.GetReturnValue().Set(returnValue); +} + NAN_METHOD(cryptonight_light) { if (info.Length() < 1) return THROW_ERROR_EXCEPTION("You must provide one argument."); @@ -228,6 +255,52 @@ NAN_METHOD(cryptonight_async) { Nan::AsyncQueueWorker(new CCryptonightAsync(callback, Buffer::Data(target), Buffer::Length(target), variant)); } + +class CCryptonightUPXAsync : public Nan::AsyncWorker { + + private: + + struct cryptonight_ctx* m_ctx; + const char* const m_input; + const uint32_t m_input_len; + const int m_variant; + char m_output[32]; + + public: + + CCryptonightUPXAsync(Nan::Callback* const callback, const char* const input, const uint32_t input_len, const int variant) + : Nan::AsyncWorker(callback), m_ctx(static_cast(_mm_malloc(sizeof(cryptonight_ctx), 16))), + m_input(input), m_input_len(input_len), m_variant(variant) { + m_ctx->memory = static_cast(_mm_malloc(xmrig::CRYPTONIGHT_UPX_MEMORY, 4096)); + } + + ~CCryptonightUPXAsync() { + _mm_free(m_ctx->memory); + _mm_free(m_ctx); + } + + void Execute () { + switch (m_variant) { + case 0: cryptonight_single_hash(reinterpret_cast(m_input), m_input_len, reinterpret_cast(m_output), &m_ctx); + break; + case 1: cryptonight_single_hash(reinterpret_cast(m_input), m_input_len, reinterpret_cast(m_output), &m_ctx); + break; + default: cryptonight_single_hash(reinterpret_cast(m_input), m_input_len, reinterpret_cast(m_output), &m_ctx); + } + } + + void HandleOKCallback () { + Nan::HandleScope scope; + + v8::Local argv[] = { + Nan::Null(), + v8::Local(Nan::CopyBuffer(m_output, 32).ToLocalChecked()) + }; + callback->Call(2, argv, async_resource); + } +}; + + class CCryptonightLightAsync : public Nan::AsyncWorker { private: @@ -272,6 +345,27 @@ class CCryptonightLightAsync : public Nan::AsyncWorker { } }; +NAN_METHOD(cryptonight_upx_async) { + if (info.Length() < 2) return THROW_ERROR_EXCEPTION("You must provide at least two arguments."); + + Local target = info[0]->ToObject(); + if (!Buffer::HasInstance(target)) return THROW_ERROR_EXCEPTION("Argument should be a buffer object."); + + int variant = 0; + + int callback_arg_num; + if (info.Length() >= 3) { + if (!info[1]->IsNumber()) return THROW_ERROR_EXCEPTION("Argument 2 should be a number"); + variant = Nan::To(info[1]).FromMaybe(0); + callback_arg_num = 2; + } else { + callback_arg_num = 1; + } + + Callback *callback = new Nan::Callback(info[callback_arg_num].As()); + Nan::AsyncQueueWorker(new CCryptonightUPXAsync(callback, Buffer::Data(target), Buffer::Length(target), variant)); +} + NAN_METHOD(cryptonight_light_async) { if (info.Length() < 2) return THROW_ERROR_EXCEPTION("You must provide at least two arguments."); @@ -366,6 +460,8 @@ NAN_METHOD(cryptonight_heavy_async) { NAN_MODULE_INIT(init) { Nan::Set(target, Nan::New("cryptonight").ToLocalChecked(), Nan::GetFunction(Nan::New(cryptonight)).ToLocalChecked()); Nan::Set(target, Nan::New("cryptonight_async").ToLocalChecked(), Nan::GetFunction(Nan::New(cryptonight_async)).ToLocalChecked()); + Nan::Set(target, Nan::New("cryptonight_upx").ToLocalChecked(), Nan::GetFunction(Nan::New(cryptonight_upx)).ToLocalChecked()); + Nan::Set(target, Nan::New("cryptonight_upx_async").ToLocalChecked(), Nan::GetFunction(Nan::New(cryptonight_upx_async)).ToLocalChecked()); Nan::Set(target, Nan::New("cryptonight_light").ToLocalChecked(), Nan::GetFunction(Nan::New(cryptonight_light)).ToLocalChecked()); Nan::Set(target, Nan::New("cryptonight_light_async").ToLocalChecked(), Nan::GetFunction(Nan::New(cryptonight_light_async)).ToLocalChecked()); Nan::Set(target, Nan::New("cryptonight_heavy").ToLocalChecked(), Nan::GetFunction(Nan::New(cryptonight_heavy)).ToLocalChecked()); diff --git a/xmrig/common/xmrig.h b/xmrig/common/xmrig.h index 52650f0d..1a63349f 100644 --- a/xmrig/common/xmrig.h +++ b/xmrig/common/xmrig.h @@ -32,6 +32,7 @@ namespace xmrig enum Algo { INVALID_ALGO = -1, CRYPTONIGHT, /* CryptoNight (Monero) */ + CRYPTONIGHT_UPX, /* CryptoNight-UPX (uPlexa) */ CRYPTONIGHT_LITE, /* CryptoNight-Lite (AEON) */ CRYPTONIGHT_HEAVY /* CryptoNight-Heavy (RYO) */ }; diff --git a/xmrig/crypto/CryptoNight_constants.h b/xmrig/crypto/CryptoNight_constants.h index f13891a7..acde56cc 100644 --- a/xmrig/crypto/CryptoNight_constants.h +++ b/xmrig/crypto/CryptoNight_constants.h @@ -45,6 +45,10 @@ constexpr const size_t CRYPTONIGHT_LITE_MEMORY = 1 * 1024 * 1024; constexpr const uint32_t CRYPTONIGHT_LITE_MASK = 0xFFFF0; constexpr const uint32_t CRYPTONIGHT_LITE_ITER = 0x40000; +constexpr const size_t CRYPTONIGHT_UPX_MEMORY = 1 * 1024 * 1024; +constexpr const uint32_t CRYPTONIGHT_UPX_MASK = 0xFFFF0; +constexpr const uint32_t CRYPTONIGHT_UPX_ITER = 0x20000; + constexpr const size_t CRYPTONIGHT_HEAVY_MEMORY = 4 * 1024 * 1024; constexpr const uint32_t CRYPTONIGHT_HEAVY_MASK = 0x3FFFF0; constexpr const uint32_t CRYPTONIGHT_HEAVY_ITER = 0x40000; @@ -52,6 +56,7 @@ constexpr const uint32_t CRYPTONIGHT_HEAVY_ITER = 0x40000; template inline constexpr size_t cn_select_memory() { return 0; } template<> inline constexpr size_t cn_select_memory() { return CRYPTONIGHT_MEMORY; } +template<> inline constexpr size_t cn_select_memory() { return CRYPTONIGHT_UPX_MEMORY; } template<> inline constexpr size_t cn_select_memory() { return CRYPTONIGHT_LITE_MEMORY; } template<> inline constexpr size_t cn_select_memory() { return CRYPTONIGHT_HEAVY_MEMORY; } @@ -66,6 +71,9 @@ inline size_t cn_select_memory(Algo algorithm) case CRYPTONIGHT_LITE: return CRYPTONIGHT_LITE_MEMORY; + case CRYPTONIGHT_UPX: + return CRYPTONIGHT_UPX_MEMORY; + case CRYPTONIGHT_HEAVY: return CRYPTONIGHT_HEAVY_MEMORY; @@ -79,6 +87,7 @@ inline size_t cn_select_memory(Algo algorithm) template inline constexpr uint32_t cn_select_mask() { return 0; } template<> inline constexpr uint32_t cn_select_mask() { return CRYPTONIGHT_MASK; } +template<> inline constexpr uint32_t cn_select_mask() { return CRYPTONIGHT_UPX_MASK; } template<> inline constexpr uint32_t cn_select_mask() { return CRYPTONIGHT_LITE_MASK; } template<> inline constexpr uint32_t cn_select_mask() { return CRYPTONIGHT_HEAVY_MASK; } @@ -93,6 +102,9 @@ inline uint32_t cn_select_mask(Algo algorithm) case CRYPTONIGHT_LITE: return CRYPTONIGHT_LITE_MASK; + case CRYPTONIGHT_UPX: + return CRYPTONIGHT_UPX_MASK; + case CRYPTONIGHT_HEAVY: return CRYPTONIGHT_HEAVY_MASK; @@ -112,6 +124,7 @@ template<> inline constexpr uint32_t cn_select_iter() template<> inline constexpr uint32_t cn_select_iter() { return CRYPTONIGHT_MSR_ITER; } template<> inline constexpr uint32_t cn_select_iter() { return CRYPTONIGHT_XAO_ITER; } template<> inline constexpr uint32_t cn_select_iter() { return CRYPTONIGHT_ITER; } +template<> inline constexpr uint32_t cn_select_iter() { return CRYPTONIGHT_UPX_ITER; } template<> inline constexpr uint32_t cn_select_iter() { return CRYPTONIGHT_LITE_ITER; } template<> inline constexpr uint32_t cn_select_iter() { return CRYPTONIGHT_LITE_ITER; } template<> inline constexpr uint32_t cn_select_iter() { return CRYPTONIGHT_HEAVY_ITER; } @@ -140,6 +153,9 @@ inline uint32_t cn_select_iter(Algo algorithm, Variant variant) case CRYPTONIGHT_LITE: return CRYPTONIGHT_LITE_ITER; + case CRYPTONIGHT_UPX: + return CRYPTONIGHT_UPX; + case CRYPTONIGHT_HEAVY: return CRYPTONIGHT_HEAVY_ITER;