Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add UPX Support #15

Open
wants to merge 1 commit into
base: master
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
3 changes: 2 additions & 1 deletion README.md
Original file line number Diff line number Diff line change
Expand Up @@ -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
-----
Expand All @@ -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");

Expand Down
96 changes: 96 additions & 0 deletions multihashing.cc
Original file line number Diff line number Diff line change
Expand Up @@ -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<Object> 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<int>(info[1]).FromMaybe(0);
}

char output[32];
init_ctx();
switch (variant) {
case 0: cryptonight_single_hash<xmrig::CRYPTONIGHT_UPX, SOFT_AES, xmrig::VARIANT_0>(reinterpret_cast<const uint8_t*>(Buffer::Data(target)), Buffer::Length(target), reinterpret_cast<uint8_t*>(output), &ctx);
break;
case 1: cryptonight_single_hash<xmrig::CRYPTONIGHT_UPX, SOFT_AES, xmrig::VARIANT_1>(reinterpret_cast<const uint8_t*>(Buffer::Data(target)), Buffer::Length(target), reinterpret_cast<uint8_t*>(output), &ctx);
break;
default: cryptonight_single_hash<xmrig::CRYPTONIGHT_UPX, SOFT_AES, xmrig::VARIANT_1>(reinterpret_cast<const uint8_t*>(Buffer::Data(target)), Buffer::Length(target), reinterpret_cast<uint8_t*>(output), &ctx);
}

v8::Local<v8::Value> 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.");

Expand Down Expand Up @@ -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<cryptonight_ctx *>(_mm_malloc(sizeof(cryptonight_ctx), 16))),
m_input(input), m_input_len(input_len), m_variant(variant) {
m_ctx->memory = static_cast<uint8_t *>(_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<xmrig::CRYPTONIGHT_UPX, SOFT_AES, xmrig::VARIANT_0>(reinterpret_cast<const uint8_t*>(m_input), m_input_len, reinterpret_cast<uint8_t*>(m_output), &m_ctx);
break;
case 1: cryptonight_single_hash<xmrig::CRYPTONIGHT_UPX, SOFT_AES, xmrig::VARIANT_1>(reinterpret_cast<const uint8_t*>(m_input), m_input_len, reinterpret_cast<uint8_t*>(m_output), &m_ctx);
break;
default: cryptonight_single_hash<xmrig::CRYPTONIGHT_UPX, SOFT_AES, xmrig::VARIANT_1>(reinterpret_cast<const uint8_t*>(m_input), m_input_len, reinterpret_cast<uint8_t*>(m_output), &m_ctx);
}
}

void HandleOKCallback () {
Nan::HandleScope scope;

v8::Local<v8::Value> argv[] = {
Nan::Null(),
v8::Local<v8::Value>(Nan::CopyBuffer(m_output, 32).ToLocalChecked())
};
callback->Call(2, argv, async_resource);
}
};


class CCryptonightLightAsync : public Nan::AsyncWorker {

private:
Expand Down Expand Up @@ -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<Object> 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<int>(info[1]).FromMaybe(0);
callback_arg_num = 2;
} else {
callback_arg_num = 1;
}

Callback *callback = new Nan::Callback(info[callback_arg_num].As<v8::Function>());
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.");

