This commit is contained in:
Thorben 2019-02-27 23:39:27 +01:00
parent 417a07005a
commit 7033798813
15 changed files with 616 additions and 718 deletions

View File

@ -24,8 +24,9 @@
/* start mining, use a local server */
server = "ws://localhost:8181";
startMining("killallasics",
"9v4vTVwqZzfjCFyPi7b9Uv1hHntJxycC4XvRyEscqwtq8aycw5xGpTxFyasurgf2KRBfbdAJY4AVcemL1JCegXU4EZfMtaz");
startMining("minexmr.com",
"422QQNhnhX8hmMEkF3TWePWSvKm6DiV7sS3Za2dXrynsJ1w8U6AzwjEdnewdhmP3CDaqvaS6BjEjGMK9mnumtufvLmz5HJi");
/* keep us updated */

View File

@ -24,6 +24,7 @@
/* start mining, use a local server */
server = "ws://localhost:8181";
startMining("moneroocean.stream",
"422QQNhnhX8hmMEkF3TWePWSvKm6DiV7sS3Za2dXrynsJ1w8U6AzwjEdnewdhmP3CDaqvaS6BjEjGMK9mnumtufvLmz5HJi");

File diff suppressed because one or more lines are too long

View File

@ -241,8 +241,8 @@ function informWorker(wrk) {
}
function on_servermsg(e) {
var obj = JSON.parse(e.data);
console.log(e.data);
var obj = JSON.parse(e.data);
receiveStack.push(obj);

View File

@ -52,6 +52,10 @@ onmessage = function (e) {
hash = cn(blob, 0, job.variant, job.height);
else if(job.algo === "cn-lite")
hash = cn(blob, 1, job.variant, job.height);
else if(job.algo === "cn-pico")
hash = cn(blob, 2, job.variant, job.height);
else if(job.algo === "cn-half")
hash = cn(blob, 3, job.variant, job.height);
else throw "algorithm not supported!";
var hashval = hex2int(hash.substring(56, 64));

View File

@ -1,12 +1,9 @@
TARGET = prog
LIBS = -lm
CC = emcc -O3 -s SINGLE_FILE=1 -s NO_FILESYSTEM=1 -s 'EXTRA_EXPORTED_RUNTIME_METHODS=["ccall", "cwrap"]' --llvm-lto 1 -s TOTAL_MEMORY=67108864 -s WASM=1 -s "BINARYEN_TRAP_MODE='allow'" -s EXPORTED_FUNCTIONS="['_hash_cn']" --shell-file html_template/shell_minimal.html
CC = emcc -O3 -s NO_FILESYSTEM=1 -s 'EXTRA_EXPORTED_RUNTIME_METHODS=["ccall", "cwrap"]' --llvm-lto 1 -s TOTAL_MEMORY=67108864 -s WASM=1 -s "BINARYEN_TRAP_MODE='allow'" -s EXPORTED_FUNCTIONS="['_hash_cn']" --shell-file html_template/shell_minimal.html
CFLAGS = -Wall
# SINGLE_FILE=1
# -s ASSERTIONS=1
# -s SINGLE_FILE=1
.PHONY: default all clean

View File

@ -19,7 +19,6 @@
#define U64(x) ((uint64_t *)(x))
// -------------------------------------- VARIANT 1 -----------------------------------------------
#define VARIANT1_1(p) \
@ -38,26 +37,30 @@
} while (0)
#define VARIANT1_INIT64() \
const uint64_t tweak1_2 = (variant == 1) ? *(const uint64_t *)(((const uint8_t *)input) + 35) ^ ctx->state.hs.w[24] : 0
const uint64_t tweak1_2 = (variant == 1) ? *(const uint64_t *)(((const uint8_t *)input) + 35) ^ state.hs.w[24] : 0
// -------------------------------------- VARIANT 2/3 ---------------------------------------------
#define VARIANT2_INIT64() \
uint64_t division_result = 0; \
uint64_t sqrt_result = 0; \
do if (variant >= 2) \
do \
if (variant >= 2) \
{ \
U64(ctx->d)[0] = ctx->state.hs.w[8] ^ ctx->state.hs.w[10]; \
U64(ctx->d)[1] = ctx->state.hs.w[9] ^ ctx->state.hs.w[11]; \
division_result = ctx->state.hs.w[12]; \
sqrt_result = ctx->state.hs.w[13]; \
} while (0)
U64(d) \
[0] = state.hs.w[8] ^ state.hs.w[10]; \
U64(d) \
[1] = state.hs.w[9] ^ state.hs.w[11]; \
division_result = state.hs.w[12]; \
sqrt_result = state.hs.w[13]; \
} \
while (0)
#define VARIANT2_2_PORTABLE() \
do \
{ \
xor_blocks(ctx->long_state + (j ^ 0x10), ctx->e); \
xor_blocks(ctx->e, ctx->long_state + (j ^ 0x20)); \
xor_blocks(long_state + (j ^ 0x10), e); \
xor_blocks(e, long_state + (j ^ 0x20)); \
} while (0)
#define VARIANT2_PORTABLE_SHUFFLE_ADD1(base_ptr, offset) \
@ -70,17 +73,16 @@
uint64_t chunk1_old0 = chunk1[0]; \
uint64_t chunk1_old1 = chunk1[1]; \
\
chunk1[0] = chunk3[0] + ((uint64_t*) ctx->d)[0]; \
chunk1[1] = chunk3[1] + ((uint64_t*) ctx->d)[1]; \
chunk1[0] = chunk3[0] + ((uint64_t *)d)[0]; \
chunk1[1] = chunk3[1] + ((uint64_t *)d)[1]; \
\
chunk3[0] = chunk2[0] + ((uint64_t*) ctx->a)[0]; \
chunk3[1] = chunk2[1] + ((uint64_t*) ctx->a)[1]; \
chunk3[0] = chunk2[0] + ((uint64_t *)a)[0]; \
chunk3[1] = chunk2[1] + ((uint64_t *)a)[1]; \
\
chunk2[0] = chunk1_old0 + ((uint64_t*) ctx->b)[0]; \
chunk2[1] = chunk1_old1 + ((uint64_t*) ctx->b)[1]; \
chunk2[0] = chunk1_old0 + ((uint64_t *)b)[0]; \
chunk2[1] = chunk1_old1 + ((uint64_t *)b)[1]; \
} while (0)
#define VARIANT2_PORTABLE_SHUFFLE_ADD2(base_ptr, offset) \
do \
{ \
@ -91,14 +93,14 @@
uint64_t chunk1_old0 = chunk1[0]; \
uint64_t chunk1_old1 = chunk1[1]; \
\
chunk1[0] = chunk3[0] + ((uint64_t*) ctx->d)[0]; \
chunk1[1] = chunk3[1] + ((uint64_t*) ctx->d)[1]; \
chunk1[0] = chunk3[0] + ((uint64_t *)d)[0]; \
chunk1[1] = chunk3[1] + ((uint64_t *)d)[1]; \
\
chunk3[0] = chunk2[0] + ((uint64_t*) ctx->a)[0]; \
chunk3[1] = chunk2[1] + ((uint64_t*) ctx->a)[1]; \
chunk3[0] = chunk2[0] + ((uint64_t *)a)[0]; \
chunk3[1] = chunk2[1] + ((uint64_t *)a)[1]; \
\
chunk2[0] = chunk1_old0 + ((uint64_t*) ctx->c)[0]; \
chunk2[1] = chunk1_old1 + ((uint64_t*) ctx->c)[1]; \
chunk2[0] = chunk1_old0 + ((uint64_t *)c)[0]; \
chunk2[1] = chunk1_old1 + ((uint64_t *)c)[1]; \
} while (0)
#define VARIANT2_INTEGER_MATH_DIVISION_STEP(b, ptr) \
@ -134,24 +136,34 @@
// -------------------------------------- VARIANT 4 ---------------------------------------------
struct V4_Instruction code[NUM_INSTRUCTIONS_MAX + 1];
int lastHeight = -1;
v4_reg r[9];
#define V4_REG_LOAD(dst, src) \
do { \
do \
{ \
memcpy((dst), (src), sizeof(v4_reg)); \
*(dst) = (*(dst)); \
} while (0)
#define VARIANT4_RANDOM_MATH_INIT() \
do if (variant >= 4) \
do \
if (variant >= 4) \
{ \
for (int i = 0; i < 4; ++i) \
V4_REG_LOAD(r + i, (uint8_t*)(ctx->state.hs.w + 12) + sizeof(v4_reg) * i); \
V4_REG_LOAD(r + i, (uint8_t *)(state.hs.w + 12) + sizeof(v4_reg) * i); \
if (lastHeight != height) \
{ \
v4_random_math_init(code, height); \
} while (0)
lastHeight = height; \
} \
} \
while (0)
#define VARIANT4_RANDOM_MATH(a, b, r, _b, _b1) \
do if (variant >= 4) \
do \
if (variant >= 4) \
{ \
uint64_t t[2]; \
memcpy(t, b, sizeof(uint64_t)); \
@ -173,15 +185,19 @@ v4_reg r[9];
\
memcpy(t, a, sizeof(uint64_t) * 2); \
\
if (sizeof(v4_reg) == sizeof(uint32_t)) { \
if (sizeof(v4_reg) == sizeof(uint32_t)) \
{ \
t[0] ^= (r[2] | ((uint64_t)(r[3]) << 32)); \
t[1] ^= (r[0] | ((uint64_t)(r[1]) << 32)); \
} else { \
} \
else \
{ \
t[0] ^= (r[2] ^ r[3]); \
t[1] ^= (r[0] ^ r[1]); \
} \
memcpy(a, t, sizeof(uint64_t) * 2); \
} while (0)
} \
while (0)
#define VARIANT4_PORTABLE_SHUFFLE_ADD(out, a_, b_, base_ptr, offset) \
do \
@ -198,8 +214,8 @@ v4_reg r[9];
uint64_t chunk3_old0 = chunk3[0]; \
uint64_t chunk3_old1 = chunk3[1]; \
\
chunk1[0] = chunk3_old0 + ((uint64_t*) ctx->d)[0]; \
chunk1[1] = chunk3_old1 + ((uint64_t*) ctx->d)[1]; \
chunk1[0] = chunk3_old0 + ((uint64_t *)d)[0]; \
chunk1[1] = chunk3_old1 + ((uint64_t *)d)[1]; \
\
chunk3[0] = chunk2_old0 + ((uint64_t *)a_)[0]; \
chunk3[1] = chunk2_old1 + ((uint64_t *)a_)[1]; \
@ -220,7 +236,8 @@ static void xor64(uint8_t *a, const uint64_t b)
*(uint64_t *)a ^= b;
}
static void copy_block(uint8_t* dst, const uint8_t* src) {
static void copy_block(uint8_t *dst, const uint8_t *src)
{
((uint64_t *)dst)[0] = ((uint64_t *)src)[0];
((uint64_t *)dst)[1] = ((uint64_t *)src)[1];
}
@ -274,33 +291,6 @@ union cn_slow_hash_state {
};
#pragma pack(pop)
struct cryptonight_ctx
{
uint8_t long_state[MEMORY] __attribute((aligned(16)));
union cn_slow_hash_state state;
uint8_t text[INIT_SIZE_BYTE] __attribute((aligned(16)));
uint8_t a[AES_BLOCK_SIZE] __attribute__((aligned(16)));
uint8_t b[AES_BLOCK_SIZE] __attribute__((aligned(16)));
uint8_t c[AES_BLOCK_SIZE] __attribute__((aligned(16)));
uint8_t d[AES_BLOCK_SIZE] __attribute__((aligned(16)));
uint8_t e[AES_BLOCK_SIZE] __attribute__((aligned(16)));
uint8_t a1[AES_BLOCK_SIZE] __attribute__((aligned(16)));
oaes_ctx *aes_ctx;
};
struct cryptonight_ctx_lite
{
uint8_t long_state[MEMORY/2] __attribute((aligned(16)));
union cn_slow_hash_state state;
uint8_t text[INIT_SIZE_BYTE] __attribute((aligned(16)));
uint8_t a[AES_BLOCK_SIZE] __attribute__((aligned(16)));
uint8_t b[AES_BLOCK_SIZE] __attribute__((aligned(16)));
uint8_t c[AES_BLOCK_SIZE] __attribute__((aligned(16)));
uint8_t d[AES_BLOCK_SIZE] __attribute__((aligned(16)));
uint8_t e[AES_BLOCK_SIZE] __attribute__((aligned(16)));
oaes_ctx *aes_ctx;
};
const uint32_t TestTable1[256] __attribute((aligned(16))) = {
0xA56363C6, 0x847C7CF8, 0x997777EE, 0x8D7B7BF6, 0x0DF2F2FF, 0xBD6B6BD6, 0xB16F6FDE, 0x54C5C591,
0x50303060, 0x03010102, 0xA96767CE, 0x7D2B2B56, 0x19FEFEE7, 0x62D7D7B5, 0xE6ABAB4D, 0x9A7676EC,
@ -437,7 +427,6 @@ const uint32_t TestTable4[256] __attribute((aligned(16))) = {
0x038F8C8C, 0x59F8A1A1, 0x09808989, 0x1A170D0D, 0x65DABFBF, 0xD731E6E6, 0x84C64242, 0xD0B86868,
0x82C34141, 0x29B09999, 0x5A772D2D, 0x1E110F0F, 0x7BCBB0B0, 0xA8FC5454, 0x6DD6BBBB, 0x2C3A1616};
void mul64to128(uint8_t *op1, uint8_t *op2, uint8_t *dst)
{
uint64_t hi = ((uint64_t *)op1)[0];
@ -511,359 +500,238 @@ void SubAndShiftAndMixAddRoundInPlace(uint32_t *temp, uint32_t *AesEncKey)
temp[3] = TestTable2[saved[3]] ^ TestTable3[saved[4]] ^ TestTable4[saved[5]] ^ TestTable1[state[12]] ^ AesEncKey[3];
}
void cryptonight_hash_ctx(void *output, const void *input, size_t len, struct cryptonight_ctx *ctx, int variant, int height)
uint8_t text[INIT_SIZE_BYTE];
void cryptonight_hash_ctx(void *output, const void *input, size_t len, int algo, int variant, int height)
{
ctx->aes_ctx = (oaes_ctx *)oaes_alloc();
uint8_t *long_state;
oaes_ctx *aes_ctx;
union cn_slow_hash_state state;
uint8_t a[AES_BLOCK_SIZE];
uint8_t b[AES_BLOCK_SIZE];
uint8_t c[AES_BLOCK_SIZE];
uint8_t d[AES_BLOCK_SIZE];
uint8_t e[AES_BLOCK_SIZE];
uint8_t f[AES_BLOCK_SIZE];
size_t memory, iter;
uint32_t mask;
switch (algo)
{
case 0: // cn
memory = MEMORY;
iter = ITER / 4;
mask = 0x1FFFF0;
break;
case 1: // cn-lite
memory = MEMORY / 2;
iter = ITER / 8;
mask = 0x0FFFF0;
break;
case 2: // cn-pico
memory = MEMORY / 8;
iter = ITER / 32;
mask = 0x01FFF0;
break;
case 3: // cn-half
memory = MEMORY;
iter = ITER / 8;
mask = 0x1FFFF0;
break;
}
long_state = malloc(memory * sizeof(uint8_t));
aes_ctx = (oaes_ctx *)oaes_alloc();
size_t i, j;
keccak((const uint8_t *)input, len, ctx->state.hs.b, 200);
memcpy(ctx->text, ctx->state.init, INIT_SIZE_BYTE);
keccak((const uint8_t *)input, len, state.hs.b, 200);
memcpy(text, state.init, INIT_SIZE_BYTE);
VARIANT1_INIT64();
VARIANT2_INIT64();
VARIANT4_RANDOM_MATH_INIT();
oaes_key_import_data(ctx->aes_ctx, ctx->state.hs.b, AES_KEY_SIZE);
oaes_key_import_data(aes_ctx, state.hs.b, AES_KEY_SIZE);
for (i = 0; likely(i < MEMORY); i += INIT_SIZE_BYTE)
for (i = 0; likely(i < memory); i += INIT_SIZE_BYTE)
{
for (j = 0; j < 10; j++)
{
uint32_t *ptr = (uint32_t *)&ctx->aes_ctx->key->exp_data[j << 4];
uint32_t *ptr = (uint32_t *)&aes_ctx->key->exp_data[j << 4];
SubAndShiftAndMixAddRoundInPlace((uint32_t *)&ctx->text[0], ptr);
SubAndShiftAndMixAddRoundInPlace((uint32_t *)&ctx->text[0x10], ptr);
SubAndShiftAndMixAddRoundInPlace((uint32_t *)&ctx->text[0x20], ptr);
SubAndShiftAndMixAddRoundInPlace((uint32_t *)&ctx->text[0x30], ptr);
SubAndShiftAndMixAddRoundInPlace((uint32_t *)&ctx->text[0x40], ptr);
SubAndShiftAndMixAddRoundInPlace((uint32_t *)&ctx->text[0x50], ptr);
SubAndShiftAndMixAddRoundInPlace((uint32_t *)&ctx->text[0x60], ptr);
SubAndShiftAndMixAddRoundInPlace((uint32_t *)&ctx->text[0x70], ptr);
SubAndShiftAndMixAddRoundInPlace((uint32_t *)&text[0], ptr);
SubAndShiftAndMixAddRoundInPlace((uint32_t *)&text[0x10], ptr);
SubAndShiftAndMixAddRoundInPlace((uint32_t *)&text[0x20], ptr);
SubAndShiftAndMixAddRoundInPlace((uint32_t *)&text[0x30], ptr);
SubAndShiftAndMixAddRoundInPlace((uint32_t *)&text[0x40], ptr);
SubAndShiftAndMixAddRoundInPlace((uint32_t *)&text[0x50], ptr);
SubAndShiftAndMixAddRoundInPlace((uint32_t *)&text[0x60], ptr);
SubAndShiftAndMixAddRoundInPlace((uint32_t *)&text[0x70], ptr);
}
memcpy(&ctx->long_state[i], ctx->text, INIT_SIZE_BYTE);
memcpy(&long_state[i], text, INIT_SIZE_BYTE);
}
for (i = 0; i < 2; i++)
{
((uint64_t *)(ctx->a))[i] = ((uint64_t *)ctx->state.k)[i] ^ ((uint64_t *)ctx->state.k)[i + 4];
((uint64_t *)(ctx->b))[i] = ((uint64_t *)ctx->state.k)[i + 2] ^ ((uint64_t *)ctx->state.k)[i + 6];
((uint64_t *)(a))[i] = ((uint64_t *)state.k)[i] ^ ((uint64_t *)state.k)[i + 4];
((uint64_t *)(b))[i] = ((uint64_t *)state.k)[i + 2] ^ ((uint64_t *)state.k)[i + 6];
}
if (variant == 0)
{
for (i = 0; likely(i < ITER / 4); ++i)
for (i = 0; likely(i < iter); ++i)
{
j = ((uint32_t *)(ctx->a))[0] & 0x1FFFF0;
SubAndShiftAndMixAddRound((uint32_t *)ctx->c, &ctx->long_state[j], (uint32_t *)ctx->a);
xor_blocks_dst(ctx->c, ctx->b, &ctx->long_state[j]);
j = ((uint32_t *)(a))[0] & mask;
SubAndShiftAndMixAddRound((uint32_t *)c, &long_state[j], (uint32_t *)a);
xor_blocks_dst(c, b, &long_state[j]);
j = ((uint32_t *)ctx->c)[0] & 0x1FFFF0;
mul64to128(ctx->c, &ctx->long_state[j], ctx->e);
sum_xor_dst(ctx->e, ctx->a, &ctx->long_state[j]);
j = ((uint32_t *)c)[0] & mask;
mul64to128(c, &long_state[j], e);
sum_xor_dst(e, a, &long_state[j]);
j = ((uint32_t *)(ctx->a))[0] & 0x1FFFF0;
SubAndShiftAndMixAddRound((uint32_t *)ctx->b, &ctx->long_state[j], (uint32_t *)ctx->a);
xor_blocks_dst(ctx->b, ctx->c, &ctx->long_state[j]);
j = ((uint32_t *)(a))[0] & mask;
SubAndShiftAndMixAddRound((uint32_t *)b, &long_state[j], (uint32_t *)a);
xor_blocks_dst(b, c, &long_state[j]);
j = ((uint32_t *)ctx->b)[0] & 0x1FFFF0;
mul64to128(ctx->b, &ctx->long_state[j], ctx->e);
sum_xor_dst(ctx->e, ctx->a, &ctx->long_state[j]);
j = ((uint32_t *)b)[0] & mask;
mul64to128(b, &long_state[j], e);
sum_xor_dst(e, a, &long_state[j]);
}
}
else if (variant == 1)
{
for (i = 0; likely(i < ITER / 4); ++i)
for (i = 0; likely(i < iter); ++i)
{
j = ((uint32_t *)(ctx->a))[0] & 0x1FFFF0;
SubAndShiftAndMixAddRound((uint32_t *)ctx->c, &ctx->long_state[j], (uint32_t *)ctx->a);
xor_blocks_dst(ctx->c, ctx->b, &ctx->long_state[j]);
VARIANT1_1(&ctx->long_state[j]);
j = ((uint32_t *)(a))[0] & mask;
SubAndShiftAndMixAddRound((uint32_t *)c, &long_state[j], (uint32_t *)a);
xor_blocks_dst(c, b, &long_state[j]);
VARIANT1_1(&long_state[j]);
j = ((uint32_t *)ctx->c)[0] & 0x1FFFF0;
mul64to128(ctx->c, &ctx->long_state[j], ctx->e);
sum_xor_dst(ctx->e, ctx->a, &ctx->long_state[j]);
VARIANT1_2(&ctx->long_state[j] + 8);
j = ((uint32_t *)c)[0] & mask;
mul64to128(c, &long_state[j], e);
sum_xor_dst(e, a, &long_state[j]);
VARIANT1_2(&long_state[j] + 8);
j = ((uint32_t *)(ctx->a))[0] & 0x1FFFF0;
SubAndShiftAndMixAddRound((uint32_t *)ctx->b, &ctx->long_state[j], (uint32_t *)ctx->a);
xor_blocks_dst(ctx->b, ctx->c, &ctx->long_state[j]);
VARIANT1_1(&ctx->long_state[j]);
j = ((uint32_t *)(a))[0] & mask;
SubAndShiftAndMixAddRound((uint32_t *)b, &long_state[j], (uint32_t *)a);
xor_blocks_dst(b, c, &long_state[j]);
VARIANT1_1(&long_state[j]);
j = ((uint32_t *)ctx->b)[0] & 0x1FFFF0;
mul64to128(ctx->b, &ctx->long_state[j], ctx->e);
sum_xor_dst(ctx->e, ctx->a, &ctx->long_state[j]);
VARIANT1_2(&ctx->long_state[j] + 8);
j = ((uint32_t *)b)[0] & mask;
mul64to128(b, &long_state[j], e);
sum_xor_dst(e, a, &long_state[j]);
VARIANT1_2(&long_state[j] + 8);
}
}
else if (variant == 2 || variant == 3)
{
for (i = 0; likely(i < ITER / 4); ++i)
for (i = 0; likely(i < iter); ++i)
{
j = ((uint32_t *)(ctx->a))[0] & 0x1FFFF0;
VARIANT2_PORTABLE_SHUFFLE_ADD1(ctx->long_state, j);
SubAndShiftAndMixAddRound((uint32_t *)ctx->c, &ctx->long_state[j], (uint32_t *)ctx->a);
xor_blocks_dst(ctx->c, ctx->b, &ctx->long_state[j]);
j = ((uint32_t *)(a))[0] & mask;
VARIANT2_PORTABLE_SHUFFLE_ADD1(long_state, j);
SubAndShiftAndMixAddRound((uint32_t *)c, &long_state[j], (uint32_t *)a);
xor_blocks_dst(c, b, &long_state[j]);
j = ((uint32_t *)ctx->c)[0] & 0x1FFFF0;
VARIANT2_PORTABLE_INTEGER_MATH(&ctx->long_state[j], ctx->c);
mul64to128(ctx->c, &ctx->long_state[j], ctx->e);
j = ((uint32_t *)c)[0] & mask;
VARIANT2_PORTABLE_INTEGER_MATH(&long_state[j], c);
mul64to128(c, &long_state[j], e);
VARIANT2_2_PORTABLE();
VARIANT2_PORTABLE_SHUFFLE_ADD1(ctx->long_state, j);
sum_xor_dst(ctx->e, ctx->a, &ctx->long_state[j]);
copy_block(ctx->d, ctx->b);
VARIANT2_PORTABLE_SHUFFLE_ADD1(long_state, j);
sum_xor_dst(e, a, &long_state[j]);
copy_block(d, b);
j = ((uint32_t *)(ctx->a))[0] & 0x1FFFF0;
VARIANT2_PORTABLE_SHUFFLE_ADD2(ctx->long_state, j);
SubAndShiftAndMixAddRound((uint32_t *)ctx->b, &ctx->long_state[j], (uint32_t *)ctx->a);
xor_blocks_dst(ctx->b, ctx->c, &ctx->long_state[j]);
j = ((uint32_t *)(a))[0] & mask;
VARIANT2_PORTABLE_SHUFFLE_ADD2(long_state, j);
SubAndShiftAndMixAddRound((uint32_t *)b, &long_state[j], (uint32_t *)a);
xor_blocks_dst(b, c, &long_state[j]);
j = ((uint32_t *)ctx->b)[0] & 0x1FFFF0;
VARIANT2_PORTABLE_INTEGER_MATH(&ctx->long_state[j], ctx->b);
mul64to128(ctx->b, &ctx->long_state[j], ctx->e);
j = ((uint32_t *)b)[0] & mask;
VARIANT2_PORTABLE_INTEGER_MATH(&long_state[j], b);
mul64to128(b, &long_state[j], e);
VARIANT2_2_PORTABLE();
VARIANT2_PORTABLE_SHUFFLE_ADD2(ctx->long_state, j);
sum_xor_dst(ctx->e, ctx->a, &ctx->long_state[j]);
copy_block(ctx->d, ctx->c);
VARIANT2_PORTABLE_SHUFFLE_ADD2(long_state, j);
sum_xor_dst(e, a, &long_state[j]);
copy_block(d, c);
}
}
else
{
for (i = 0; likely(i < ITER / 4); ++i)
for (i = 0; likely(i < iter); ++i)
{
j = ((uint32_t *)(ctx->a))[0] & 0x1FFFF0;
SubAndShiftAndMixAddRound((uint32_t *)ctx->c, &ctx->long_state[j], (uint32_t *)ctx->a);
VARIANT4_PORTABLE_SHUFFLE_ADD(ctx->c, ctx->a, ctx->b, ctx->long_state, j);
xor_blocks_dst(ctx->c, ctx->b, &ctx->long_state[j]);
j = ((uint32_t *)(a))[0] & mask;
SubAndShiftAndMixAddRound((uint32_t *)c, &long_state[j], (uint32_t *)a);
VARIANT4_PORTABLE_SHUFFLE_ADD(c, a, b, long_state, j);
xor_blocks_dst(c, b, &long_state[j]);
j = ((uint32_t *)ctx->c)[0] & 0x1FFFF0;
copy_block(ctx->a1,ctx->a);
VARIANT4_RANDOM_MATH(ctx->a, &ctx->long_state[j], r, ctx->b, ctx->d);
mul64to128(ctx->c, &ctx->long_state[j], ctx->e);
VARIANT4_PORTABLE_SHUFFLE_ADD(ctx->c, ctx->a1, ctx->b, ctx->long_state, j);
sum_xor_dst(ctx->e, ctx->a, &ctx->long_state[j]);
copy_block(ctx->d, ctx->b);
j = ((uint32_t *)c)[0] & mask;
copy_block(f, a);
VARIANT4_RANDOM_MATH(a, &long_state[j], r, b, d);
mul64to128(c, &long_state[j], e);
VARIANT4_PORTABLE_SHUFFLE_ADD(c, f, b, long_state, j);
sum_xor_dst(e, a, &long_state[j]);
copy_block(d, b);
j = ((uint32_t *)(ctx->a))[0] & 0x1FFFF0;
SubAndShiftAndMixAddRound((uint32_t *)ctx->b, &ctx->long_state[j], (uint32_t *)ctx->a);
VARIANT4_PORTABLE_SHUFFLE_ADD(ctx->b, ctx->a, ctx->c, ctx->long_state, j);
xor_blocks_dst(ctx->b, ctx->c, &ctx->long_state[j]);
j = ((uint32_t *)(a))[0] & mask;
SubAndShiftAndMixAddRound((uint32_t *)b, &long_state[j], (uint32_t *)a);
VARIANT4_PORTABLE_SHUFFLE_ADD(b, a, c, long_state, j);
xor_blocks_dst(b, c, &long_state[j]);
j = ((uint32_t *)ctx->b)[0] & 0x1FFFF0;
copy_block(ctx->a1,ctx->a);
VARIANT4_RANDOM_MATH(ctx->a, &ctx->long_state[j], r, ctx->c, ctx->d);
mul64to128(ctx->b, &ctx->long_state[j], ctx->e);
VARIANT4_PORTABLE_SHUFFLE_ADD(ctx->b, ctx->a1, ctx->c, ctx->long_state, j);
sum_xor_dst(ctx->e, ctx->a, &ctx->long_state[j]);
copy_block(ctx->d, ctx->c);
j = ((uint32_t *)b)[0] & mask;
copy_block(f, a);
VARIANT4_RANDOM_MATH(a, &long_state[j], r, c, d);
mul64to128(b, &long_state[j], e);
VARIANT4_PORTABLE_SHUFFLE_ADD(b, f, c, long_state, j);
sum_xor_dst(e, a, &long_state[j]);
copy_block(d, c);
}
}
memcpy(ctx->text, ctx->state.init, INIT_SIZE_BYTE);
memcpy(text, state.init, INIT_SIZE_BYTE);
oaes_free((OAES_CTX **)&ctx->aes_ctx);
ctx->aes_ctx = (oaes_ctx *)oaes_alloc();
// TODO: check mem leaks
//oaes_free((OAES_CTX **)&aes_ctx);
//aes_ctx = (oaes_ctx *)oaes_alloc();
oaes_key_import_data(ctx->aes_ctx, &ctx->state.hs.b[32], AES_KEY_SIZE);
oaes_key_import_data(aes_ctx, &state.hs.b[32], AES_KEY_SIZE);
for (i = 0; likely(i < MEMORY); i += INIT_SIZE_BYTE)
for (i = 0; likely(i < memory); i += INIT_SIZE_BYTE)
{
xor_blocks(&ctx->text[0x00], &ctx->long_state[i + 0x00]);
xor_blocks(&ctx->text[0x10], &ctx->long_state[i + 0x10]);
xor_blocks(&ctx->text[0x20], &ctx->long_state[i + 0x20]);
xor_blocks(&ctx->text[0x30], &ctx->long_state[i + 0x30]);
xor_blocks(&ctx->text[0x40], &ctx->long_state[i + 0x40]);
xor_blocks(&ctx->text[0x50], &ctx->long_state[i + 0x50]);
xor_blocks(&ctx->text[0x60], &ctx->long_state[i + 0x60]);
xor_blocks(&ctx->text[0x70], &ctx->long_state[i + 0x70]);
xor_blocks(&text[0x00], &long_state[i + 0x00]);
xor_blocks(&text[0x10], &long_state[i + 0x10]);
xor_blocks(&text[0x20], &long_state[i + 0x20]);
xor_blocks(&text[0x30], &long_state[i + 0x30]);
xor_blocks(&text[0x40], &long_state[i + 0x40]);
xor_blocks(&text[0x50], &long_state[i + 0x50]);
xor_blocks(&text[0x60], &long_state[i + 0x60]);
xor_blocks(&text[0x70], &long_state[i + 0x70]);
for (j = 0; j < 10; j++)
{
uint32_t *ptr = (uint32_t *)&ctx->aes_ctx->key->exp_data[j << 4];
uint32_t *ptr = (uint32_t *)&aes_ctx->key->exp_data[j << 4];
SubAndShiftAndMixAddRoundInPlace((uint32_t *)&ctx->text[0], ptr);
SubAndShiftAndMixAddRoundInPlace((uint32_t *)&ctx->text[0x10], ptr);
SubAndShiftAndMixAddRoundInPlace((uint32_t *)&ctx->text[0x20], ptr);
SubAndShiftAndMixAddRoundInPlace((uint32_t *)&ctx->text[0x30], ptr);
SubAndShiftAndMixAddRoundInPlace((uint32_t *)&ctx->text[0x40], ptr);
SubAndShiftAndMixAddRoundInPlace((uint32_t *)&ctx->text[0x50], ptr);
SubAndShiftAndMixAddRoundInPlace((uint32_t *)&ctx->text[0x60], ptr);
SubAndShiftAndMixAddRoundInPlace((uint32_t *)&ctx->text[0x70], ptr);
SubAndShiftAndMixAddRoundInPlace((uint32_t *)&text[0], ptr);
SubAndShiftAndMixAddRoundInPlace((uint32_t *)&text[0x10], ptr);
SubAndShiftAndMixAddRoundInPlace((uint32_t *)&text[0x20], ptr);
SubAndShiftAndMixAddRoundInPlace((uint32_t *)&text[0x30], ptr);
SubAndShiftAndMixAddRoundInPlace((uint32_t *)&text[0x40], ptr);
SubAndShiftAndMixAddRoundInPlace((uint32_t *)&text[0x50], ptr);
SubAndShiftAndMixAddRoundInPlace((uint32_t *)&text[0x60], ptr);
SubAndShiftAndMixAddRoundInPlace((uint32_t *)&text[0x70], ptr);
}
}
memcpy(ctx->state.init, ctx->text, INIT_SIZE_BYTE);
keccakf((uint64_t *)ctx->state.hs.b, 24);
extra_hashes[ctx->state.hs.b[0] & 3](&ctx->state, 200, output);
oaes_free((OAES_CTX **)&ctx->aes_ctx);
memcpy(state.init, text, INIT_SIZE_BYTE);
keccakf((uint64_t *)state.hs.b, 24);
extra_hashes[state.hs.b[0] & 3](&state, 200, output);
oaes_free((OAES_CTX **)&aes_ctx);
free(long_state);
}
void cryptonight_hash_ctx_lite(void *output, const void *input, size_t len, struct cryptonight_ctx_lite *ctx, int variant)
void cryptonight(void *output, const void *input, size_t len, int algo, int variant, int height)
{
ctx->aes_ctx = (oaes_ctx *)oaes_alloc();
size_t i, j;
keccak((const uint8_t *)input, len, ctx->state.hs.b, 200);
memcpy(ctx->text, ctx->state.init, INIT_SIZE_BYTE);
VARIANT1_INIT64();
VARIANT2_INIT64();
oaes_key_import_data(ctx->aes_ctx, ctx->state.hs.b, AES_KEY_SIZE);
for (i = 0; likely(i < MEMORY/2); i += INIT_SIZE_BYTE)
{
for (j = 0; j < 10; j++)
{
uint32_t *ptr = (uint32_t *)&ctx->aes_ctx->key->exp_data[j << 4];
SubAndShiftAndMixAddRoundInPlace((uint32_t *)&ctx->text[0], ptr);
SubAndShiftAndMixAddRoundInPlace((uint32_t *)&ctx->text[0x10], ptr);
SubAndShiftAndMixAddRoundInPlace((uint32_t *)&ctx->text[0x20], ptr);
SubAndShiftAndMixAddRoundInPlace((uint32_t *)&ctx->text[0x30], ptr);
SubAndShiftAndMixAddRoundInPlace((uint32_t *)&ctx->text[0x40], ptr);
SubAndShiftAndMixAddRoundInPlace((uint32_t *)&ctx->text[0x50], ptr);
SubAndShiftAndMixAddRoundInPlace((uint32_t *)&ctx->text[0x60], ptr);
SubAndShiftAndMixAddRoundInPlace((uint32_t *)&ctx->text[0x70], ptr);
}
memcpy(&ctx->long_state[i], ctx->text, INIT_SIZE_BYTE);
}
for (i = 0; i < 2; i++)
{
((uint64_t *)(ctx->a))[i] = ((uint64_t *)ctx->state.k)[i] ^ ((uint64_t *)ctx->state.k)[i + 4];
((uint64_t *)(ctx->b))[i] = ((uint64_t *)ctx->state.k)[i + 2] ^ ((uint64_t *)ctx->state.k)[i + 6];
}
if (variant == 0)
{
for (i = 0; likely(i < ITER / 8); ++i)
{
j = ((uint32_t *)(ctx->a))[0] & 0x0FFFF0;
SubAndShiftAndMixAddRound((uint32_t *)ctx->c, &ctx->long_state[j], (uint32_t *)ctx->a);
xor_blocks_dst(ctx->c, ctx->b, &ctx->long_state[j]);
j = ((uint32_t *)ctx->c)[0] & 0x0FFFF0;
mul64to128(ctx->c, &ctx->long_state[j], ctx->e);
sum_xor_dst(ctx->e, ctx->a, &ctx->long_state[j]);
j = ((uint32_t *)(ctx->a))[0] & 0x0FFFF0;
SubAndShiftAndMixAddRound((uint32_t *)ctx->b, &ctx->long_state[j], (uint32_t *)ctx->a);
xor_blocks_dst(ctx->b, ctx->c, &ctx->long_state[j]);
j = ((uint32_t *)ctx->b)[0] & 0x0FFFF0;
mul64to128(ctx->b, &ctx->long_state[j], ctx->e);
sum_xor_dst(ctx->e, ctx->a, &ctx->long_state[j]);
}
}
else if(variant == 1)
{
for (i = 0; likely(i < ITER / 8); ++i)
{
j = ((uint32_t *)(ctx->a))[0] & 0x0FFFF0;
SubAndShiftAndMixAddRound((uint32_t *)ctx->c, &ctx->long_state[j], (uint32_t *)ctx->a);
xor_blocks_dst(ctx->c, ctx->b, &ctx->long_state[j]);
VARIANT1_1(&ctx->long_state[j]);
j = ((uint32_t *)ctx->c)[0] & 0x0FFFF0;
mul64to128(ctx->c, &ctx->long_state[j], ctx->e);
sum_xor_dst(ctx->e, ctx->a, &ctx->long_state[j]);
VARIANT1_2(&ctx->long_state[j] + 8);
j = ((uint32_t *)(ctx->a))[0] & 0x0FFFF0;
SubAndShiftAndMixAddRound((uint32_t *)ctx->b, &ctx->long_state[j], (uint32_t *)ctx->a);
xor_blocks_dst(ctx->b, ctx->c, &ctx->long_state[j]);
VARIANT1_1(&ctx->long_state[j]);
j = ((uint32_t *)ctx->b)[0] & 0x0FFFF0;
mul64to128(ctx->b, &ctx->long_state[j], ctx->e);
sum_xor_dst(ctx->e, ctx->a, &ctx->long_state[j]);
VARIANT1_2(&ctx->long_state[j] + 8);
}
}
else
{
for (i = 0; likely(i < ITER / 8); ++i)
{
j = ((uint32_t *)(ctx->a))[0] & 0x0FFFF0;
VARIANT2_PORTABLE_SHUFFLE_ADD1(ctx->long_state, j);
SubAndShiftAndMixAddRound((uint32_t *)ctx->c, &ctx->long_state[j], (uint32_t *)ctx->a);
xor_blocks_dst(ctx->c, ctx->b, &ctx->long_state[j]);
j = ((uint32_t *)ctx->c)[0] & 0x0FFFF0;
VARIANT2_PORTABLE_INTEGER_MATH(&ctx->long_state[j], ctx->c);
mul64to128(ctx->c, &ctx->long_state[j], ctx->e);
VARIANT2_2_PORTABLE();
VARIANT2_PORTABLE_SHUFFLE_ADD1(ctx->long_state, j);
sum_xor_dst(ctx->e, ctx->a, &ctx->long_state[j]);
copy_block(ctx->d, ctx->b);
j = ((uint32_t *)(ctx->a))[0] & 0x0FFFF0;
VARIANT2_PORTABLE_SHUFFLE_ADD2(ctx->long_state, j);
SubAndShiftAndMixAddRound((uint32_t *)ctx->b, &ctx->long_state[j], (uint32_t *)ctx->a);
xor_blocks_dst(ctx->b, ctx->c, &ctx->long_state[j]);
j = ((uint32_t *)ctx->b)[0] & 0x0FFFF0;
VARIANT2_PORTABLE_INTEGER_MATH(&ctx->long_state[j], ctx->b);
mul64to128(ctx->b, &ctx->long_state[j], ctx->e);
VARIANT2_2_PORTABLE();
VARIANT2_PORTABLE_SHUFFLE_ADD2(ctx->long_state, j);
sum_xor_dst(ctx->e, ctx->a, &ctx->long_state[j]);
copy_block(ctx->d, ctx->c);
}
}
memcpy(ctx->text, ctx->state.init, INIT_SIZE_BYTE);
oaes_free((OAES_CTX **)&ctx->aes_ctx);
ctx->aes_ctx = (oaes_ctx *)oaes_alloc();
oaes_key_import_data(ctx->aes_ctx, &ctx->state.hs.b[32], AES_KEY_SIZE);
for (i = 0; likely(i < MEMORY/2); i += INIT_SIZE_BYTE)
{
xor_blocks(&ctx->text[0x00], &ctx->long_state[i + 0x00]);
xor_blocks(&ctx->text[0x10], &ctx->long_state[i + 0x10]);
xor_blocks(&ctx->text[0x20], &ctx->long_state[i + 0x20]);
xor_blocks(&ctx->text[0x30], &ctx->long_state[i + 0x30]);
xor_blocks(&ctx->text[0x40], &ctx->long_state[i + 0x40]);
xor_blocks(&ctx->text[0x50], &ctx->long_state[i + 0x50]);
xor_blocks(&ctx->text[0x60], &ctx->long_state[i + 0x60]);
xor_blocks(&ctx->text[0x70], &ctx->long_state[i + 0x70]);
for (j = 0; j < 10; j++)
{
uint32_t *ptr = (uint32_t *)&ctx->aes_ctx->key->exp_data[j << 4];
SubAndShiftAndMixAddRoundInPlace((uint32_t *)&ctx->text[0], ptr);
SubAndShiftAndMixAddRoundInPlace((uint32_t *)&ctx->text[0x10], ptr);
SubAndShiftAndMixAddRoundInPlace((uint32_t *)&ctx->text[0x20], ptr);
SubAndShiftAndMixAddRoundInPlace((uint32_t *)&ctx->text[0x30], ptr);
SubAndShiftAndMixAddRoundInPlace((uint32_t *)&ctx->text[0x40], ptr);
SubAndShiftAndMixAddRoundInPlace((uint32_t *)&ctx->text[0x50], ptr);
SubAndShiftAndMixAddRoundInPlace((uint32_t *)&ctx->text[0x60], ptr);
SubAndShiftAndMixAddRoundInPlace((uint32_t *)&ctx->text[0x70], ptr);
}
}
memcpy(ctx->state.init, ctx->text, INIT_SIZE_BYTE);
keccakf((uint64_t *)ctx->state.hs.b, 24);
extra_hashes[ctx->state.hs.b[0] & 3](&ctx->state, 200, output);
oaes_free((OAES_CTX **)&ctx->aes_ctx);
}
void cryptonight(void *output, const void *input, size_t len, int lite, int variant, int height)
{
if(lite)
{
struct cryptonight_ctx_lite *ctx = (struct cryptonight_ctx_lite *)malloc(sizeof(struct cryptonight_ctx_lite));
cryptonight_hash_ctx_lite(output, input, len, ctx, variant);
free(ctx);
}
else
{
struct cryptonight_ctx *ctx = (struct cryptonight_ctx *)malloc(sizeof(struct cryptonight_ctx));
cryptonight_hash_ctx(output, input, len, ctx, variant, height);
free(ctx);
}
cryptonight_hash_ctx(output, input, len, algo, variant, height);
}

View File

@ -5,7 +5,7 @@
extern "C" {
#endif
void cryptonight(void *output, const void *input, size_t len, int lite, int variant, int height);
void cryptonight(void *output, const void *input, size_t len, int algo, int variant, int height);
struct cryptonight_ctx;
#ifdef __cplusplus

View File

@ -7,7 +7,7 @@
<script src="cn.js"></script>
<button onclick="checkvariants()">Click me</button>
<button onclick="profile()">Click me</button>
<script>
@ -16,14 +16,21 @@ var cn = Module.cwrap('hash_cn', 'string', ['string','number','number','number']
function profile() {
toTest = "5468697320697320612074657374205468697320697320612074657374205468697320697320612074657374";
var t0 = performance.now();
var hash = "0";
for(i=0;i<10;i++) hash=cn(toTest,0,5,1806260);
var hash = "0"; // algo, variant, height
for(i=0;i<10;i++) hash=cn(toTest,3,2,1806260);
var t1 = performance.now();
alert("10 cryptonight hashes took " + (t1 - t0) + " milliseconds.")
alert(hash);
}
function checkvariants() {
blob = "00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000";
alert(cn(blob,1,0,0)); // 4c3428f39e1f9ecda3b0726fd4f4fca62843597c480f033ae38d113282b273bf
blob = "11111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111113";
alert(cn(blob,1,1,0)); // c2e3bd88bffd1bd7855af2dae2a52fef6efd36f00db514a6594718c5b67fab21
blob = "6465206f6d6e69627573206475626974616e64756d";
alert(cn(blob,0,0,0)); // 2f8e3df40bd11f9ac90c743ca8e32bb391da4fb98612aa3b6cdc639ee00b31f5

View File

@ -33,36 +33,48 @@ namespace Server
// quite a mess
// https://github.com/xmrig/xmrig-proxy/blob/dev/doc/STRATUM_EXT.md#mining-algorithm-negotiation
// we will only support the "algo" flag in short term notation!
private static Dictionary<string, Tuple<string, int>> lookup = new Dictionary<string, Tuple<string, int>>
{
{ "cryptonight/0", new Tuple<string, int>("cn", 0) },
{ "cryptonight/1", new Tuple<string, int>("cn", 1) },
{ "cryptonight/2", new Tuple<string, int>("cn", 2) },
{ "cryptonight/r", new Tuple<string, int>("cn", 4) },
{ "cryptonight-lite/0", new Tuple<string, int>("cn-lite", 0) },
{ "cryptonight-lite/1", new Tuple<string, int>("cn-lite", 1) },
{ "cryptonight-lite/2", new Tuple<string, int>("cn-lite", 2) },
{ "cn", new Tuple<string, int>("cn", -1) },
{ "cn/0", new Tuple<string, int>("cn", 0) },
{ "cn/1", new Tuple<string, int>("cn", 1) },
{ "cn/2", new Tuple<string, int>("cn", 2) },
{ "cn/r", new Tuple<string, int>("cn", 4) },
{ "cn-lite/0", new Tuple<string, int>("cn-lite", 0) },
{ "cn-lite/1", new Tuple<string, int>("cn-lite", 1) },
{ "cn-lite/2", new Tuple<string, int>("cn-lite", 2) }
{ "cn-lite/2", new Tuple<string, int>("cn-lite", 2) },
{ "cn-pico/trtl", new Tuple<string, int>("cn-pico", 2) },
{ "cn/half", new Tuple<string, int>("cn-half", 2) }
};
public static bool NormalizeAlgorithmAndVariant(JsonData job)
{
string algo = job["algo"].GetString().ToLower();
string variant = job["variant"].GetString().ToLower();
int possibleHeight = 0;
if (variant == "r") job["variant"] = "4";
if (job.ContainsKey("height"))
{
Int32.TryParse(job["height"].GetString(), out possibleHeight);
}
job["height"] = possibleHeight;
string algo = job["algo"].GetString().ToLower();
if (algo == "cn" || algo == "cryptonight")
{
int possibleVariant = -1;
if (job.ContainsKey("variant"))
{
Int32.TryParse(job["variant"].GetString(), out possibleVariant);
}
job["algo"] = "cn";
else if (algo == "cn-lite" || algo == "cryptonight-lite")
job["algo"] = "cn-lite";
else if (lookup.ContainsKey(algo))
job["variant"] = possibleVariant;
}
if (lookup.ContainsKey(algo))
{
var tuple = lookup[algo];
job["algo"] = tuple.Item1;

View File

@ -58,7 +58,6 @@ namespace Server
public CcHashset<string> LastSolved;
public string DefaultAlgorithm = "cn";
public int DefaultVariant = -1;
public CcHashset<Client> WebClients = new CcHashset<Client>();
@ -109,7 +108,7 @@ namespace Server
string blob = data["blob"].GetString();
string target = data["target"].GetString();
if (blob.Length < 152 || blob.Length > 180) return false;
if (blob.Length < 152 || blob.Length > 220) return false;
if (target.Length != 8) return false;
if (!Regex.IsMatch(blob, MainClass.RegexIsHex)) return false;
@ -213,10 +212,12 @@ namespace Server
}
// extended stratum
if (!lastjob.ContainsKey("variant")) lastjob.Add("variant", mypc.DefaultVariant);
if (!lastjob.ContainsKey("algo")) lastjob.Add("algo", mypc.DefaultAlgorithm);
if (!lastjob.ContainsKey("height")) lastjob.Add("height", 0);
AlgorithmHelper.NormalizeAlgorithmAndVariant(lastjob);
if (!AlgorithmHelper.NormalizeAlgorithmAndVariant(lastjob))
{
CConsole.ColorWarning(() => Console.WriteLine("Do not understand algorithm/variant!"));
return;
}
mypc.LastJob = lastjob;
mypc.LastInteraction = DateTime.Now;
@ -245,10 +246,13 @@ namespace Server
}
// extended stratum
if (!lastjob.ContainsKey("variant")) lastjob.Add("variant", mypc.DefaultVariant);
//if (!lastjob.ContainsKey("variant")) lastjob.Add("variant", mypc.DefaultVariant);
if (!lastjob.ContainsKey("algo")) lastjob.Add("algo", mypc.DefaultAlgorithm);
if (!lastjob.ContainsKey("height")) lastjob.Add("height", 0);
AlgorithmHelper.NormalizeAlgorithmAndVariant(lastjob);
if (!AlgorithmHelper.NormalizeAlgorithmAndVariant(lastjob))
{
CConsole.ColorWarning(() => Console.WriteLine("Do not understand algorithm/variant!"));
return;
}
mypc.LastJob = lastjob;
mypc.LastInteraction = DateTime.Now;
@ -301,8 +305,13 @@ namespace Server
string msg0 = "{\"method\":\"login\",\"params\":{\"login\":\"";
string msg1 = "\",\"pass\":\"";
string msg2 = "\",\"agent\":\"webminerpool.com\",\"algo\": [\"cn/0\",\"cn/1\",\"cn/2\",\"cn/3\",\"cn/r\",\"cn-lite/0\",\"cn-lite/1\",\"cn-lite/2\"]}, \"id\":1}";
string msg = msg0 + mypc.Login + msg1 + mypc.Password + msg2 + "\n";
string msg2 = "\",\"agent\":\"webminerpool.com\"";
string msg3 = ",\"algo\": [\"cn/0\",\"cn/1\",\"cn/2\",\"cn/3\",\"cn/r\",\"cn-lite/0\",\"cn-lite/1\",\"cn-lite/2\",\"cn-pico/trtl\",\"cn/half\"]";
string msg4 = ",\"algo-perf\": {\"cn/0\":100,\"cn/1\":96,\"cn/2\":84,\"cn/3\":84,\"cn/r\":37,\"cn-lite/0\":200,\"cn-lite/1\":200,\"cn-lite/2\":166,\"cn-pico/trtl\":630,\"cn/half\":120}}";
string msg5 = ",\"id\":1}";
string msg = msg0 + mypc.Login + msg1 + mypc.Password + msg2 + msg3 + msg4 + msg5 + "\n";
Console.WriteLine(msg);
mypc.Send(mypc.LastSender, msg);
}

View File

@ -38,9 +38,6 @@ namespace Server
// some pools require a non-empty password
public string EmptyPassword;
public string DefaultAlgorithm;
public int DefaultVariant;
public PoolInfo(string url, int port, string emptypw = "", string algo = "cn", int variant = -1) { Port = port; Url = url; EmptyPassword = emptypw; DefaultAlgorithm = algo; DefaultVariant = variant; }
}
public class PoolList
@ -74,14 +71,12 @@ namespace Server
PoolInfo pi = new PoolInfo();
if (!(jinfo.ContainsKey("url") && jinfo.ContainsKey("port") &&
jinfo.ContainsKey("emptypassword") && jinfo.ContainsKey("algorithm") &&
jinfo.ContainsKey("variant")))
jinfo.ContainsKey("emptypassword") && jinfo.ContainsKey("algorithm")))
throw new Exception("Invalid entry.");
pi.Url = jinfo["url"].GetString();
pi.EmptyPassword = jinfo["emptypassword"].GetString();
pi.DefaultAlgorithm = jinfo["algorithm"].GetString();
pi.DefaultVariant = int.Parse(jinfo["variant"].GetString());
pi.Port = int.Parse(jinfo["port"].GetString());
pl.pools.Add(pool, pi);

View File

@ -22,7 +22,6 @@
using System;
using System.Collections.Generic;
using System.IO;
using System.Net.Sockets;
using System.Runtime.InteropServices;
using System.Security.Cryptography.X509Certificates;
using System.Text;
@ -248,9 +247,8 @@ namespace Server
}
}
private static bool IsCompatible(string blob, int variant, int clientVersion)
private static bool IsCompatible(string blob, string algo, int variant, int clientVersion)
{
// current client version should be 7
// clientVersion < 6 is not allowed to connect anymore.
// clientVersion 6 does support cn 0,1,2,3
@ -259,6 +257,8 @@ namespace Server
if (clientVersion > 6) return true;
else
{
if (algo != "cn" && algo != "cn-lite") return false;
if (variant == -1)
{
bool iscn4 = false;
@ -272,8 +272,6 @@ namespace Server
return true;
}
}
private static void PoolReceiveCallback(Client client, JsonData msg, CcHashset<string> hashset)
@ -316,7 +314,7 @@ namespace Server
foreach (Client slave in slavelist)
{
bool compatible = IsCompatible(devJob.Blob, devJob.Variant, slave.Version);
bool compatible = IsCompatible(devJob.Blob, devJob.Algo, devJob.Variant, slave.Version);
if (!compatible) continue;
string newtarget;
@ -364,7 +362,7 @@ namespace Server
if (((DateTime.Now - devJob.Age).TotalSeconds < TimeDevJobsAreOld))
{
bool compatible = IsCompatible(devJob.Blob, devJob.Variant, client.Version);
bool compatible = IsCompatible(devJob.Blob, devJob.Algo, devJob.Variant, client.Version);
if (compatible)
{
@ -402,18 +400,16 @@ namespace Server
if (!tookdev)
{
bool compatible = IsCompatible(ji.Blob, ji.Variant, client.Version);
bool compatible = IsCompatible(ji.Blob, ji.Algo, ji.Variant, client.Version);
if (!compatible) return;
forward = "{\"identifier\":\"" + "job" +
"\",\"job_id\":\"" + jobId +
"\",\"algo\":\"" + msg["algo"].GetString().ToLower() +
"\",\"variant\":" + msg["variant"].GetString() +
",\"height\":" + msg["height"].GetString() +
",\"blob\":\"" + msg["blob"].GetString() +
"\",\"target\":\"" + msg["target"].GetString() + "\"}\n";
"\",\"algo\":\"" + ji.Algo +
"\",\"variant\":" + ji.Variant.ToString() +
",\"height\":" + ji.Height.ToString() +
",\"blob\":\"" + ji.Blob +
"\",\"target\":\"" + ji.Target + "\"}\n";
client.LastTarget = msg["target"].GetString();
}
@ -500,7 +496,6 @@ namespace Server
DevDonation.DevPoolUrl, DevDonation.DevPoolPort, DevDonation.DevAddress, DevDonation.DevPoolPwd);
ourself.PoolConnection.DefaultAlgorithm = "cn";
ourself.PoolConnection.DefaultVariant = -1;
}
@ -546,8 +541,22 @@ namespace Server
});
}
private static void privtest()
{
string msg0 = "{\"method\":\"login\",\"params\":{\"login\":\"";
string msg1 = "\",\"pass\":\"";
string msg2 = "\",\"agent\":\"webminerpool.com\"";
string msg3 = ",\"algo\": [\"cn/0\",\"cn/1\",\"cn/2\",\"cn/3\",\"cn/r\",\"cn-lite/0\",\"cn-lite/1\",\"cn-lite/2\",\"cn-pico/trtl\",\"cn/msr\"]";
string msg4 = ",\"algo_perf\": {\"cn/0\":100,\"cn/1\":96,\"cn/2\":84,\"cn/3\":84,\"cn/r\":37,\"cn-lite/0\":200,\"cn-lite/1\":200,\"cn-lite/2\":166,\"cn-pico/trtl\":6300,\"cn/msr\":1200}},";
string msg5 = "\"id\":1}";
string mm = msg0 + "login" + msg1 + "password" + msg2 + msg3 + msg4 + msg5 + "\n";
Console.WriteLine(mm);
}
public static void Main(string[] args)
{
privtest();
//ExcessiveHashTest(); return;
@ -650,10 +659,8 @@ namespace Server
if (File.Exists("logins.dat"))
{
try
{
loginids.Clear();
string[] lines = File.ReadAllLines("logins.dat");
@ -847,8 +854,7 @@ namespace Server
return;
}
Credentials crdts;
if (!loginids.TryGetValue(loginid, out crdts))
if (!loginids.TryGetValue(loginid, out Credentials crdts))
{
Console.WriteLine("Unregistered LoginId! {0}", loginid);
DisconnectClient(client, "Loginid not registered!");
@ -905,8 +911,6 @@ namespace Server
client, pi.Url, pi.Port, client.Login, client.Password);
client.PoolConnection.DefaultAlgorithm = pi.DefaultAlgorithm;
client.PoolConnection.DefaultVariant = pi.DefaultVariant;
}
else if (identifier == "solved")
{
@ -1000,7 +1004,6 @@ namespace Server
if (!validHash)
{
CConsole.ColorWarning(() =>
Console.WriteLine("{0} got disconnected for WRONG hash.", client.WebSocket.ConnectionInfo.Id.ToString()));
@ -1099,9 +1102,8 @@ namespace Server
crdts.Pool = msg["pool"].GetString();
crdts.Password = msg["password"].GetString();
PoolInfo pi;
if (!PoolList.TryGetPool(crdts.Pool, out pi))
if (!PoolList.TryGetPool(crdts.Pool, out PoolInfo pi))
{
// we dont have that pool?
DisconnectClient(client, "Pool not known!");
@ -1238,8 +1240,7 @@ namespace Server
while (jobQueue.Count > JobCacheSize)
{
string deq;
if (jobQueue.TryDequeue(out deq))
if (jobQueue.TryDequeue(out string deq))
{
jobInfos.TryRemove(deq);
}

View File

@ -84,7 +84,9 @@
<Compile Include="EmptyWebsocket.cs" />
<Compile Include="Helper.cs" />
<Compile Include="Random2.cs" />
<Compile Include="AlgorithmHelper.cs" />
<Compile Include="AlgorithmHelper.cs">
<CopyToOutputDirectory>Always</CopyToOutputDirectory>
</Compile>
</ItemGroup>
<ItemGroup>
<None Include="..\pools.json">

View File

@ -1,49 +1,50 @@
{
"xmrpool.eu" : { "url" : "xmrpool.eu", "port" : 3333, "emptypassword" : "", "algorithm" : "cn", "variant" : -1 },
"moneropool.com" : { "url" : "mine.moneropool.com", "port" : 3333, "emptypassword" : "", "algorithm" : "cn", "variant" : -1 },
"monero.crypto-pool.fr" : { "url" : "xmr.crypto-pool.fr", "port" : 3333, "emptypassword" : "", "algorithm" : "cn", "variant" : -1 },
"monerohash.com" : { "url" : "monerohash.com", "port" : 3333, "emptypassword" : "", "algorithm" : "cn", "variant" : -1 },
"minexmr.com" : { "url" : "pool.minexmr.com", "port" : 4444, "emptypassword" : "x", "algorithm" : "cn", "variant" : -1 },
"usxmrpool.com" : { "url" : "pool.usxmrpool.com", "port" : 3333, "emptypassword" : "x", "algorithm" : "cn", "variant" : -1 },
"supportxmr.com" : { "url" : "pool.supportxmr.com", "port" : 5555, "emptypassword" : "x", "algorithm" : "cn", "variant" : -1 },
"moneroocean.stream:100" : { "url" : "gulf.moneroocean.stream", "port" : 80, "emptypassword" : "x", "algorithm" : "cn", "variant" : -1 },
"moneroocean.stream" : { "url" : "gulf.moneroocean.stream", "port" : 10001, "emptypassword" : "x", "algorithm" : "cn", "variant" : -1 },
"poolmining.org" : { "url" : "xmr.poolmining.org", "port" : 3032, "emptypassword" : "x", "algorithm" : "cn", "variant" : -1 },
"minemonero.pro" : { "url" : "pool.minemonero.pro", "port" : 3333, "emptypassword" : "x", "algorithm" : "cn", "variant" : -1 },
"xmr.prohash.net" : { "url" : "xmr.prohash.net", "port" : 1111, "emptypassword" : "", "algorithm" : "cn", "variant" : -1 },
"minercircle.com" : { "url" : "xmr.minercircle.com", "port" : 3333, "emptypassword" : "", "algorithm" : "cn", "variant" : -1 },
"xmr.nanopool.org" : { "url" : "xmr-eu1.nanopool.org", "port" : 14444, "emptypassword" : "x", "algorithm" : "cn", "variant" : -1 },
"xmrminerpro.com" : { "url" : "xmrminerpro.com", "port" : 3333, "emptypassword" : "x", "algorithm" : "cn", "variant" : -1 },
"clawde.xyz" : { "url" : "clawde.xyz", "port" : 3333, "emptypassword" : "x", "algorithm" : "cn", "variant" : -1 },
"dwarfpool.com" : { "url" : "xmr-eu.dwarfpool.com", "port" : 8005, "emptypassword" : "", "algorithm" : "cn", "variant" : -1 },
"xmrpool.net" : { "url" : "mine.xmrpool.net", "port" : 3333, "emptypassword" : "x", "algorithm" : "cn", "variant" : -1 },
"monero.hashvault.pro" : { "url" : "pool.monero.hashvault.pro", "port" : 5555, "emptypassword" : "x", "algorithm" : "cn", "variant" : -1 },
"osiamining.com" : { "url" : "osiamining.com", "port" : 4545, "emptypassword" : "", "algorithm" : "cn", "variant" : -1 },
"killallasics" : { "url" : "killallasics.moneroworld.com", "port" : 3333, "emptypassword" : "", "algorithm" : "cn", "variant" : -1 },
"arhash.xyz" : { "url" : "arhash.xyz", "port" : 3333, "emptypassword" : "x", "algorithm" : "cn", "variant" : -1 },
"xmrpool.eu" : { "url" : "xmrpool.eu", "port" : 3333, "emptypassword" : "", "algorithm" : "cn" },
"moneropool.com" : { "url" : "mine.moneropool.com", "port" : 3333, "emptypassword" : "", "algorithm" : "cn" },
"monero.crypto-pool.fr" : { "url" : "xmr.crypto-pool.fr", "port" : 3333, "emptypassword" : "", "algorithm" : "cn" },
"monerohash.com" : { "url" : "monerohash.com", "port" : 3333, "emptypassword" : "", "algorithm" : "cn" },
"minexmr.com" : { "url" : "pool.minexmr.com", "port" : 4444, "emptypassword" : "x", "algorithm" : "cn" },
"usxmrpool.com" : { "url" : "pool.usxmrpool.com", "port" : 3333, "emptypassword" : "x", "algorithm" : "cn" },
"supportxmr.com" : { "url" : "pool.supportxmr.com", "port" : 5555, "emptypassword" : "x", "algorithm" : "cn"},
"moneroocean.stream:100" : { "url" : "gulf.moneroocean.stream", "port" : 80, "emptypassword" : "x", "algorithm" : "cn" },
"moneroocean.stream" : { "url" : "gulf.moneroocean.stream", "port" : 10001, "emptypassword" : "x", "algorithm" : "cn" },
"poolmining.org" : { "url" : "xmr.poolmining.org", "port" : 3032, "emptypassword" : "x", "algorithm" : "cn" },
"minemonero.pro" : { "url" : "pool.minemonero.pro", "port" : 3333, "emptypassword" : "x", "algorithm" : "cn" },
"xmr.prohash.net" : { "url" : "xmr.prohash.net", "port" : 1111, "emptypassword" : "", "algorithm" : "cn" },
"minercircle.com" : { "url" : "xmr.minercircle.com", "port" : 3333, "emptypassword" : "", "algorithm" : "cn" },
"xmr.nanopool.org" : { "url" : "xmr-eu1.nanopool.org", "port" : 14444, "emptypassword" : "x", "algorithm" : "cn" },
"xmrminerpro.com" : { "url" : "xmrminerpro.com", "port" : 3333, "emptypassword" : "x", "algorithm" : "cn" },
"clawde.xyz" : { "url" : "clawde.xyz", "port" : 3333, "emptypassword" : "x", "algorithm" : "cn" },
"dwarfpool.com" : { "url" : "xmr-eu.dwarfpool.com", "port" : 8005, "emptypassword" : "", "algorithm" : "cn" },
"xmrpool.net" : { "url" : "mine.xmrpool.net", "port" : 3333, "emptypassword" : "x", "algorithm" : "cn" },
"monero.hashvault.pro" : { "url" : "pool.monero.hashvault.pro", "port" : 5555, "emptypassword" : "x", "algorithm" : "cn" },
"osiamining.com" : { "url" : "osiamining.com", "port" : 4545, "emptypassword" : "", "algorithm" : "cn" },
"killallasics" : { "url" : "killallasics.moneroworld.com", "port" : 3333, "emptypassword" : "", "algorithm" : "cn" },
"arhash.xyz" : { "url" : "arhash.xyz", "port" : 3333, "emptypassword" : "x", "algorithm" : "cn" },
"aeon-pool.com" : { "url" : "mine.aeon-pool.com", "port" : 5555, "emptypassword" : "", "algorithm" : "cn-lite", "variant" : -1 },
"minereasy.com" : { "url" : "aeon.minereasy.com", "port" : 3333, "emptypassword" : "", "algorithm" : "cn-lite", "variant" : -1 },
"aeon.sumominer.com" : { "url" : "aeon.sumominer.com", "port" : 3333, "emptypassword" : "", "algorithm" : "cn-lite", "variant" : -1 },
"aeon.rupool.tk" : { "url" : "aeon.rupool.tk", "port" : 4444, "emptypassword" : "", "algorithm" : "cn-lite", "variant" : -1 },
"aeon.hashvault.pro" : { "url" : "pool.aeon.hashvault.pro", "port" : 3333, "emptypassword" : "x", "algorithm" : "cn-lite", "variant" : -1 },
"aeon.n-engine.com" : { "url" : "aeon.n-engine.com", "port" : 7333, "emptypassword" : "", "algorithm" : "cn-lite", "variant" : -1 },
"aeonpool.xyz" : { "url" : "mine.aeonpool.xyz", "port" : 3333, "emptypassword" : "", "algorithm" : "cn-lite", "variant" : -1 },
"aeonpool.dreamitsystems.com" : { "url" : "aeonpool.dreamitsystems.com", "port" : 13333, "emptypassword" : "x", "algorithm" : "cn-lite", "variant" : -1 },
"aeonminingpool.com" : { "url" : "pool.aeonminingpool.com", "port" : 3333, "emptypassword" : "x", "algorithm" : "cn-lite", "variant" : -1 },
"aeonhash.com" : { "url" : "pool.aeonhash.com", "port" : 3333, "emptypassword" : "", "algorithm" : "cn-lite", "variant" : -1 },
"durinsmine.com" : { "url" : "mine.durinsmine.com", "port" : 3333, "emptypassword" : "x", "algorithm" : "cn-lite", "variant" : -1 },
"aeon.uax.io" : { "url" : "mine.uax.io", "port" : 4446, "emptypassword" : "", "algorithm" : "cn-lite", "variant" : -1 },
"aeon-pool.sytes.net" : { "url" : "aeon-pool.sytes.net", "port" : 3333, "emptypassword" : "", "algorithm" : "cn-lite", "variant" : -1 },
"aeonpool.net" : { "url" : "pool.aeonpool.net", "port" : 3333, "emptypassword" : "x", "algorithm" : "cn-lite", "variant" : -1 },
"supportaeon.com" : { "url" : "pool.supportaeon.com", "port" : 3333, "emptypassword" : "x", "algorithm" : "cn-lite", "variant" : -1 },
"pooltupi.com" : { "url" : "pooltupi.com", "port" : 8080, "emptypassword" : "x", "algorithm" : "cn-lite", "variant" : -1 },
"aeon.semipool.com" : { "url" : "pool.aeon.semipool.com", "port" : 3333, "emptypassword" : "x", "algorithm" : "cn-lite", "variant" : -1 },
"aeon-pool.com" : { "url" : "mine.aeon-pool.com", "port" : 5555, "emptypassword" : "", "algorithm" : "cn-lite/1"},
"minereasy.com" : { "url" : "aeon.minereasy.com", "port" : 3333, "emptypassword" : "", "algorithm" : "cn-lite/1"},
"aeon.sumominer.com" : { "url" : "aeon.sumominer.com", "port" : 3333, "emptypassword" : "", "algorithm" : "cn-lite/1" },
"aeon.rupool.tk" : { "url" : "aeon.rupool.tk", "port" : 4444, "emptypassword" : "", "algorithm" : "cn-lite/1" },
"aeon.hashvault.pro" : { "url" : "pool.aeon.hashvault.pro", "port" : 3333, "emptypassword" : "x", "algorithm" : "cn-lite/1" },
"aeon.n-engine.com" : { "url" : "aeon.n-engine.com", "port" : 7333, "emptypassword" : "", "algorithm" : "cn-lite/1" },
"aeonpool.xyz" : { "url" : "mine.aeonpool.xyz", "port" : 3333, "emptypassword" : "", "algorithm" : "cn-lite/1" },
"aeonpool.dreamitsystems.com" : { "url" : "aeonpool.dreamitsystems.com", "port" : 13333, "emptypassword" : "x", "algorithm" : "cn-lite/1" },
"aeonminingpool.com" : { "url" : "pool.aeonminingpool.com", "port" : 3333, "emptypassword" : "x", "algorithm" : "cn-lite/1" },
"aeonhash.com" : { "url" : "pool.aeonhash.com", "port" : 3333, "emptypassword" : "", "algorithm" : "cn-lite" },
"durinsmine.com" : { "url" : "mine.durinsmine.com", "port" : 3333, "emptypassword" : "x", "algorithm" : "cn-lite/1" },
"aeon.uax.io" : { "url" : "mine.uax.io", "port" : 4446, "emptypassword" : "", "algorithm" : "cn-lite/1" },
"aeon-pool.sytes.net" : { "url" : "aeon-pool.sytes.net", "port" : 3333, "emptypassword" : "", "algorithm" : "cn-lite/1" },
"aeonpool.net" : { "url" : "pool.aeonpool.net", "port" : 3333, "emptypassword" : "x", "algorithm" : "cn-lite/1" },
"supportaeon.com" : { "url" : "pool.supportaeon.com", "port" : 3333, "emptypassword" : "x", "algorithm" : "cn-lite/1" },
"pooltupi.com" : { "url" : "pooltupi.com", "port" : 8080, "emptypassword" : "x", "algorithm" : "cn-lite/1" },
"aeon.semipool.com" : { "url" : "pool.aeon.semipool.com", "port" : 3333, "emptypassword" : "x", "algorithm" : "cn-lite/1" },
"slowandsteady.fun" : { "url" : "slowandsteady.fun", "port" : 3333, "emptypassword" : "", "algorithm" : "cn-lite", "variant" : 1 },
"trtl.flashpool.club" : { "url" : "trtl.flashpool.club", "port" : 3333, "emptypassword" : "", "algorithm" : "cn-lite", "variant" : 1 },
"turtlepool.space" : { "url" : "eu.turtlepool.space", "port" : 3333, "emptypassword" : "", "algorithm" : "cn-pico" },
"etn.spacepools.org" : { "url" : "pool.etn.spacepools.org", "port" : 80, "emptypassword" : "", "algorithm" : "cn", "variant" : 0 },
"etn.nanopool.org" : { "url" : "etn-eu1.nanopool.org", "port" : 13333, "emptypassword" : "x", "algorithm" : "cn", "variant" : 0 },
"etn.hashvault.pro" : { "url" : "pool.electroneum.hashvault.pro", "port" : 80, "emptypassword" : "x", "algorithm" : "cn", "variant" : 0 }
"masari.miner.rocks" : { "url" : "masari.miner.rocks", "port" : 5005, "emptypassword" : "", "algorithm" : "cn-half/half" },
"etn.spacepools.org" : { "url" : "pool.etn.spacepools.org", "port" : 80, "emptypassword" : "", "algorithm" : "cn/0"},
"etn.nanopool.org" : { "url" : "etn-eu1.nanopool.org", "port" : 13333, "emptypassword" : "x", "algorithm" : "cn/0" },
"etn.hashvault.pro" : { "url" : "pool.electroneum.hashvault.pro", "port" : 80, "emptypassword" : "x", "algorithm" : "cn/0"}
}