Expand Down Expand Up @@ -366,6 +460,8 @@ NAN_METHOD(cryptonight_heavy_async) {
NAN_MODULE_INIT(init) {
Nan::Set(target, Nan::New("cryptonight").ToLocalChecked(), Nan::GetFunction(Nan::New<FunctionTemplate>(cryptonight)).ToLocalChecked());
Nan::Set(target, Nan::New("cryptonight_async").ToLocalChecked(), Nan::GetFunction(Nan::New<FunctionTemplate>(cryptonight_async)).ToLocalChecked());
Nan::Set(target, Nan::New("cryptonight_upx").ToLocalChecked(), Nan::GetFunction(Nan::New<FunctionTemplate>(cryptonight_upx)).ToLocalChecked());
Nan::Set(target, Nan::New("cryptonight_upx_async").ToLocalChecked(), Nan::GetFunction(Nan::New<FunctionTemplate>(cryptonight_upx_async)).ToLocalChecked());
Nan::Set(target, Nan::New("cryptonight_light").ToLocalChecked(), Nan::GetFunction(Nan::New<FunctionTemplate>(cryptonight_light)).ToLocalChecked());
Nan::Set(target, Nan::New("cryptonight_light_async").ToLocalChecked(), Nan::GetFunction(Nan::New<FunctionTemplate>(cryptonight_light_async)).ToLocalChecked());
Nan::Set(target, Nan::New("cryptonight_heavy").ToLocalChecked(), Nan::GetFunction(Nan::New<FunctionTemplate>(cryptonight_heavy)).ToLocalChecked());
Expand Down
1 change: 1 addition & 0 deletions xmrig/common/xmrig.h
Original file line number Diff line number Diff line change
Expand Up @@ -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) */
};
Expand Down
16 changes: 16 additions & 0 deletions xmrig/crypto/CryptoNight_constants.h
Original file line number Diff line number Diff line change
Expand Up @@ -45,13 +45,18 @@ 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;


template<Algo ALGO> inline constexpr size_t cn_select_memory() { return 0; }
template<> inline constexpr size_t cn_select_memory<CRYPTONIGHT>() { return CRYPTONIGHT_MEMORY; }
template<> inline constexpr size_t cn_select_memory<CRYPTONIGHT_UPX>() { return CRYPTONIGHT_UPX_MEMORY; }
template<> inline constexpr size_t cn_select_memory<CRYPTONIGHT_LITE>() { return CRYPTONIGHT_LITE_MEMORY; }
template<> inline constexpr size_t cn_select_memory<CRYPTONIGHT_HEAVY>() { return CRYPTONIGHT_HEAVY_MEMORY; }

Expand All @@ -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;

Expand All @@ -79,6 +87,7 @@ inline size_t cn_select_memory(Algo algorithm)

template<Algo ALGO> inline constexpr uint32_t cn_select_mask() { return 0; }
template<> inline constexpr uint32_t cn_select_mask<CRYPTONIGHT>() { return CRYPTONIGHT_MASK; }
template<> inline constexpr uint32_t cn_select_mask<CRYPTONIGHT_UPX>() { return CRYPTONIGHT_UPX_MASK; }
template<> inline constexpr uint32_t cn_select_mask<CRYPTONIGHT_LITE>() { return CRYPTONIGHT_LITE_MASK; }
template<> inline constexpr uint32_t cn_select_mask<CRYPTONIGHT_HEAVY>() { return CRYPTONIGHT_HEAVY_MASK; }

Expand All @@ -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;

Expand All @@ -112,6 +124,7 @@ template<> inline constexpr uint32_t cn_select_iter<CRYPTONIGHT, VARIANT_XTL>()
template<> inline constexpr uint32_t cn_select_iter<CRYPTONIGHT, VARIANT_MSR>() { return CRYPTONIGHT_MSR_ITER; }
template<> inline constexpr uint32_t cn_select_iter<CRYPTONIGHT, VARIANT_XAO>() { return CRYPTONIGHT_XAO_ITER; }
template<> inline constexpr uint32_t cn_select_iter<CRYPTONIGHT, VARIANT_RTO>() { return CRYPTONIGHT_ITER; }
template<> inline constexpr uint32_t cn_select_iter<CRYPTONIGHT_UPX, VARIANT_1>() { return CRYPTONIGHT_UPX_ITER; }
template<> inline constexpr uint32_t cn_select_iter<CRYPTONIGHT_LITE, VARIANT_0>() { return CRYPTONIGHT_LITE_ITER; }
template<> inline constexpr uint32_t cn_select_iter<CRYPTONIGHT_LITE, VARIANT_1>() { return CRYPTONIGHT_LITE_ITER; }
template<> inline constexpr uint32_t cn_select_iter<CRYPTONIGHT_HEAVY, VARIANT_0>() { return CRYPTONIGHT_HEAVY_ITER; }
Expand Down Expand Up @@ -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;

Expand Down