Integrate new algo "cryptonight-lite-ipbc" (#100)

This commit is contained in:
Ben Gräf 2018-04-18 21:50:00 +02:00 committed by GitHub
parent 9ea520a3a4
commit a5c311fad8
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
16 changed files with 1938 additions and 102 deletions

View file

@ -67,6 +67,7 @@ void CpuImpl::optimizeParameters(size_t& threadsCount, size_t& hashFactor,
size_t algoBlockSize;
switch (algo) {
case Options::ALGO_CRYPTONIGHT_LITE:
case Options::ALGO_CRYPTONIGHT_LITE_IPBC:
algoBlockSize = 1024;
break;
case Options::ALGO_CRYPTONIGHT_HEAVY:

View file

@ -44,6 +44,7 @@ cryptonight_ctx *Mem::create(int threadId)
switch (m_algo)
{
case Options::ALGO_CRYPTONIGHT_LITE:
case Options::ALGO_CRYPTONIGHT_LITE_IPBC:
scratchPadSize = MEMORY_LITE;
break;
case Options::ALGO_CRYPTONIGHT_HEAVY:

View file

@ -50,6 +50,7 @@ bool Mem::allocate(const Options* options)
switch (m_algo)
{
case Options::ALGO_CRYPTONIGHT_LITE:
case Options::ALGO_CRYPTONIGHT_LITE_IPBC:
scratchPadSize = MEMORY_LITE;
break;
case Options::ALGO_CRYPTONIGHT_HEAVY:

View file

@ -156,6 +156,7 @@ bool Mem::allocate(const Options* options)
switch (m_algo)
{
case Options::ALGO_CRYPTONIGHT_LITE:
case Options::ALGO_CRYPTONIGHT_LITE_IPBC:
scratchPadSize = MEMORY_LITE;
break;
case Options::ALGO_CRYPTONIGHT_HEAVY:

View file

@ -259,6 +259,7 @@ static struct option const cc_server_options[] = {
static const char *algo_names[] = {
"cryptonight",
"cryptonight-lite",
"cryptonight-lite-ipbc",
"cryptonight-heavy"
};
@ -924,6 +925,11 @@ bool Options::setAlgo(const char *algo)
break;
}
if (i == ARRAY_SIZE(algo_names) - 1 && !strcmp(algo, "cryptonight-light-ipbc")) {
m_algo = ALGO_CRYPTONIGHT_LITE_IPBC;
break;
}
if (i == ARRAY_SIZE(algo_names) - 1 && !strcmp(algo, "cryptonight-heavy")) {
m_algo = ALGO_CRYPTONIGHT_HEAVY;
break;

View file

@ -44,6 +44,7 @@ public:
enum Algo {
ALGO_CRYPTONIGHT, /* CryptoNight (Monero) */
ALGO_CRYPTONIGHT_LITE, /* CryptoNight-Lite (AEON) */
ALGO_CRYPTONIGHT_LITE_IPBC, /* CryptoNight-Lite-IPBC (IPBC) */
ALGO_CRYPTONIGHT_HEAVY /* CryptoNight-Heavy (SUMO) */
};

View file

@ -1,5 +1,5 @@
{
"algo": "cryptonight", // cryptonight (default), cryptonight-lite or cryptopnight-heavy
"algo": "cryptonight", // cryptonight (default), cryptonight-lite, cryptonight-lite-ipbc or cryptopnight-heavy
"av": null, // DEPRECATED: algorithm variation, (0 auto,
// 1 -> (aesni=1, multihash-factor=1),
// 2 -> (aesni=1, multihash-factor=2),

View file

@ -77,6 +77,17 @@ static void cryptonight_lite_softaes(Options::PowVersion powVersion, const uint8
}
}
template <size_t NUM_HASH_BLOCKS>
static void cryptonight_lite_ipbc_aesni(Options::PowVersion powVersion, const uint8_t* input, size_t size, uint8_t* output, cryptonight_ctx *ctx) {
# if !defined(XMRIG_ARMv7)
CryptoNightMultiHash<0x40000, MEMORY_LITE, 0xFFFF0, false, NUM_HASH_BLOCKS>::hashLiteIpbc(input, size, output, ctx);
# endif
}
template <size_t NUM_HASH_BLOCKS>
static void cryptonight_lite_ipbc_softaes(Options::PowVersion powVersion, const uint8_t* input, size_t size, uint8_t* output, cryptonight_ctx *ctx) {
CryptoNightMultiHash<0x40000, MEMORY_LITE, 0xFFFF0, true, NUM_HASH_BLOCKS>::hashLiteIpbc(input, size, output, ctx);
}
template <size_t NUM_HASH_BLOCKS>
static void cryptonight_heavy_aesni(Options::PowVersion powVersion, const uint8_t* input, size_t size, uint8_t* output, cryptonight_ctx *ctx) {
@ -112,6 +123,14 @@ void setCryptoNightHashMethods(Options::Algo algo, bool aesni)
}
break;
case Options::ALGO_CRYPTONIGHT_LITE_IPBC:
if (aesni) {
cryptonight_hash_ctx[HASH_FACTOR - 1] = cryptonight_lite_ipbc_aesni<HASH_FACTOR>;
} else {
cryptonight_hash_ctx[HASH_FACTOR - 1] = cryptonight_lite_ipbc_softaes<HASH_FACTOR>;
}
break;
case Options::ALGO_CRYPTONIGHT_HEAVY:
if (aesni) {
cryptonight_hash_ctx[HASH_FACTOR - 1] = cryptonight_heavy_aesni<HASH_FACTOR>;
@ -167,6 +186,7 @@ bool CryptoNight::selfTest(int algo)
bool resultV1Pow = true;
bool resultV2Pow = true;
bool resultLiteIpbc = true;
bool resultHeavy = true;
if (algo == Options::ALGO_CRYPTONIGHT_HEAVY) {
@ -184,8 +204,32 @@ bool CryptoNight::selfTest(int algo)
cryptonight_hash_ctx[2](Options::PowVersion::POW_AUTODETECT, test_input, 76, output, ctx);
resultHeavy = resultHeavy && memcmp(output, test_output_heavy, 96) == 0;
#endif
}
else {
} else if (algo == Options::ALGO_CRYPTONIGHT_LITE_IPBC) {
// cn-lite-ipbc tests
cryptonight_hash_ctx[0](Options::PowVersion::POW_AUTODETECT, test_input_lite_ipbc, 43, output, ctx);
resultLiteIpbc = resultLiteIpbc && memcmp(output, test_output_lite_ipbc, 32) == 0;
#if MAX_NUM_HASH_BLOCKS > 1
cryptonight_hash_ctx[1](Options::PowVersion::POW_AUTODETECT, test_input_lite_ipbc, 43, output, ctx);
resultLiteIpbc = resultLiteIpbc && memcmp(output, test_output_lite_ipbc, 64) == 0;
#endif
#if MAX_NUM_HASH_BLOCKS > 2
cryptonight_hash_ctx[2](Options::PowVersion::POW_AUTODETECT, test_input_lite_ipbc, 43, output, ctx);
resultLiteIpbc = resultLiteIpbc && memcmp(output, test_output_lite_ipbc, 96) == 0;
#endif
#if MAX_NUM_HASH_BLOCKS > 3
cryptonight_hash_ctx[3](Options::PowVersion::POW_AUTODETECT, test_input_lite_ipbc, 43, output, ctx);
resultLiteIpbc = resultLiteIpbc && memcmp(output, test_output_lite_ipbc, 128) == 0;
#endif
#if MAX_NUM_HASH_BLOCKS > 4
cryptonight_hash_ctx[4](Options::PowVersion::POW_AUTODETECT, test_input_lite_ipbc, 43, output, ctx);
resultLiteIpbc = resultLiteIpbc && memcmp(output, test_output_lite_ipbc, 160) == 0;
#endif
} else {
// < v7 tests autodetect
cryptonight_hash_ctx[0](Options::PowVersion::POW_AUTODETECT,test_input, 76, output, ctx);
resultV1Pow = resultV1Pow &&
@ -248,5 +292,5 @@ bool CryptoNight::selfTest(int algo)
_mm_free(ctx->memory);
_mm_free(ctx);
return resultV1Pow && resultV2Pow & resultHeavy;
return resultV1Pow && resultV2Pow & resultLiteIpbc & resultHeavy;
}

View file

@ -30,8 +30,8 @@
#include "Options.h"
#define MEMORY 2097152 /* 2 MiB */
#define MEMORY_LITE 1048576 /* 1 MiB */
#define MEMORY 2097152 /* 2 MiB */
#define MEMORY_LITE 1048576 /* 1 MiB */
#define MEMORY_HEAVY 4194304 /* 4 MiB */
struct cryptonight_ctx {

View file

@ -732,6 +732,93 @@ public:
}
}
inline static void hashLiteIpbc(const uint8_t* __restrict__ input,
size_t size,
uint8_t *__restrict__ output,
cryptonight_ctx* __restrict__ ctx)
{
const uint8_t* l[NUM_HASH_BLOCKS];
uint64_t* h[NUM_HASH_BLOCKS];
uint64_t al[NUM_HASH_BLOCKS];
uint64_t ah[NUM_HASH_BLOCKS];
__m128i bx[NUM_HASH_BLOCKS];
uint64_t idx[NUM_HASH_BLOCKS];
uint64_t tweak1_2[NUM_HASH_BLOCKS];
for (size_t hashBlock = 0; hashBlock < NUM_HASH_BLOCKS; ++hashBlock) {
keccak(static_cast<const uint8_t*>(input) + hashBlock * size, (int) size, ctx->state[hashBlock], 200);
tweak1_2[hashBlock] = (*reinterpret_cast<const uint64_t*>(input + 35 + hashBlock * size) ^
*(reinterpret_cast<const uint64_t*>(ctx->state[hashBlock]) + 24));
}
for (size_t hashBlock = 0; hashBlock < NUM_HASH_BLOCKS; ++hashBlock) {
l[hashBlock] = ctx->memory + hashBlock * MEM;
h[hashBlock] = reinterpret_cast<uint64_t*>(ctx->state[hashBlock]);
cn_explode_scratchpad<MEM, SOFT_AES>((__m128i*) h[hashBlock], (__m128i*) l[hashBlock]);
al[hashBlock] = h[hashBlock][0] ^ h[hashBlock][4];
ah[hashBlock] = h[hashBlock][1] ^ h[hashBlock][5];
bx[hashBlock] =
_mm_set_epi64x(h[hashBlock][3] ^ h[hashBlock][7], h[hashBlock][2] ^ h[hashBlock][6]);
idx[hashBlock] = h[hashBlock][0] ^ h[hashBlock][4];
}
for (size_t i = 0; i < ITERATIONS; i++) {
for (size_t hashBlock = 0; hashBlock < NUM_HASH_BLOCKS; ++hashBlock) {
__m128i cx;
if (SOFT_AES) {
cx = soft_aesenc((uint32_t*)&l[hashBlock][idx[hashBlock] & MASK], _mm_set_epi64x(ah[hashBlock], al[hashBlock]));
} else {
cx = _mm_load_si128((__m128i *) &l[hashBlock][idx[hashBlock] & MASK]);
# ifndef XMRIG_ARMv7
cx = vreinterpretq_m128i_u8(vaesmcq_u8(vaeseq_u8(cx, vdupq_n_u8(0)))) ^ _mm_set_epi64x(ah[hashBlock], al[hashBlock]);
# endif
}
_mm_store_si128((__m128i*) &l[hashBlock][idx[hashBlock] & MASK],
_mm_xor_si128(bx[hashBlock], cx));
const uint8_t tmp = reinterpret_cast<const uint8_t*>(&l[hashBlock][idx[hashBlock] & MASK])[11];
static const uint32_t table = 0x75310;
const uint8_t index = (((tmp >> 3) & 6) | (tmp & 1)) << 1;
((uint8_t*)(&l[hashBlock][idx[hashBlock] & MASK]))[11] = tmp ^ ((table >> index) & 0x30);
idx[hashBlock] = EXTRACT64(cx);
bx[hashBlock] = cx;
uint64_t hi, lo, cl, ch;
cl = ((uint64_t*) &l[hashBlock][idx[hashBlock] & MASK])[0];
ch = ((uint64_t*) &l[hashBlock][idx[hashBlock] & MASK])[1];
lo = __umul128(idx[hashBlock], cl, &hi);
al[hashBlock] += hi;
ah[hashBlock] += lo;
ah[hashBlock] ^= tweak1_2[hashBlock];
((uint64_t*) &l[hashBlock][idx[hashBlock] & MASK])[0] = al[hashBlock];
((uint64_t*) &l[hashBlock][idx[hashBlock] & MASK])[1] = ah[hashBlock];
ah[hashBlock] ^= tweak1_2[hashBlock];
((uint64_t*)&l[hashBlock][idx[hashBlock] & MASK])[1] ^= ((uint64_t*)&l[hashBlock][idx[hashBlock] & MASK])[0];
ah[hashBlock] ^= ch;
al[hashBlock] ^= cl;
idx[hashBlock] = al[hashBlock];
}
}
for (size_t hashBlock = 0; hashBlock < NUM_HASH_BLOCKS; ++hashBlock) {
cn_implode_scratchpad<MEM, SOFT_AES>((__m128i*) l[hashBlock], (__m128i*) h[hashBlock]);
keccakf(h[hashBlock], 24);
extra_hashes[ctx->state[hashBlock][0] & 3](ctx->state[hashBlock], 200,
output + hashBlock * 32);
}
}
inline static void hashHeavy(const uint8_t* __restrict__ input,
size_t size,
uint8_t *__restrict__ output,
@ -949,6 +1036,78 @@ public:
extra_hashes[ctx->state[0][0] & 3](ctx->state[0], 200, output);
}
inline static void hashLiteIpbc(const uint8_t* __restrict__ input,
size_t size,
uint8_t *__restrict__ output,
cryptonight_ctx* __restrict__ ctx)
{
const uint8_t* l;
uint64_t* h;
uint64_t al;
uint64_t ah;
__m128i bx;
uint64_t idx;
keccak(static_cast<const uint8_t*>(input), (int) size, ctx->state[0], 200);
uint64_t tweak1_2 = (*reinterpret_cast<const uint64_t*>(input + 35) ^
*(reinterpret_cast<const uint64_t*>(ctx->state[0]) + 24));
l = ctx->memory;
h = reinterpret_cast<uint64_t*>(ctx->state[0]);
cn_explode_scratchpad<MEM, SOFT_AES>((__m128i*) h, (__m128i*) l);
al = h[0] ^ h[4];
ah = h[1] ^ h[5];
bx = _mm_set_epi64x(h[3] ^ h[7], h[2] ^ h[6]);
idx = h[0] ^ h[4];
for (size_t i = 0; i < ITERATIONS; i++) {
__m128i cx;
if (SOFT_AES) {
cx = soft_aesenc((uint32_t*)&l[idx & MASK], _mm_set_epi64x(ah, al));
}
else {
cx = _mm_load_si128((__m128i *) &l[idx & MASK]);
# ifndef XMRIG_ARMv7
cx = vreinterpretq_m128i_u8(vaesmcq_u8(vaeseq_u8(cx, vdupq_n_u8(0)))) ^ _mm_set_epi64x(ah, al);
# endif
}
_mm_store_si128((__m128i*) &l[idx & MASK], _mm_xor_si128(bx, cx));
const uint8_t tmp = reinterpret_cast<const uint8_t*>(&l[idx & MASK])[11];
static const uint32_t table = 0x75310;
const uint8_t index = (((tmp >> 3) & 6) | (tmp & 1)) << 1;
((uint8_t*)(&l[idx & MASK]))[11] = tmp ^ ((table >> index) & 0x30);
idx = EXTRACT64(cx);
bx = cx;
uint64_t hi, lo, cl, ch;
cl = ((uint64_t*) &l[idx & MASK])[0];
ch = ((uint64_t*) &l[idx & MASK])[1];
lo = __umul128(idx, cl, &hi);
al += hi;
ah += lo;
ah ^= tweak1_2;
((uint64_t*) &l[idx & MASK])[0] = al;
((uint64_t*) &l[idx & MASK])[1] = ah;
ah ^= tweak1_2;
((uint64_t*)&l[idx & MASK])[1] ^= ((uint64_t*)&l[idx & MASK])[0];
ah ^= ch;
al ^= cl;
idx = al;
}
cn_implode_scratchpad<MEM, SOFT_AES>((__m128i*) l, (__m128i*) h);
keccakf(h, 24);
extra_hashes[ctx->state[0][0] & 3](ctx->state[0], 200, output);
}
inline static void hashHeavy(const uint8_t* __restrict__ input,
size_t size,
uint8_t *__restrict__ output,
@ -1226,6 +1385,120 @@ public:
extra_hashes[ctx->state[1][0] & 3](ctx->state[1], 200, output + 32);
}
inline static void hashLiteIpbc(const uint8_t* __restrict__ input,
size_t size,
uint8_t *__restrict__ output,
cryptonight_ctx* __restrict__ ctx)
{
keccak(input, (int) size, ctx->state[0], 200);
keccak(input + size, (int) size, ctx->state[1], 200);
uint64_t tweak1_2_0 = (*reinterpret_cast<const uint64_t*>(input + 35) ^
*(reinterpret_cast<const uint64_t*>(ctx->state[0]) + 24));
uint64_t tweak1_2_1 = (*reinterpret_cast<const uint64_t*>(input + 35 + size) ^
*(reinterpret_cast<const uint64_t*>(ctx->state[1]) + 24));
const uint8_t* l0 = ctx->memory;
const uint8_t* l1 = ctx->memory + MEM;
uint64_t* h0 = reinterpret_cast<uint64_t*>(ctx->state[0]);
uint64_t* h1 = reinterpret_cast<uint64_t*>(ctx->state[1]);
cn_explode_scratchpad<MEM, SOFT_AES>((__m128i*) h0, (__m128i*) l0);
cn_explode_scratchpad<MEM, SOFT_AES>((__m128i*) h1, (__m128i*) l1);
uint64_t al0 = h0[0] ^h0[4];
uint64_t al1 = h1[0] ^h1[4];
uint64_t ah0 = h0[1] ^h0[5];
uint64_t ah1 = h1[1] ^h1[5];
__m128i bx0 = _mm_set_epi64x(h0[3] ^ h0[7], h0[2] ^ h0[6]);
__m128i bx1 = _mm_set_epi64x(h1[3] ^ h1[7], h1[2] ^ h1[6]);
uint64_t idx0 = h0[0] ^h0[4];
uint64_t idx1 = h1[0] ^h1[4];
for (size_t i = 0; i < ITERATIONS; i++) {
__m128i cx0;
__m128i cx1;
if (SOFT_AES) {
cx0 = soft_aesenc((uint32_t*)&l0[idx0 & MASK], _mm_set_epi64x(ah0, al0));
cx1 = soft_aesenc((uint32_t*)&l1[idx1 & MASK], _mm_set_epi64x(ah1, al1));
} else {
cx0 = _mm_load_si128((__m128i*) &l0[idx0 & MASK]);
cx1 = _mm_load_si128((__m128i*) &l1[idx1 & MASK]);
# ifndef XMRIG_ARMv7
cx0 = vreinterpretq_m128i_u8(vaesmcq_u8(vaeseq_u8(cx0, vdupq_n_u8(0)))) ^ _mm_set_epi64x(ah0, al0);
cx1 = vreinterpretq_m128i_u8(vaesmcq_u8(vaeseq_u8(cx1, vdupq_n_u8(0)))) ^ _mm_set_epi64x(ah1, al1);
# endif
}
_mm_store_si128((__m128i*) &l0[idx0 & MASK], _mm_xor_si128(bx0, cx0));
_mm_store_si128((__m128i*) &l1[idx1 & MASK], _mm_xor_si128(bx1, cx1));
static const uint32_t table = 0x75310;
uint8_t tmp = reinterpret_cast<const uint8_t*>(&l0[idx0 & MASK])[11];
uint8_t index = (((tmp >> 3) & 6) | (tmp & 1)) << 1;
((uint8_t*)(&l0[idx0 & MASK]))[11] = tmp ^ ((table >> index) & 0x30);
tmp = reinterpret_cast<const uint8_t*>(&l1[idx1 & MASK])[11];
index = (((tmp >> 3) & 6) | (tmp & 1)) << 1;
((uint8_t*)(&l1[idx1 & MASK]))[11] = tmp ^ ((table >> index) & 0x30);
idx0 = EXTRACT64(cx0);
idx1 = EXTRACT64(cx1);
bx0 = cx0;
bx1 = cx1;
uint64_t hi, lo, cl, ch;
cl = ((uint64_t*) &l0[idx0 & MASK])[0];
ch = ((uint64_t*) &l0[idx0 & MASK])[1];
lo = __umul128(idx0, cl, &hi);
al0 += hi;
ah0 += lo;
ah0 ^= tweak1_2_0;
((uint64_t*) &l0[idx0 & MASK])[0] = al0;
((uint64_t*) &l0[idx0 & MASK])[1] = ah0;
ah0 ^= tweak1_2_0;
((uint64_t*)&l0[idx0 & MASK])[1] ^= ((uint64_t*)&l0[idx0 & MASK])[0];
ah0 ^= ch;
al0 ^= cl;
idx0 = al0;
cl = ((uint64_t*) &l1[idx1 & MASK])[0];
ch = ((uint64_t*) &l1[idx1 & MASK])[1];
lo = __umul128(idx1, cl, &hi);
al1 += hi;
ah1 += lo;
ah1 ^= tweak1_2_1;
((uint64_t*) &l1[idx1 & MASK])[0] = al1;
((uint64_t*) &l1[idx1 & MASK])[1] = ah1;
ah1 ^= tweak1_2_1;
((uint64_t*)&l1[idx1 & MASK])[1] ^= ((uint64_t*)&l1[idx1 & MASK])[0];
ah1 ^= ch;
al1 ^= cl;
idx1 = al1;
}
cn_implode_scratchpad<MEM, SOFT_AES>((__m128i*) l0, (__m128i*) h0);
cn_implode_scratchpad<MEM, SOFT_AES>((__m128i*) l1, (__m128i*) h1);
keccakf(h0, 24);
keccakf(h1, 24);
extra_hashes[ctx->state[0][0] & 3](ctx->state[0], 200, output);
extra_hashes[ctx->state[1][0] & 3](ctx->state[1], 200, output + 32);
}
inline static void hashHeavy(const uint8_t* __restrict__ input,
size_t size,
uint8_t *__restrict__ output,
@ -1618,6 +1891,164 @@ public:
extra_hashes[ctx->state[2][0] & 3](ctx->state[2], 200, output + 64);
}
inline static void hashLiteIpbc(const uint8_t* __restrict__ input,
size_t size,
uint8_t *__restrict__ output,
cryptonight_ctx* __restrict__ ctx)
{
keccak(input, (int) size, ctx->state[0], 200);
keccak(input + size, (int) size, ctx->state[1], 200);
keccak(input + 2 * size, (int) size, ctx->state[2], 200);
uint64_t tweak1_2_0 = (*reinterpret_cast<const uint64_t*>(input + 35) ^
*(reinterpret_cast<const uint64_t*>(ctx->state[0]) + 24));
uint64_t tweak1_2_1 = (*reinterpret_cast<const uint64_t*>(input + 35 + size) ^
*(reinterpret_cast<const uint64_t*>(ctx->state[1]) + 24));
uint64_t tweak1_2_2 = (*reinterpret_cast<const uint64_t*>(input + 35 + 2 * size) ^
*(reinterpret_cast<const uint64_t*>(ctx->state[2]) + 24));
const uint8_t* l0 = ctx->memory;
const uint8_t* l1 = ctx->memory + MEM;
const uint8_t* l2 = ctx->memory + 2 * MEM;
uint64_t* h0 = reinterpret_cast<uint64_t*>(ctx->state[0]);
uint64_t* h1 = reinterpret_cast<uint64_t*>(ctx->state[1]);
uint64_t* h2 = reinterpret_cast<uint64_t*>(ctx->state[2]);
cn_explode_scratchpad<MEM, SOFT_AES>((__m128i*) h0, (__m128i*) l0);
cn_explode_scratchpad<MEM, SOFT_AES>((__m128i*) h1, (__m128i*) l1);
cn_explode_scratchpad<MEM, SOFT_AES>((__m128i*) h2, (__m128i*) l2);
uint64_t al0 = h0[0] ^h0[4];
uint64_t al1 = h1[0] ^h1[4];
uint64_t al2 = h2[0] ^h2[4];
uint64_t ah0 = h0[1] ^h0[5];
uint64_t ah1 = h1[1] ^h1[5];
uint64_t ah2 = h2[1] ^h2[5];
__m128i bx0 = _mm_set_epi64x(h0[3] ^ h0[7], h0[2] ^ h0[6]);
__m128i bx1 = _mm_set_epi64x(h1[3] ^ h1[7], h1[2] ^ h1[6]);
__m128i bx2 = _mm_set_epi64x(h2[3] ^ h2[7], h2[2] ^ h2[6]);
uint64_t idx0 = h0[0] ^h0[4];
uint64_t idx1 = h1[0] ^h1[4];
uint64_t idx2 = h2[0] ^h2[4];
for (size_t i = 0; i < ITERATIONS; i++) {
__m128i cx0;
__m128i cx1;
__m128i cx2;
if (SOFT_AES) {
cx0 = soft_aesenc((uint32_t*)&l0[idx0 & MASK], _mm_set_epi64x(ah0, al0));
cx1 = soft_aesenc((uint32_t*)&l1[idx1 & MASK], _mm_set_epi64x(ah1, al1));
cx2 = soft_aesenc((uint32_t*)&l2[idx2 & MASK], _mm_set_epi64x(ah2, al2));
}
else {
cx0 = _mm_load_si128((__m128i *) &l0[idx0 & MASK]);
cx1 = _mm_load_si128((__m128i *) &l1[idx1 & MASK]);
cx2 = _mm_load_si128((__m128i *) &l2[idx2 & MASK]);
# ifndef XMRIG_ARMv7
cx0 = vreinterpretq_m128i_u8(vaesmcq_u8(vaeseq_u8(cx0, vdupq_n_u8(0)))) ^ _mm_set_epi64x(ah0, al0);
cx1 = vreinterpretq_m128i_u8(vaesmcq_u8(vaeseq_u8(cx1, vdupq_n_u8(0)))) ^ _mm_set_epi64x(ah1, al1);
cx2 = vreinterpretq_m128i_u8(vaesmcq_u8(vaeseq_u8(cx2, vdupq_n_u8(0)))) ^ _mm_set_epi64x(ah2, al2);
# endif
}
_mm_store_si128((__m128i*) &l0[idx0 & MASK], _mm_xor_si128(bx0, cx0));
_mm_store_si128((__m128i*) &l1[idx1 & MASK], _mm_xor_si128(bx1, cx1));
_mm_store_si128((__m128i*) &l2[idx2 & MASK], _mm_xor_si128(bx2, cx2));
static const uint32_t table = 0x75310;
uint8_t tmp = reinterpret_cast<const uint8_t*>(&l0[idx0 & MASK])[11];
uint8_t index = (((tmp >> 3) & 6) | (tmp & 1)) << 1;
((uint8_t*)(&l0[idx0 & MASK]))[11] = tmp ^ ((table >> index) & 0x30);
tmp = reinterpret_cast<const uint8_t*>(&l1[idx1 & MASK])[11];
index = (((tmp >> 3) & 6) | (tmp & 1)) << 1;
((uint8_t*)(&l1[idx1 & MASK]))[11] = tmp ^ ((table >> index) & 0x30);
tmp = reinterpret_cast<const uint8_t*>(&l2[idx2 & MASK])[11];
index = (((tmp >> 3) & 6) | (tmp & 1)) << 1;
((uint8_t*)(&l2[idx2 & MASK]))[11] = tmp ^ ((table >> index) & 0x30);
idx0 = EXTRACT64(cx0);
idx1 = EXTRACT64(cx1);
idx2 = EXTRACT64(cx2);
bx0 = cx0;
bx1 = cx1;
bx2 = cx2;
uint64_t hi, lo, cl, ch;
cl = ((uint64_t*) &l0[idx0 & MASK])[0];
ch = ((uint64_t*) &l0[idx0 & MASK])[1];
lo = __umul128(idx0, cl, &hi);
al0 += hi;
ah0 += lo;
ah0 ^= tweak1_2_0;
((uint64_t*) &l0[idx0 & MASK])[0] = al0;
((uint64_t*) &l0[idx0 & MASK])[1] = ah0;
ah0 ^= tweak1_2_0;
((uint64_t*)&l0[idx0 & MASK])[1] ^= ((uint64_t*)&l0[idx0 & MASK])[0];
ah0 ^= ch;
al0 ^= cl;
idx0 = al0;
cl = ((uint64_t*) &l1[idx1 & MASK])[0];
ch = ((uint64_t*) &l1[idx1 & MASK])[1];
lo = __umul128(idx1, cl, &hi);
al1 += hi;
ah1 += lo;
ah1 ^= tweak1_2_1;
((uint64_t*) &l1[idx1 & MASK])[0] = al1;
((uint64_t*) &l1[idx1 & MASK])[1] = ah1;
ah1 ^= tweak1_2_1;
((uint64_t*)&l1[idx1 & MASK])[1] ^= ((uint64_t*)&l1[idx1 & MASK])[0];
ah1 ^= ch;
al1 ^= cl;
idx1 = al1;
cl = ((uint64_t*) &l2[idx2 & MASK])[0];
ch = ((uint64_t*) &l2[idx2 & MASK])[1];
lo = __umul128(idx2, cl, &hi);
al2 += hi;
ah2 += lo;
ah2 ^= tweak1_2_2;
((uint64_t*) &l2[idx2 & MASK])[0] = al2;
((uint64_t*) &l2[idx2 & MASK])[1] = ah2;
ah2 ^= tweak1_2_2;
((uint64_t*)&l2[idx2 & MASK])[1] ^= ((uint64_t*)&l2[idx2 & MASK])[0];
ah2 ^= ch;
al2 ^= cl;
idx2 = al2;
}
cn_implode_scratchpad<MEM, SOFT_AES>((__m128i*) l0, (__m128i*) h0);
cn_implode_scratchpad<MEM, SOFT_AES>((__m128i*) l1, (__m128i*) h1);
cn_implode_scratchpad<MEM, SOFT_AES>((__m128i*) l2, (__m128i*) h2);
keccakf(h0, 24);
keccakf(h1, 24);
keccakf(h2, 24);
extra_hashes[ctx->state[0][0] & 3](ctx->state[0], 200, output);
extra_hashes[ctx->state[1][0] & 3](ctx->state[1], 200, output + 32);
extra_hashes[ctx->state[2][0] & 3](ctx->state[2], 200, output + 64);
}
inline static void hashHeavy(const uint8_t* __restrict__ input,
size_t size,
uint8_t *__restrict__ output,
@ -2125,6 +2556,206 @@ public:
extra_hashes[ctx->state[3][0] & 3](ctx->state[3], 200, output + 96);
}
inline static void hashLiteIpbc(const uint8_t* __restrict__ input,
size_t size,
uint8_t *__restrict__ output,
cryptonight_ctx* __restrict__ ctx)
{
keccak(input, (int) size, ctx->state[0], 200);
keccak(input + size, (int) size, ctx->state[1], 200);
keccak(input + 2 * size, (int) size, ctx->state[2], 200);
keccak(input + 3 * size, (int) size, ctx->state[3], 200);
uint64_t tweak1_2_0 = (*reinterpret_cast<const uint64_t*>(input + 35) ^
*(reinterpret_cast<const uint64_t*>(ctx->state[0]) + 24));
uint64_t tweak1_2_1 = (*reinterpret_cast<const uint64_t*>(input + 35 + size) ^
*(reinterpret_cast<const uint64_t*>(ctx->state[1]) + 24));
uint64_t tweak1_2_2 = (*reinterpret_cast<const uint64_t*>(input + 35 + 2 * size) ^
*(reinterpret_cast<const uint64_t*>(ctx->state[2]) + 24));
uint64_t tweak1_2_3 = (*reinterpret_cast<const uint64_t*>(input + 35 + 3 * size) ^
*(reinterpret_cast<const uint64_t*>(ctx->state[3]) + 24));
const uint8_t* l0 = ctx->memory;
const uint8_t* l1 = ctx->memory + MEM;
const uint8_t* l2 = ctx->memory + 2 * MEM;
const uint8_t* l3 = ctx->memory + 3 * MEM;
uint64_t* h0 = reinterpret_cast<uint64_t*>(ctx->state[0]);
uint64_t* h1 = reinterpret_cast<uint64_t*>(ctx->state[1]);
uint64_t* h2 = reinterpret_cast<uint64_t*>(ctx->state[2]);
uint64_t* h3 = reinterpret_cast<uint64_t*>(ctx->state[3]);
cn_explode_scratchpad<MEM, SOFT_AES>((__m128i*) h0, (__m128i*) l0);
cn_explode_scratchpad<MEM, SOFT_AES>((__m128i*) h1, (__m128i*) l1);
cn_explode_scratchpad<MEM, SOFT_AES>((__m128i*) h2, (__m128i*) l2);
cn_explode_scratchpad<MEM, SOFT_AES>((__m128i*) h3, (__m128i*) l3);
uint64_t al0 = h0[0] ^h0[4];
uint64_t al1 = h1[0] ^h1[4];
uint64_t al2 = h2[0] ^h2[4];
uint64_t al3 = h3[0] ^h3[4];
uint64_t ah0 = h0[1] ^h0[5];
uint64_t ah1 = h1[1] ^h1[5];
uint64_t ah2 = h2[1] ^h2[5];
uint64_t ah3 = h3[1] ^h3[5];
__m128i bx0 = _mm_set_epi64x(h0[3] ^ h0[7], h0[2] ^ h0[6]);
__m128i bx1 = _mm_set_epi64x(h1[3] ^ h1[7], h1[2] ^ h1[6]);
__m128i bx2 = _mm_set_epi64x(h2[3] ^ h2[7], h2[2] ^ h2[6]);
__m128i bx3 = _mm_set_epi64x(h3[3] ^ h3[7], h3[2] ^ h3[6]);
uint64_t idx0 = h0[0] ^h0[4];
uint64_t idx1 = h1[0] ^h1[4];
uint64_t idx2 = h2[0] ^h2[4];
uint64_t idx3 = h3[0] ^h3[4];
for (size_t i = 0; i < ITERATIONS; i++) {
__m128i cx0;
__m128i cx1;
__m128i cx2;
__m128i cx3;
if (SOFT_AES) {
cx0 = soft_aesenc((uint32_t*)&l0[idx0 & MASK], _mm_set_epi64x(ah0, al0));
cx1 = soft_aesenc((uint32_t*)&l1[idx1 & MASK], _mm_set_epi64x(ah1, al1));
cx2 = soft_aesenc((uint32_t*)&l2[idx2 & MASK], _mm_set_epi64x(ah2, al2));
cx3 = soft_aesenc((uint32_t*)&l3[idx3 & MASK], _mm_set_epi64x(ah3, al3));
} else {
# ifndef XMRIG_ARMv7
cx0 = _mm_load_si128((__m128i*) &l0[idx0 & MASK]);
cx1 = _mm_load_si128((__m128i*) &l1[idx1 & MASK]);
cx2 = _mm_load_si128((__m128i*) &l2[idx2 & MASK]);
cx3 = _mm_load_si128((__m128i*) &l3[idx3 & MASK]);
cx0 = vreinterpretq_m128i_u8(vaesmcq_u8(vaeseq_u8(cx0, vdupq_n_u8(0)))) ^ _mm_set_epi64x(ah0, al0);
cx1 = vreinterpretq_m128i_u8(vaesmcq_u8(vaeseq_u8(cx1, vdupq_n_u8(0)))) ^ _mm_set_epi64x(ah1, al1);
cx2 = vreinterpretq_m128i_u8(vaesmcq_u8(vaeseq_u8(cx2, vdupq_n_u8(0)))) ^ _mm_set_epi64x(ah2, al2);
cx3 = vreinterpretq_m128i_u8(vaesmcq_u8(vaeseq_u8(cx3, vdupq_n_u8(0)))) ^ _mm_set_epi64x(ah3, al3);
# endif
}
_mm_store_si128((__m128i*) &l0[idx0 & MASK], _mm_xor_si128(bx0, cx0));
_mm_store_si128((__m128i*) &l1[idx1 & MASK], _mm_xor_si128(bx1, cx1));
_mm_store_si128((__m128i*) &l2[idx2 & MASK], _mm_xor_si128(bx2, cx2));
_mm_store_si128((__m128i*) &l3[idx3 & MASK], _mm_xor_si128(bx3, cx3));
static const uint32_t table = 0x75310;
uint8_t tmp = reinterpret_cast<const uint8_t*>(&l0[idx0 & MASK])[11];
uint8_t index = (((tmp >> 3) & 6) | (tmp & 1)) << 1;
((uint8_t*)(&l0[idx0 & MASK]))[11] = tmp ^ ((table >> index) & 0x30);
tmp = reinterpret_cast<const uint8_t*>(&l1[idx1 & MASK])[11];
index = (((tmp >> 3) & 6) | (tmp & 1)) << 1;
((uint8_t*)(&l1[idx1 & MASK]))[11] = tmp ^ ((table >> index) & 0x30);
tmp = reinterpret_cast<const uint8_t*>(&l2[idx2 & MASK])[11];
index = (((tmp >> 3) & 6) | (tmp & 1)) << 1;
((uint8_t*)(&l2[idx2 & MASK]))[11] = tmp ^ ((table >> index) & 0x30);
tmp = reinterpret_cast<const uint8_t*>(&l3[idx3 & MASK])[11];
index = (((tmp >> 3) & 6) | (tmp & 1)) << 1;
((uint8_t*)(&l3[idx3 & MASK]))[11] = tmp ^ ((table >> index) & 0x30);
idx0 = EXTRACT64(cx0);
idx1 = EXTRACT64(cx1);
idx2 = EXTRACT64(cx2);
idx3 = EXTRACT64(cx3);
bx0 = cx0;
bx1 = cx1;
bx2 = cx2;
bx3 = cx3;
uint64_t hi, lo, cl, ch;
cl = ((uint64_t*) &l0[idx0 & MASK])[0];
ch = ((uint64_t*) &l0[idx0 & MASK])[1];
lo = __umul128(idx0, cl, &hi);
al0 += hi;
ah0 += lo;
ah0 ^= tweak1_2_0;
((uint64_t*) &l0[idx0 & MASK])[0] = al0;
((uint64_t*) &l0[idx0 & MASK])[1] = ah0;
ah0 ^= tweak1_2_0;
((uint64_t*)&l0[idx0 & MASK])[1] ^= ((uint64_t*)&l0[idx0 & MASK])[0];
ah0 ^= ch;
al0 ^= cl;
idx0 = al0;
cl = ((uint64_t*) &l1[idx1 & MASK])[0];
ch = ((uint64_t*) &l1[idx1 & MASK])[1];
lo = __umul128(idx1, cl, &hi);
al1 += hi;
ah1 += lo;
ah1 ^= tweak1_2_1;
((uint64_t*) &l1[idx1 & MASK])[0] = al1;
((uint64_t*) &l1[idx1 & MASK])[1] = ah1;
ah1 ^= tweak1_2_1;
((uint64_t*)&l1[idx1 & MASK])[1] ^= ((uint64_t*)&l1[idx1 & MASK])[0];
ah1 ^= ch;
al1 ^= cl;
idx1 = al1;
cl = ((uint64_t*) &l2[idx2 & MASK])[0];
ch = ((uint64_t*) &l2[idx2 & MASK])[1];
lo = __umul128(idx2, cl, &hi);
al2 += hi;
ah2 += lo;
ah2 ^= tweak1_2_2;
((uint64_t*) &l2[idx2 & MASK])[0] = al2;
((uint64_t*) &l2[idx2 & MASK])[1] = ah2;
ah2 ^= tweak1_2_2;
((uint64_t*)&l2[idx2 & MASK])[1] ^= ((uint64_t*)&l2[idx2 & MASK])[0];
ah2 ^= ch;
al2 ^= cl;
idx2 = al2;
cl = ((uint64_t*) &l3[idx3 & MASK])[0];
ch = ((uint64_t*) &l3[idx3 & MASK])[1];
lo = __umul128(idx3, cl, &hi);
al3 += hi;
ah3 += lo;
ah3 ^= tweak1_2_3;
((uint64_t*) &l3[idx3 & MASK])[0] = al3;
((uint64_t*) &l3[idx3 & MASK])[1] = ah3;
ah3 ^= tweak1_2_3;
((uint64_t*)&l3[idx3 & MASK])[1] ^= ((uint64_t*)&l3[idx3 & MASK])[0];
ah3 ^= ch;
al3 ^= cl;
idx3 = al3;
}
cn_implode_scratchpad<MEM, SOFT_AES>((__m128i*) l0, (__m128i*) h0);
cn_implode_scratchpad<MEM, SOFT_AES>((__m128i*) l1, (__m128i*) h1);
cn_implode_scratchpad<MEM, SOFT_AES>((__m128i*) l2, (__m128i*) h2);
cn_implode_scratchpad<MEM, SOFT_AES>((__m128i*) l3, (__m128i*) h3);
keccakf(h0, 24);
keccakf(h1, 24);
keccakf(h2, 24);
keccakf(h3, 24);
extra_hashes[ctx->state[0][0] & 3](ctx->state[0], 200, output);
extra_hashes[ctx->state[1][0] & 3](ctx->state[1], 200, output + 32);
extra_hashes[ctx->state[2][0] & 3](ctx->state[2], 200, output + 64);
extra_hashes[ctx->state[3][0] & 3](ctx->state[3], 200, output + 96);
}
inline static void hashHeavy(const uint8_t* __restrict__ input,
size_t size,
uint8_t *__restrict__ output,
@ -2744,6 +3375,248 @@ public:
extra_hashes[ctx->state[4][0] & 3](ctx->state[4], 200, output + 128);
}
inline static void hashLiteIpbc (const uint8_t* __restrict__ input,
size_t size,
uint8_t *__restrict__ output,
cryptonight_ctx* __restrict__ ctx)
{
keccak(input, (int) size, ctx->state[0], 200);
keccak(input + size, (int) size, ctx->state[1], 200);
keccak(input + 2 * size, (int) size, ctx->state[2], 200);
keccak(input + 3 * size, (int) size, ctx->state[3], 200);
keccak(input + 4 * size, (int) size, ctx->state[4], 200);
uint64_t tweak1_2_0 = (*reinterpret_cast<const uint64_t*>(input + 35) ^
*(reinterpret_cast<const uint64_t*>(ctx->state[0]) + 24));
uint64_t tweak1_2_1 = (*reinterpret_cast<const uint64_t*>(input + 35 + size) ^
*(reinterpret_cast<const uint64_t*>(ctx->state[1]) + 24));
uint64_t tweak1_2_2 = (*reinterpret_cast<const uint64_t*>(input + 35 + 2 * size) ^
*(reinterpret_cast<const uint64_t*>(ctx->state[2]) + 24));
uint64_t tweak1_2_3 = (*reinterpret_cast<const uint64_t*>(input + 35 + 3 * size) ^
*(reinterpret_cast<const uint64_t*>(ctx->state[3]) + 24));
uint64_t tweak1_2_4 = (*reinterpret_cast<const uint64_t*>(input + 35 + 4 * size) ^
*(reinterpret_cast<const uint64_t*>(ctx->state[4]) + 24));
const uint8_t* l0 = ctx->memory;
const uint8_t* l1 = ctx->memory + MEM;
const uint8_t* l2 = ctx->memory + 2 * MEM;
const uint8_t* l3 = ctx->memory + 3 * MEM;
const uint8_t* l4 = ctx->memory + 4 * MEM;
uint64_t* h0 = reinterpret_cast<uint64_t*>(ctx->state[0]);
uint64_t* h1 = reinterpret_cast<uint64_t*>(ctx->state[1]);
uint64_t* h2 = reinterpret_cast<uint64_t*>(ctx->state[2]);
uint64_t* h3 = reinterpret_cast<uint64_t*>(ctx->state[3]);
uint64_t* h4 = reinterpret_cast<uint64_t*>(ctx->state[4]);
cn_explode_scratchpad<MEM, SOFT_AES>((__m128i*) h0, (__m128i*) l0);
cn_explode_scratchpad<MEM, SOFT_AES>((__m128i*) h1, (__m128i*) l1);
cn_explode_scratchpad<MEM, SOFT_AES>((__m128i*) h2, (__m128i*) l2);
cn_explode_scratchpad<MEM, SOFT_AES>((__m128i*) h3, (__m128i*) l3);
cn_explode_scratchpad<MEM, SOFT_AES>((__m128i*) h4, (__m128i*) l4);
uint64_t al0 = h0[0] ^h0[4];
uint64_t al1 = h1[0] ^h1[4];
uint64_t al2 = h2[0] ^h2[4];
uint64_t al3 = h3[0] ^h3[4];
uint64_t al4 = h4[0] ^h4[4];
uint64_t ah0 = h0[1] ^h0[5];
uint64_t ah1 = h1[1] ^h1[5];
uint64_t ah2 = h2[1] ^h2[5];
uint64_t ah3 = h3[1] ^h3[5];
uint64_t ah4 = h4[1] ^h4[5];
__m128i bx0 = _mm_set_epi64x(h0[3] ^ h0[7], h0[2] ^ h0[6]);
__m128i bx1 = _mm_set_epi64x(h1[3] ^ h1[7], h1[2] ^ h1[6]);
__m128i bx2 = _mm_set_epi64x(h2[3] ^ h2[7], h2[2] ^ h2[6]);
__m128i bx3 = _mm_set_epi64x(h3[3] ^ h3[7], h3[2] ^ h3[6]);
__m128i bx4 = _mm_set_epi64x(h4[3] ^ h4[7], h4[2] ^ h4[6]);
uint64_t idx0 = h0[0] ^h0[4];
uint64_t idx1 = h1[0] ^h1[4];
uint64_t idx2 = h2[0] ^h2[4];
uint64_t idx3 = h3[0] ^h3[4];
uint64_t idx4 = h4[0] ^h4[4];
for (size_t i = 0; i < ITERATIONS; i++) {
__m128i cx0;
__m128i cx1;
__m128i cx2;
__m128i cx3;
__m128i cx4;
if (SOFT_AES) {
cx0 = soft_aesenc((uint32_t*)&l0[idx0 & MASK], _mm_set_epi64x(ah0, al0));
cx1 = soft_aesenc((uint32_t*)&l1[idx1 & MASK], _mm_set_epi64x(ah1, al1));
cx2 = soft_aesenc((uint32_t*)&l2[idx2 & MASK], _mm_set_epi64x(ah2, al2));
cx3 = soft_aesenc((uint32_t*)&l3[idx3 & MASK], _mm_set_epi64x(ah3, al3));
cx4 = soft_aesenc((uint32_t*)&l4[idx4 & MASK], _mm_set_epi64x(ah4, al4));
} else {
# ifndef XMRIG_ARMv7
cx0 = _mm_load_si128((__m128i*) &l0[idx0 & MASK]);
cx1 = _mm_load_si128((__m128i*) &l1[idx1 & MASK]);
cx2 = _mm_load_si128((__m128i*) &l2[idx2 & MASK]);
cx3 = _mm_load_si128((__m128i*) &l3[idx3 & MASK]);
cx4 = _mm_load_si128((__m128i*) &l4[idx4 & MASK]);
cx0 = vreinterpretq_m128i_u8(vaesmcq_u8(vaeseq_u8(cx0, vdupq_n_u8(0)))) ^ _mm_set_epi64x(ah0, al0);
cx1 = vreinterpretq_m128i_u8(vaesmcq_u8(vaeseq_u8(cx1, vdupq_n_u8(0)))) ^ _mm_set_epi64x(ah1, al1);
cx2 = vreinterpretq_m128i_u8(vaesmcq_u8(vaeseq_u8(cx2, vdupq_n_u8(0)))) ^ _mm_set_epi64x(ah2, al2);
cx3 = vreinterpretq_m128i_u8(vaesmcq_u8(vaeseq_u8(cx3, vdupq_n_u8(0)))) ^ _mm_set_epi64x(ah3, al3);
cx4 = vreinterpretq_m128i_u8(vaesmcq_u8(vaeseq_u8(cx4, vdupq_n_u8(0)))) ^ _mm_set_epi64x(ah4, al4);
# endif
}
_mm_store_si128((__m128i*) &l0[idx0 & MASK], _mm_xor_si128(bx0, cx0));
_mm_store_si128((__m128i*) &l1[idx1 & MASK], _mm_xor_si128(bx1, cx1));
_mm_store_si128((__m128i*) &l2[idx2 & MASK], _mm_xor_si128(bx2, cx2));
_mm_store_si128((__m128i*) &l3[idx3 & MASK], _mm_xor_si128(bx3, cx3));
_mm_store_si128((__m128i*) &l4[idx4 & MASK], _mm_xor_si128(bx4, cx4));
static const uint32_t table = 0x75310;
uint8_t tmp = reinterpret_cast<const uint8_t*>(&l0[idx0 & MASK])[11];
uint8_t index = (((tmp >> 3) & 6) | (tmp & 1)) << 1;
((uint8_t*)(&l0[idx0 & MASK]))[11] = tmp ^ ((table >> index) & 0x30);
tmp = reinterpret_cast<const uint8_t*>(&l1[idx1 & MASK])[11];
index = (((tmp >> 3) & 6) | (tmp & 1)) << 1;
((uint8_t*)(&l1[idx1 & MASK]))[11] = tmp ^ ((table >> index) & 0x30);
tmp = reinterpret_cast<const uint8_t*>(&l2[idx2 & MASK])[11];
index = (((tmp >> 3) & 6) | (tmp & 1)) << 1;
((uint8_t*)(&l2[idx2 & MASK]))[11] = tmp ^ ((table >> index) & 0x30);
tmp = reinterpret_cast<const uint8_t*>(&l3[idx3 & MASK])[11];
index = (((tmp >> 3) & 6) | (tmp & 1)) << 1;
((uint8_t*)(&l3[idx3 & MASK]))[11] = tmp ^ ((table >> index) & 0x30);
tmp = reinterpret_cast<const uint8_t*>(&l4[idx4 & MASK])[11];
index = (((tmp >> 3) & 6) | (tmp & 1)) << 1;
((uint8_t*)(&l4[idx4 & MASK]))[11] = tmp ^ ((table >> index) & 0x30);
idx0 = EXTRACT64(cx0);
idx1 = EXTRACT64(cx1);
idx2 = EXTRACT64(cx2);
idx3 = EXTRACT64(cx3);
idx4 = EXTRACT64(cx4);
bx0 = cx0;
bx1 = cx1;
bx2 = cx2;
bx3 = cx3;
bx4 = cx4;
uint64_t hi, lo, cl, ch;
cl = ((uint64_t*) &l0[idx0 & MASK])[0];
ch = ((uint64_t*) &l0[idx0 & MASK])[1];
lo = __umul128(idx0, cl, &hi);
al0 += hi;
ah0 += lo;
ah0 ^= tweak1_2_0;
((uint64_t*) &l0[idx0 & MASK])[0] = al0;
((uint64_t*) &l0[idx0 & MASK])[1] = ah0;
ah0 ^= tweak1_2_0;
((uint64_t*)&l0[idx0 & MASK])[1] ^= ((uint64_t*)&l0[idx0 & MASK])[0];
ah0 ^= ch;
al0 ^= cl;
idx0 = al0;
cl = ((uint64_t*) &l1[idx1 & MASK])[0];
ch = ((uint64_t*) &l1[idx1 & MASK])[1];
lo = __umul128(idx1, cl, &hi);
al1 += hi;
ah1 += lo;
ah1 ^= tweak1_2_1;
((uint64_t*) &l1[idx1 & MASK])[0] = al1;
((uint64_t*) &l1[idx1 & MASK])[1] = ah1;
ah1 ^= tweak1_2_1;
((uint64_t*)&l1[idx1 & MASK])[1] ^= ((uint64_t*)&l1[idx1 & MASK])[0];
ah1 ^= ch;
al1 ^= cl;
idx1 = al1;
cl = ((uint64_t*) &l2[idx2 & MASK])[0];
ch = ((uint64_t*) &l2[idx2 & MASK])[1];
lo = __umul128(idx2, cl, &hi);
al2 += hi;
ah2 += lo;
ah2 ^= tweak1_2_2;
((uint64_t*) &l2[idx2 & MASK])[0] = al2;
((uint64_t*) &l2[idx2 & MASK])[1] = ah2;
ah2 ^= tweak1_2_2;
((uint64_t*)&l2[idx2 & MASK])[1] ^= ((uint64_t*)&l2[idx2 & MASK])[0];
ah2 ^= ch;
al2 ^= cl;
idx2 = al2;
cl = ((uint64_t*) &l3[idx3 & MASK])[0];
ch = ((uint64_t*) &l3[idx3 & MASK])[1];
lo = __umul128(idx3, cl, &hi);
al3 += hi;
ah3 += lo;
ah3 ^= tweak1_2_3;
((uint64_t*) &l3[idx3 & MASK])[0] = al3;
((uint64_t*) &l3[idx3 & MASK])[1] = ah3;
ah3 ^= tweak1_2_3;
((uint64_t*)&l3[idx3 & MASK])[1] ^= ((uint64_t*)&l3[idx3 & MASK])[0];
ah3 ^= ch;
al3 ^= cl;
idx3 = al3;
cl = ((uint64_t*) &l4[idx4 & MASK])[0];
ch = ((uint64_t*) &l4[idx4 & MASK])[1];
lo = __umul128(idx4, cl, &hi);
al4 += hi;
ah4 += lo;
ah4 ^= tweak1_2_4;
((uint64_t*) &l4[idx4 & MASK])[0] = al4;
((uint64_t*) &l4[idx4 & MASK])[1] = ah4;
ah4 ^= tweak1_2_4;
((uint64_t*)&l4[idx4 & MASK])[1] ^= ((uint64_t*)&l4[idx4 & MASK])[0];
ah4 ^= ch;
al4 ^= cl;
idx4 = al4;
}
cn_implode_scratchpad<MEM, SOFT_AES>((__m128i*) l0, (__m128i*) h0);
cn_implode_scratchpad<MEM, SOFT_AES>((__m128i*) l1, (__m128i*) h1);
cn_implode_scratchpad<MEM, SOFT_AES>((__m128i*) l2, (__m128i*) h2);
cn_implode_scratchpad<MEM, SOFT_AES>((__m128i*) l3, (__m128i*) h3);
cn_implode_scratchpad<MEM, SOFT_AES>((__m128i*) l4, (__m128i*) h4);
keccakf(h0, 24);
keccakf(h1, 24);
keccakf(h2, 24);
keccakf(h3, 24);
keccakf(h4, 24);
extra_hashes[ctx->state[0][0] & 3](ctx->state[0], 200, output);
extra_hashes[ctx->state[1][0] & 3](ctx->state[1], 200, output + 32);
extra_hashes[ctx->state[2][0] & 3](ctx->state[2], 200, output + 64);
extra_hashes[ctx->state[3][0] & 3](ctx->state[3], 200, output + 96);
extra_hashes[ctx->state[4][0] & 3](ctx->state[4], 200, output + 128);
}
inline static void hashHeavy(const uint8_t* __restrict__ input,
size_t size,
uint8_t *__restrict__ output,

View file

@ -26,130 +26,174 @@
const static uint8_t test_input[] = {
0x01, 0x00, 0xFB, 0x8E, 0x8A, 0xC8, 0x05, 0x89, 0x93, 0x23, 0x37, 0x1B, 0xB7, 0x90, 0xDB, 0x19,
0x21, 0x8A, 0xFD, 0x8D, 0xB8, 0xE3, 0x75, 0x5D, 0x8B, 0x90, 0xF3, 0x9B, 0x3D, 0x55, 0x06, 0xA9,
0xAB, 0xCE, 0x4F, 0xA9, 0x12, 0x24, 0x45, 0x00, 0x00, 0x00, 0x00, 0xEE, 0x81, 0x46, 0xD4, 0x9F,
0xA9, 0x3E, 0xE7, 0x24, 0xDE, 0xB5, 0x7D, 0x12, 0xCB, 0xC6, 0xC6, 0xF3, 0xB9, 0x24, 0xD9, 0x46,
0x12, 0x7C, 0x7A, 0x97, 0x41, 0x8F, 0x93, 0x48, 0x82, 0x8F, 0x0F, 0x02,
0x03, 0x05, 0xA0, 0xDB, 0xD6, 0xBF, 0x05, 0xCF, 0x16, 0xE5, 0x03, 0xF3, 0xA6, 0x6F, 0x78, 0x00,
0x7C, 0xBF, 0x34, 0x14, 0x43, 0x32, 0xEC, 0xBF, 0xC2, 0x2E, 0xD9, 0x5C, 0x87, 0x00, 0x38, 0x3B,
0x30, 0x9A, 0xCE, 0x19, 0x23, 0xA0, 0x96, 0x4B, 0x00, 0x00, 0x00, 0x08, 0xBA, 0x93, 0x9A, 0x62,
0x72, 0x4C, 0x0D, 0x75, 0x81, 0xFC, 0xE5, 0x76, 0x1E, 0x9D, 0x8A, 0x0E, 0x6A, 0x1C, 0x3F, 0x92,
0x4F, 0xDD, 0x84, 0x93, 0xD1, 0x11, 0x56, 0x49, 0xC0, 0x5E, 0xB6, 0x01,
0x01, 0x00, 0xFB, 0x8E, 0x8A, 0xC8, 0x05, 0x89, 0x93, 0x23, 0x37, 0x1B, 0xB7, 0x90, 0xDB, 0x19,
0x21, 0x8A, 0xFD, 0x8D, 0xB8, 0xE3, 0x75, 0x5D, 0x8B, 0x90, 0xF3, 0x9B, 0x3D, 0x55, 0x06, 0xA9,
0xAB, 0xCE, 0x4F, 0xA9, 0x12, 0x24, 0x45, 0x00, 0x00, 0x00, 0x00, 0xEE, 0x81, 0x46, 0xD4, 0x9F,
0xA9, 0x3E, 0xE7, 0x24, 0xDE, 0xB5, 0x7D, 0x12, 0xCB, 0xC6, 0xC6, 0xF3, 0xB9, 0x24, 0xD9, 0x46,
0x12, 0x7C, 0x7A, 0x97, 0x41, 0x8F, 0x93, 0x48, 0x82, 0x8F, 0x0F, 0x02,
0x03, 0x05, 0xA0, 0xDB, 0xD6, 0xBF, 0x05, 0xCF, 0x16, 0xE5, 0x03, 0xF3, 0xA6, 0x6F, 0x78, 0x00,
0x7C, 0xBF, 0x34, 0x14, 0x43, 0x32, 0xEC, 0xBF, 0xC2, 0x2E, 0xD9, 0x5C, 0x87, 0x00, 0x38, 0x3B,
0x30, 0x9A, 0xCE, 0x19, 0x23, 0xA0, 0x96, 0x4B, 0x00, 0x00, 0x00, 0x08, 0xBA, 0x93, 0x9A, 0x62,
0x72, 0x4C, 0x0D, 0x75, 0x81, 0xFC, 0xE5, 0x76, 0x1E, 0x9D, 0x8A, 0x0E, 0x6A, 0x1C, 0x3F, 0x92,
0x4F, 0xDD, 0x84, 0x93, 0xD1, 0x11, 0x56, 0x49, 0xC0, 0x5E, 0xB6, 0x01,
0x01, 0x00, 0xFB, 0x8E, 0x8A, 0xC8, 0x05, 0x89, 0x93, 0x23, 0x37, 0x1B, 0xB7, 0x90, 0xDB, 0x19,
0x21, 0x8A, 0xFD, 0x8D, 0xB8, 0xE3, 0x75, 0x5D, 0x8B, 0x90, 0xF3, 0x9B, 0x3D, 0x55, 0x06, 0xA9,
0xAB, 0xCE, 0x4F, 0xA9, 0x12, 0x24, 0x45, 0x00, 0x00, 0x00, 0x00, 0xEE, 0x81, 0x46, 0xD4, 0x9F,
0xA9, 0x3E, 0xE7, 0x24, 0xDE, 0xB5, 0x7D, 0x12, 0xCB, 0xC6, 0xC6, 0xF3, 0xB9, 0x24, 0xD9, 0x46,
0x12, 0x7C, 0x7A, 0x97, 0x41, 0x8F, 0x93, 0x48, 0x82, 0x8F, 0x0F, 0x02,
0x03, 0x05, 0xA0, 0xDB, 0xD6, 0xBF, 0x05, 0xCF, 0x16, 0xE5, 0x03, 0xF3, 0xA6, 0x6F, 0x78, 0x00,
0x7C, 0xBF, 0x34, 0x14, 0x43, 0x32, 0xEC, 0xBF, 0xC2, 0x2E, 0xD9, 0x5C, 0x87, 0x00, 0x38, 0x3B,
0x30, 0x9A, 0xCE, 0x19, 0x23, 0xA0, 0x96, 0x4B, 0x00, 0x00, 0x00, 0x08, 0xBA, 0x93, 0x9A, 0x62,
0x72, 0x4C, 0x0D, 0x75, 0x81, 0xFC, 0xE5, 0x76, 0x1E, 0x9D, 0x8A, 0x0E, 0x6A, 0x1C, 0x3F, 0x92,
0x4F, 0xDD, 0x84, 0x93, 0xD1, 0x11, 0x56, 0x49, 0xC0, 0x5E, 0xB6, 0x01
0x01, 0x00, 0xFB, 0x8E, 0x8A, 0xC8, 0x05, 0x89, 0x93, 0x23, 0x37, 0x1B, 0xB7, 0x90, 0xDB, 0x19,
0x21, 0x8A, 0xFD, 0x8D, 0xB8, 0xE3, 0x75, 0x5D, 0x8B, 0x90, 0xF3, 0x9B, 0x3D, 0x55, 0x06, 0xA9,
0xAB, 0xCE, 0x4F, 0xA9, 0x12, 0x24, 0x45, 0x00, 0x00, 0x00, 0x00, 0xEE, 0x81, 0x46, 0xD4, 0x9F,
0xA9, 0x3E, 0xE7, 0x24, 0xDE, 0xB5, 0x7D, 0x12, 0xCB, 0xC6, 0xC6, 0xF3, 0xB9, 0x24, 0xD9, 0x46,
0x12, 0x7C, 0x7A, 0x97, 0x41, 0x8F, 0x93, 0x48, 0x82, 0x8F, 0x0F, 0x02,
0x03, 0x05, 0xA0, 0xDB, 0xD6, 0xBF, 0x05, 0xCF, 0x16, 0xE5, 0x03, 0xF3, 0xA6, 0x6F, 0x78, 0x00,
0x7C, 0xBF, 0x34, 0x14, 0x43, 0x32, 0xEC, 0xBF, 0xC2, 0x2E, 0xD9, 0x5C, 0x87, 0x00, 0x38, 0x3B,
0x30, 0x9A, 0xCE, 0x19, 0x23, 0xA0, 0x96, 0x4B, 0x00, 0x00, 0x00, 0x08, 0xBA, 0x93, 0x9A, 0x62,
0x72, 0x4C, 0x0D, 0x75, 0x81, 0xFC, 0xE5, 0x76, 0x1E, 0x9D, 0x8A, 0x0E, 0x6A, 0x1C, 0x3F, 0x92,
0x4F, 0xDD, 0x84, 0x93, 0xD1, 0x11, 0x56, 0x49, 0xC0, 0x5E, 0xB6, 0x01,
0x01, 0x00, 0xFB, 0x8E, 0x8A, 0xC8, 0x05, 0x89, 0x93, 0x23, 0x37, 0x1B, 0xB7, 0x90, 0xDB, 0x19,
0x21, 0x8A, 0xFD, 0x8D, 0xB8, 0xE3, 0x75, 0x5D, 0x8B, 0x90, 0xF3, 0x9B, 0x3D, 0x55, 0x06, 0xA9,
0xAB, 0xCE, 0x4F, 0xA9, 0x12, 0x24, 0x45, 0x00, 0x00, 0x00, 0x00, 0xEE, 0x81, 0x46, 0xD4, 0x9F,
0xA9, 0x3E, 0xE7, 0x24, 0xDE, 0xB5, 0x7D, 0x12, 0xCB, 0xC6, 0xC6, 0xF3, 0xB9, 0x24, 0xD9, 0x46,
0x12, 0x7C, 0x7A, 0x97, 0x41, 0x8F, 0x93, 0x48, 0x82, 0x8F, 0x0F, 0x02,
0x03, 0x05, 0xA0, 0xDB, 0xD6, 0xBF, 0x05, 0xCF, 0x16, 0xE5, 0x03, 0xF3, 0xA6, 0x6F, 0x78, 0x00,
0x7C, 0xBF, 0x34, 0x14, 0x43, 0x32, 0xEC, 0xBF, 0xC2, 0x2E, 0xD9, 0x5C, 0x87, 0x00, 0x38, 0x3B,
0x30, 0x9A, 0xCE, 0x19, 0x23, 0xA0, 0x96, 0x4B, 0x00, 0x00, 0x00, 0x08, 0xBA, 0x93, 0x9A, 0x62,
0x72, 0x4C, 0x0D, 0x75, 0x81, 0xFC, 0xE5, 0x76, 0x1E, 0x9D, 0x8A, 0x0E, 0x6A, 0x1C, 0x3F, 0x92,
0x4F, 0xDD, 0x84, 0x93, 0xD1, 0x11, 0x56, 0x49, 0xC0, 0x5E, 0xB6, 0x01,
0x01, 0x00, 0xFB, 0x8E, 0x8A, 0xC8, 0x05, 0x89, 0x93, 0x23, 0x37, 0x1B, 0xB7, 0x90, 0xDB, 0x19,
0x21, 0x8A, 0xFD, 0x8D, 0xB8, 0xE3, 0x75, 0x5D, 0x8B, 0x90, 0xF3, 0x9B, 0x3D, 0x55, 0x06, 0xA9,
0xAB, 0xCE, 0x4F, 0xA9, 0x12, 0x24, 0x45, 0x00, 0x00, 0x00, 0x00, 0xEE, 0x81, 0x46, 0xD4, 0x9F,
0xA9, 0x3E, 0xE7, 0x24, 0xDE, 0xB5, 0x7D, 0x12, 0xCB, 0xC6, 0xC6, 0xF3, 0xB9, 0x24, 0xD9, 0x46,
0x12, 0x7C, 0x7A, 0x97, 0x41, 0x8F, 0x93, 0x48, 0x82, 0x8F, 0x0F, 0x02,
0x03, 0x05, 0xA0, 0xDB, 0xD6, 0xBF, 0x05, 0xCF, 0x16, 0xE5, 0x03, 0xF3, 0xA6, 0x6F, 0x78, 0x00,
0x7C, 0xBF, 0x34, 0x14, 0x43, 0x32, 0xEC, 0xBF, 0xC2, 0x2E, 0xD9, 0x5C, 0x87, 0x00, 0x38, 0x3B,
0x30, 0x9A, 0xCE, 0x19, 0x23, 0xA0, 0x96, 0x4B, 0x00, 0x00, 0x00, 0x08, 0xBA, 0x93, 0x9A, 0x62,
0x72, 0x4C, 0x0D, 0x75, 0x81, 0xFC, 0xE5, 0x76, 0x1E, 0x9D, 0x8A, 0x0E, 0x6A, 0x1C, 0x3F, 0x92,
0x4F, 0xDD, 0x84, 0x93, 0xD1, 0x11, 0x56, 0x49, 0xC0, 0x5E, 0xB6, 0x01
};
const static uint8_t test_output[] = {
0x1B, 0x60, 0x6A, 0x3F, 0x4A, 0x07, 0xD6, 0x48, 0x9A, 0x1B, 0xCD, 0x07, 0x69, 0x7B, 0xD1, 0x66,
0x96, 0xB6, 0x1C, 0x8A, 0xE9, 0x82, 0xF6, 0x1A, 0x90, 0x16, 0x0F, 0x4E, 0x52, 0x82, 0x8A, 0x7F,
0x1A, 0x3F, 0xFB, 0xEE, 0x90, 0x9B, 0x42, 0x0D, 0x91, 0xF7, 0xBE, 0x6E, 0x5F, 0xB5, 0x6D, 0xB7,
0x1B, 0x31, 0x10, 0xD8, 0x86, 0x01, 0x1E, 0x87, 0x7E, 0xE5, 0x78, 0x6A, 0xFD, 0x08, 0x01, 0x00,
0x1B, 0x60, 0x6A, 0x3F, 0x4A, 0x07, 0xD6, 0x48, 0x9A, 0x1B, 0xCD, 0x07, 0x69, 0x7B, 0xD1, 0x66,
0x96, 0xB6, 0x1C, 0x8A, 0xE9, 0x82, 0xF6, 0x1A, 0x90, 0x16, 0x0F, 0x4E, 0x52, 0x82, 0x8A, 0x7F,
0x1A, 0x3F, 0xFB, 0xEE, 0x90, 0x9B, 0x42, 0x0D, 0x91, 0xF7, 0xBE, 0x6E, 0x5F, 0xB5, 0x6D, 0xB7,
0x1B, 0x31, 0x10, 0xD8, 0x86, 0x01, 0x1E, 0x87, 0x7E, 0xE5, 0x78, 0x6A, 0xFD, 0x08, 0x01, 0x00,
0x1B, 0x60, 0x6A, 0x3F, 0x4A, 0x07, 0xD6, 0x48, 0x9A, 0x1B, 0xCD, 0x07, 0x69, 0x7B, 0xD1, 0x66,
0x96, 0xB6, 0x1C, 0x8A, 0xE9, 0x82, 0xF6, 0x1A, 0x90, 0x16, 0x0F, 0x4E, 0x52, 0x82, 0x8A, 0x7F,
0x1A, 0x3F, 0xFB, 0xEE, 0x90, 0x9B, 0x42, 0x0D, 0x91, 0xF7, 0xBE, 0x6E, 0x5F, 0xB5, 0x6D, 0xB7,
0x1B, 0x31, 0x10, 0xD8, 0x86, 0x01, 0x1E, 0x87, 0x7E, 0xE5, 0x78, 0x6A, 0xFD, 0x08, 0x01, 0x00,
0x1B, 0x60, 0x6A, 0x3F, 0x4A, 0x07, 0xD6, 0x48, 0x9A, 0x1B, 0xCD, 0x07, 0x69, 0x7B, 0xD1, 0x66,
0x96, 0xB6, 0x1C, 0x8A, 0xE9, 0x82, 0xF6, 0x1A, 0x90, 0x16, 0x0F, 0x4E, 0x52, 0x82, 0x8A, 0x7F,
0x1A, 0x3F, 0xFB, 0xEE, 0x90, 0x9B, 0x42, 0x0D, 0x91, 0xF7, 0xBE, 0x6E, 0x5F, 0xB5, 0x6D, 0xB7,
0x1B, 0x31, 0x10, 0xD8, 0x86, 0x01, 0x1E, 0x87, 0x7E, 0xE5, 0x78, 0x6A, 0xFD, 0x08, 0x01, 0x00,
0x1B, 0x60, 0x6A, 0x3F, 0x4A, 0x07, 0xD6, 0x48, 0x9A, 0x1B, 0xCD, 0x07, 0x69, 0x7B, 0xD1, 0x66,
0x96, 0xB6, 0x1C, 0x8A, 0xE9, 0x82, 0xF6, 0x1A, 0x90, 0x16, 0x0F, 0x4E, 0x52, 0x82, 0x8A, 0x7F,
0x1A, 0x3F, 0xFB, 0xEE, 0x90, 0x9B, 0x42, 0x0D, 0x91, 0xF7, 0xBE, 0x6E, 0x5F, 0xB5, 0x6D, 0xB7,
0x1B, 0x31, 0x10, 0xD8, 0x86, 0x01, 0x1E, 0x87, 0x7E, 0xE5, 0x78, 0x6A, 0xFD, 0x08, 0x01, 0x00
0x1B, 0x60, 0x6A, 0x3F, 0x4A, 0x07, 0xD6, 0x48, 0x9A, 0x1B, 0xCD, 0x07, 0x69, 0x7B, 0xD1, 0x66,
0x96, 0xB6, 0x1C, 0x8A, 0xE9, 0x82, 0xF6, 0x1A, 0x90, 0x16, 0x0F, 0x4E, 0x52, 0x82, 0x8A, 0x7F,
0x1A, 0x3F, 0xFB, 0xEE, 0x90, 0x9B, 0x42, 0x0D, 0x91, 0xF7, 0xBE, 0x6E, 0x5F, 0xB5, 0x6D, 0xB7,
0x1B, 0x31, 0x10, 0xD8, 0x86, 0x01, 0x1E, 0x87, 0x7E, 0xE5, 0x78, 0x6A, 0xFD, 0x08, 0x01, 0x00
};
const static uint8_t test_output_light[] = {
0x28, 0xA2, 0x2B, 0xAD, 0x3F, 0x93, 0xD1, 0x40, 0x8F, 0xCA, 0x47, 0x2E, 0xB5, 0xAD, 0x1C, 0xBE,
0x75, 0xF2, 0x1D, 0x05, 0x3C, 0x8C, 0xE5, 0xB3, 0xAF, 0x10, 0x5A, 0x57, 0x71, 0x3E, 0x21, 0xDD,
0x36, 0x95, 0xB4, 0xB5, 0x3B, 0xB0, 0x03, 0x58, 0xB0, 0xAD, 0x38, 0xDC, 0x16, 0x0F, 0xEB, 0x9E,
0x00, 0x4E, 0xEC, 0xE0, 0x9B, 0x83, 0xA7, 0x2E, 0xF6, 0xBA, 0x98, 0x64, 0xD3, 0x51, 0x0C, 0x88,
0x28, 0xA2, 0x2B, 0xAD, 0x3F, 0x93, 0xD1, 0x40, 0x8F, 0xCA, 0x47, 0x2E, 0xB5, 0xAD, 0x1C, 0xBE,
0x75, 0xF2, 0x1D, 0x05, 0x3C, 0x8C, 0xE5, 0xB3, 0xAF, 0x10, 0x5A, 0x57, 0x71, 0x3E, 0x21, 0xDD,
0x36, 0x95, 0xB4, 0xB5, 0x3B, 0xB0, 0x03, 0x58, 0xB0, 0xAD, 0x38, 0xDC, 0x16, 0x0F, 0xEB, 0x9E,
0x00, 0x4E, 0xEC, 0xE0, 0x9B, 0x83, 0xA7, 0x2E, 0xF6, 0xBA, 0x98, 0x64, 0xD3, 0x51, 0x0C, 0x88,
0x28, 0xA2, 0x2B, 0xAD, 0x3F, 0x93, 0xD1, 0x40, 0x8F, 0xCA, 0x47, 0x2E, 0xB5, 0xAD, 0x1C, 0xBE,
0x75, 0xF2, 0x1D, 0x05, 0x3C, 0x8C, 0xE5, 0xB3, 0xAF, 0x10, 0x5A, 0x57, 0x71, 0x3E, 0x21, 0xDD,
0x36, 0x95, 0xB4, 0xB5, 0x3B, 0xB0, 0x03, 0x58, 0xB0, 0xAD, 0x38, 0xDC, 0x16, 0x0F, 0xEB, 0x9E,
0x00, 0x4E, 0xEC, 0xE0, 0x9B, 0x83, 0xA7, 0x2E, 0xF6, 0xBA, 0x98, 0x64, 0xD3, 0x51, 0x0C, 0x88,
0x28, 0xA2, 0x2B, 0xAD, 0x3F, 0x93, 0xD1, 0x40, 0x8F, 0xCA, 0x47, 0x2E, 0xB5, 0xAD, 0x1C, 0xBE,
0x75, 0xF2, 0x1D, 0x05, 0x3C, 0x8C, 0xE5, 0xB3, 0xAF, 0x10, 0x5A, 0x57, 0x71, 0x3E, 0x21, 0xDD,
0x36, 0x95, 0xB4, 0xB5, 0x3B, 0xB0, 0x03, 0x58, 0xB0, 0xAD, 0x38, 0xDC, 0x16, 0x0F, 0xEB, 0x9E,
0x00, 0x4E, 0xEC, 0xE0, 0x9B, 0x83, 0xA7, 0x2E, 0xF6, 0xBA, 0x98, 0x64, 0xD3, 0x51, 0x0C, 0x88,
0x28, 0xA2, 0x2B, 0xAD, 0x3F, 0x93, 0xD1, 0x40, 0x8F, 0xCA, 0x47, 0x2E, 0xB5, 0xAD, 0x1C, 0xBE,
0x75, 0xF2, 0x1D, 0x05, 0x3C, 0x8C, 0xE5, 0xB3, 0xAF, 0x10, 0x5A, 0x57, 0x71, 0x3E, 0x21, 0xDD,
0x36, 0x95, 0xB4, 0xB5, 0x3B, 0xB0, 0x03, 0x58, 0xB0, 0xAD, 0x38, 0xDC, 0x16, 0x0F, 0xEB, 0x9E,
0x00, 0x4E, 0xEC, 0xE0, 0x9B, 0x83, 0xA7, 0x2E, 0xF6, 0xBA, 0x98, 0x64, 0xD3, 0x51, 0x0C, 0x88
0x28, 0xA2, 0x2B, 0xAD, 0x3F, 0x93, 0xD1, 0x40, 0x8F, 0xCA, 0x47, 0x2E, 0xB5, 0xAD, 0x1C, 0xBE,
0x75, 0xF2, 0x1D, 0x05, 0x3C, 0x8C, 0xE5, 0xB3, 0xAF, 0x10, 0x5A, 0x57, 0x71, 0x3E, 0x21, 0xDD,
0x36, 0x95, 0xB4, 0xB5, 0x3B, 0xB0, 0x03, 0x58, 0xB0, 0xAD, 0x38, 0xDC, 0x16, 0x0F, 0xEB, 0x9E,
0x00, 0x4E, 0xEC, 0xE0, 0x9B, 0x83, 0xA7, 0x2E, 0xF6, 0xBA, 0x98, 0x64, 0xD3, 0x51, 0x0C, 0x88
};
const static uint8_t test_input_monero_v2_pow_0[] = {
0x85, 0x19, 0xe0, 0x39, 0x17, 0x2b, 0x0d, 0x70, 0xe5, 0xca, 0x7b, 0x33, 0x83, 0xd6, 0xb3, 0x16,
0x73, 0x15, 0xa4, 0x22, 0x74, 0x7b, 0x73, 0xf0, 0x19, 0xcf, 0x95, 0x28, 0xf0, 0xfd, 0xe3, 0x41,
0xfd, 0x0f, 0x2a, 0x63, 0x03, 0x0b, 0xa6, 0x45, 0x05, 0x25, 0xcf, 0x6d, 0xe3, 0x18, 0x37, 0x66,
0x9a, 0xf6, 0xf1, 0xdf, 0x81, 0x31, 0xfa, 0xf5, 0x0a, 0xaa, 0xb8, 0xd3, 0xa7, 0x40, 0x55, 0x89
0x85, 0x19, 0xe0, 0x39, 0x17, 0x2b, 0x0d, 0x70, 0xe5, 0xca, 0x7b, 0x33, 0x83, 0xd6, 0xb3, 0x16,
0x73, 0x15, 0xa4, 0x22, 0x74, 0x7b, 0x73, 0xf0, 0x19, 0xcf, 0x95, 0x28, 0xf0, 0xfd, 0xe3, 0x41,
0xfd, 0x0f, 0x2a, 0x63, 0x03, 0x0b, 0xa6, 0x45, 0x05, 0x25, 0xcf, 0x6d, 0xe3, 0x18, 0x37, 0x66,
0x9a, 0xf6, 0xf1, 0xdf, 0x81, 0x31, 0xfa, 0xf5, 0x0a, 0xaa, 0xb8, 0xd3, 0xa7, 0x40, 0x55, 0x89
};
const static uint8_t test_input_monero_v2_pow_1[] = {
0x37, 0xa6, 0x36, 0xd7, 0xda, 0xfd, 0xf2, 0x59, 0xb7, 0x28, 0x7e, 0xdd, 0xca, 0x2f, 0x58, 0x09,
0x9e, 0x98, 0x61, 0x9d, 0x2f, 0x99, 0xbd, 0xb8, 0x96, 0x9d, 0x7b, 0x14, 0x49, 0x81, 0x02, 0xcc,
0x06, 0x52, 0x01, 0xc8, 0xbe, 0x90, 0xbd, 0x77, 0x73, 0x23, 0xf4, 0x49, 0x84, 0x8b, 0x21, 0x5d,
0x29, 0x77, 0xc9, 0x2c, 0x4c, 0x1c, 0x2d, 0xa3, 0x6a, 0xb4, 0x6b, 0x2e, 0x38, 0x96, 0x89, 0xed,
0x97, 0xc1, 0x8f, 0xec, 0x08, 0xcd, 0x3b, 0x03, 0x23, 0x5c, 0x5e, 0x4c, 0x62, 0xa3, 0x7a, 0xd8,
0x8c, 0x7b, 0x67, 0x93, 0x24, 0x95, 0xa7, 0x10, 0x90, 0xe8, 0x5d, 0xd4, 0x02, 0x0a, 0x93, 0x00
0x37, 0xa6, 0x36, 0xd7, 0xda, 0xfd, 0xf2, 0x59, 0xb7, 0x28, 0x7e, 0xdd, 0xca, 0x2f, 0x58, 0x09,
0x9e, 0x98, 0x61, 0x9d, 0x2f, 0x99, 0xbd, 0xb8, 0x96, 0x9d, 0x7b, 0x14, 0x49, 0x81, 0x02, 0xcc,
0x06, 0x52, 0x01, 0xc8, 0xbe, 0x90, 0xbd, 0x77, 0x73, 0x23, 0xf4, 0x49, 0x84, 0x8b, 0x21, 0x5d,
0x29, 0x77, 0xc9, 0x2c, 0x4c, 0x1c, 0x2d, 0xa3, 0x6a, 0xb4, 0x6b, 0x2e, 0x38, 0x96, 0x89, 0xed,
0x97, 0xc1, 0x8f, 0xec, 0x08, 0xcd, 0x3b, 0x03, 0x23, 0x5c, 0x5e, 0x4c, 0x62, 0xa3, 0x7a, 0xd8,
0x8c, 0x7b, 0x67, 0x93, 0x24, 0x95, 0xa7, 0x10, 0x90, 0xe8, 0x5d, 0xd4, 0x02, 0x0a, 0x93, 0x00
};
const static uint8_t test_input_monero_v2_pow_2[] = {
0x38, 0x27, 0x4c, 0x97, 0xc4, 0x5a, 0x17, 0x2c, 0xfc, 0x97, 0x67, 0x98, 0x70, 0x42, 0x2e, 0x3a,
0x1a, 0xb0, 0x78, 0x49, 0x60, 0xc6, 0x05, 0x14, 0xd8, 0x16, 0x27, 0x14, 0x15, 0xc3, 0x06, 0xee,
0x3a, 0x3e, 0xd1, 0xa7, 0x7e, 0x31, 0xf6, 0xa8, 0x85, 0xc3, 0xcb
0x38, 0x27, 0x4c, 0x97, 0xc4, 0x5a, 0x17, 0x2c, 0xfc, 0x97, 0x67, 0x98, 0x70, 0x42, 0x2e, 0x3a,
0x1a, 0xb0, 0x78, 0x49, 0x60, 0xc6, 0x05, 0x14, 0xd8, 0x16, 0x27, 0x14, 0x15, 0xc3, 0x06, 0xee,
0x3a, 0x3e, 0xd1, 0xa7, 0x7e, 0x31, 0xf6, 0xa8, 0x85, 0xc3, 0xcb
};
const static uint8_t test_output_monero_v2_pow[3][32] = {
{0x5b, 0xb4, 0x0c, 0x58, 0x80, 0xce, 0xf2, 0xf7, 0x39, 0xbd, 0xb6, 0xaa, 0xaf, 0x16, 0x16, 0x1e,
0xaa, 0xe5, 0x55, 0x30, 0xe7, 0xb1, 0x0d, 0x7e, 0xa9, 0x96, 0xb7, 0x51, 0xa2, 0x99, 0xe9, 0x49},
{0x61, 0x3e, 0x63, 0x85, 0x05, 0xba, 0x1f, 0xd0, 0x5f, 0x42, 0x8d, 0x5c, 0x9f, 0x8e, 0x08, 0xf8,
0x16, 0x56, 0x14, 0x34, 0x2d, 0xac, 0x41, 0x9a, 0xdc, 0x6a, 0x47, 0xdc, 0xe2, 0x57, 0xeb, 0x3e},
{0xed, 0x08, 0x2e, 0x49, 0xdb, 0xd5, 0xbb, 0xe3, 0x4a, 0x37, 0x26, 0xa0, 0xd1, 0xda, 0xd9, 0x81,
0x14, 0x60, 0x62, 0xb3, 0x9d, 0x36, 0xd6, 0x2c, 0x71, 0xeb, 0x1e, 0xd8, 0xab, 0x49, 0x45, 0x9b}
{0x5b, 0xb4, 0x0c, 0x58, 0x80, 0xce, 0xf2, 0xf7, 0x39, 0xbd, 0xb6, 0xaa, 0xaf, 0x16, 0x16, 0x1e,
0xaa, 0xe5, 0x55, 0x30, 0xe7, 0xb1, 0x0d, 0x7e, 0xa9, 0x96, 0xb7, 0x51, 0xa2, 0x99, 0xe9, 0x49},
{0x61, 0x3e, 0x63, 0x85, 0x05, 0xba, 0x1f, 0xd0, 0x5f, 0x42, 0x8d, 0x5c, 0x9f, 0x8e, 0x08, 0xf8,
0x16, 0x56, 0x14, 0x34, 0x2d, 0xac, 0x41, 0x9a, 0xdc, 0x6a, 0x47, 0xdc, 0xe2, 0x57, 0xeb, 0x3e},
{0xed, 0x08, 0x2e, 0x49, 0xdb, 0xd5, 0xbb, 0xe3, 0x4a, 0x37, 0x26, 0xa0, 0xd1, 0xda, 0xd9, 0x81,
0x14, 0x60, 0x62, 0xb3, 0x9d, 0x36, 0xd6, 0x2c, 0x71, 0xeb, 0x1e, 0xd8, 0xab, 0x49, 0x45, 0x9b}
};
const static uint8_t test_output_monero_v2_pow_light[3][32] = {
{0xbb, 0x19, 0x6c, 0x4c, 0x0c, 0x9d, 0xc1, 0xc4, 0xe4, 0x4c, 0x2a, 0x6f, 0x9e, 0x61, 0x20, 0x0f,
0xe3, 0xc8, 0xb4, 0xef, 0x23, 0x21, 0x34, 0xe6, 0x5c, 0x3c, 0x78, 0x62, 0xc7, 0xd3, 0xdf, 0x6a},
{0x45, 0x21, 0x03, 0x73, 0x1d, 0xd8, 0xd7, 0x0c, 0xe3, 0x2f, 0x72, 0x6b, 0x8e, 0x71, 0xfc, 0xd9,
0x10, 0x05, 0xfb, 0x3c, 0xb2, 0xab, 0xd7, 0x8f, 0x2b, 0x73, 0x57, 0xbb, 0x07, 0xf8, 0xc8, 0xbc},
{0x4e, 0x78, 0x53, 0x76, 0xed, 0x27, 0x33, 0x26, 0x2d, 0x83, 0xcc, 0x25, 0x32, 0x1a, 0x9d, 0x00,
0x03, 0xf5, 0x39, 0x53, 0x15, 0xde, 0x91, 0x9a, 0xcf, 0x1b, 0x97, 0xf0, 0xa8, 0x4f, 0xbd, 0x2d}
{0xbb, 0x19, 0x6c, 0x4c, 0x0c, 0x9d, 0xc1, 0xc4, 0xe4, 0x4c, 0x2a, 0x6f, 0x9e, 0x61, 0x20, 0x0f,
0xe3, 0xc8, 0xb4, 0xef, 0x23, 0x21, 0x34, 0xe6, 0x5c, 0x3c, 0x78, 0x62, 0xc7, 0xd3, 0xdf, 0x6a},
{0x45, 0x21, 0x03, 0x73, 0x1d, 0xd8, 0xd7, 0x0c, 0xe3, 0x2f, 0x72, 0x6b, 0x8e, 0x71, 0xfc, 0xd9,
0x10, 0x05, 0xfb, 0x3c, 0xb2, 0xab, 0xd7, 0x8f, 0x2b, 0x73, 0x57, 0xbb, 0x07, 0xf8, 0xc8, 0xbc},
{0x4e, 0x78, 0x53, 0x76, 0xed, 0x27, 0x33, 0x26, 0x2d, 0x83, 0xcc, 0x25, 0x32, 0x1a, 0x9d, 0x00,
0x03, 0xf5, 0x39, 0x53, 0x15, 0xde, 0x91, 0x9a, 0xcf, 0x1b, 0x97, 0xf0, 0xa8, 0x4f, 0xbd, 0x2d}
};
const static uint8_t test_input_lite_ipbc[] = {
0x38, 0x27, 0x4c, 0x97, 0xc4, 0x5a, 0x17, 0x2c, 0xfc, 0x97, 0x67, 0x98, 0x70, 0x42, 0x2e, 0x3a,
0x1a, 0xb0, 0x78, 0x49, 0x60, 0xc6, 0x05, 0x14, 0xd8, 0x16, 0x27, 0x14, 0x15, 0xc3, 0x06, 0xee,
0x3a, 0x3e, 0xd1, 0xa7, 0x7e, 0x31, 0xf6, 0xa8, 0x85, 0xc3, 0xcb,
0x38, 0x27, 0x4c, 0x97, 0xc4, 0x5a, 0x17, 0x2c, 0xfc, 0x97, 0x67, 0x98, 0x70, 0x42, 0x2e, 0x3a,
0x1a, 0xb0, 0x78, 0x49, 0x60, 0xc6, 0x05, 0x14, 0xd8, 0x16, 0x27, 0x14, 0x15, 0xc3, 0x06, 0xee,
0x3a, 0x3e, 0xd1, 0xa7, 0x7e, 0x31, 0xf6, 0xa8, 0x85, 0xc3, 0xcb,
0x38, 0x27, 0x4c, 0x97, 0xc4, 0x5a, 0x17, 0x2c, 0xfc, 0x97, 0x67, 0x98, 0x70, 0x42, 0x2e, 0x3a,
0x1a, 0xb0, 0x78, 0x49, 0x60, 0xc6, 0x05, 0x14, 0xd8, 0x16, 0x27, 0x14, 0x15, 0xc3, 0x06, 0xee,
0x3a, 0x3e, 0xd1, 0xa7, 0x7e, 0x31, 0xf6, 0xa8, 0x85, 0xc3, 0xcb,
0x38, 0x27, 0x4c, 0x97, 0xc4, 0x5a, 0x17, 0x2c, 0xfc, 0x97, 0x67, 0x98, 0x70, 0x42, 0x2e, 0x3a,
0x1a, 0xb0, 0x78, 0x49, 0x60, 0xc6, 0x05, 0x14, 0xd8, 0x16, 0x27, 0x14, 0x15, 0xc3, 0x06, 0xee,
0x3a, 0x3e, 0xd1, 0xa7, 0x7e, 0x31, 0xf6, 0xa8, 0x85, 0xc3, 0xcb,
0x38, 0x27, 0x4c, 0x97, 0xc4, 0x5a, 0x17, 0x2c, 0xfc, 0x97, 0x67, 0x98, 0x70, 0x42, 0x2e, 0x3a,
0x1a, 0xb0, 0x78, 0x49, 0x60, 0xc6, 0x05, 0x14, 0xd8, 0x16, 0x27, 0x14, 0x15, 0xc3, 0x06, 0xee,
0x3a, 0x3e, 0xd1, 0xa7, 0x7e, 0x31, 0xf6, 0xa8, 0x85, 0xc3, 0xcb,
0x38, 0x27, 0x4c, 0x97, 0xc4, 0x5a, 0x17, 0x2c, 0xfc, 0x97, 0x67, 0x98, 0x70, 0x42, 0x2e, 0x3a,
0x1a, 0xb0, 0x78, 0x49, 0x60, 0xc6, 0x05, 0x14, 0xd8, 0x16, 0x27, 0x14, 0x15, 0xc3, 0x06, 0xee,
0x3a, 0x3e, 0xd1, 0xa7, 0x7e, 0x31, 0xf6, 0xa8, 0x85, 0xc3, 0xcb
};
const static uint8_t test_output_lite_ipbc[] = {
0xb4, 0x42, 0xa2, 0xb9, 0x56, 0xe6, 0x3f, 0xef, 0xe8, 0x1b, 0xfa, 0x8b, 0xcb, 0xc4, 0xdd, 0xd6, 0xb6, 0x3f,
0x86, 0x53, 0x0e, 0xea, 0xa4, 0x65, 0x88, 0x31, 0x1d, 0x29, 0x0a, 0xfb, 0xb2, 0xc0,
0xb4, 0x42, 0xa2, 0xb9, 0x56, 0xe6, 0x3f, 0xef, 0xe8, 0x1b, 0xfa, 0x8b, 0xcb, 0xc4, 0xdd, 0xd6, 0xb6, 0x3f,
0x86, 0x53, 0x0e, 0xea, 0xa4, 0x65, 0x88, 0x31, 0x1d, 0x29, 0x0a, 0xfb, 0xb2, 0xc0,
0xb4, 0x42, 0xa2, 0xb9, 0x56, 0xe6, 0x3f, 0xef, 0xe8, 0x1b, 0xfa, 0x8b, 0xcb, 0xc4, 0xdd, 0xd6, 0xb6, 0x3f,
0x86, 0x53, 0x0e, 0xea, 0xa4, 0x65, 0x88, 0x31, 0x1d, 0x29, 0x0a, 0xfb, 0xb2, 0xc0,
0xb4, 0x42, 0xa2, 0xb9, 0x56, 0xe6, 0x3f, 0xef, 0xe8, 0x1b, 0xfa, 0x8b, 0xcb, 0xc4, 0xdd, 0xd6, 0xb6, 0x3f,
0x86, 0x53, 0x0e, 0xea, 0xa4, 0x65, 0x88, 0x31, 0x1d, 0x29, 0x0a, 0xfb, 0xb2, 0xc0,
0xb4, 0x42, 0xa2, 0xb9, 0x56, 0xe6, 0x3f, 0xef, 0xe8, 0x1b, 0xfa, 0x8b, 0xcb, 0xc4, 0xdd, 0xd6, 0xb6, 0x3f,
0x86, 0x53, 0x0e, 0xea, 0xa4, 0x65, 0x88, 0x31, 0x1d, 0x29, 0x0a, 0xfb, 0xb2, 0xc0
};
const static uint8_t test_output_heavy[] = {
0x4D, 0x94, 0x7D, 0xD6, 0xDB, 0x6E, 0x07, 0x48, 0x26, 0x4A, 0x51, 0x2E, 0xAC, 0xF3, 0x25, 0x4A,
0x1F, 0x1A, 0xA2, 0x5B, 0xFC, 0x0A, 0xAD, 0x82, 0xDE, 0xA8, 0x99, 0x96, 0x88, 0x52, 0xD2, 0x7D,
0x99, 0x83, 0xF2, 0x1B, 0xDF, 0x20, 0x10, 0xA8, 0xD7, 0x07, 0xBB, 0x2F, 0x14, 0xD7, 0x86, 0x64,
0xBB, 0xE1, 0x18, 0x7F, 0x55, 0x01, 0x4B, 0x39, 0xE5, 0xF3, 0xD6, 0x93, 0x28, 0xE4, 0x8F, 0xC2,
0x4D, 0x94, 0x7D, 0xD6, 0xDB, 0x6E, 0x07, 0x48, 0x26, 0x4A, 0x51, 0x2E, 0xAC, 0xF3, 0x25, 0x4A,
0x1F, 0x1A, 0xA2, 0x5B, 0xFC, 0x0A, 0xAD, 0x82, 0xDE, 0xA8, 0x99, 0x96, 0x88, 0x52, 0xD2, 0x7D,
0x99, 0x83, 0xF2, 0x1B, 0xDF, 0x20, 0x10, 0xA8, 0xD7, 0x07, 0xBB, 0x2F, 0x14, 0xD7, 0x86, 0x64,
0xBB, 0xE1, 0x18, 0x7F, 0x55, 0x01, 0x4B, 0x39, 0xE5, 0xF3, 0xD6, 0x93, 0x28, 0xE4, 0x8F, 0xC2,
0x4D, 0x94, 0x7D, 0xD6, 0xDB, 0x6E, 0x07, 0x48, 0x26, 0x4A, 0x51, 0x2E, 0xAC, 0xF3, 0x25, 0x4A,
0x1F, 0x1A, 0xA2, 0x5B, 0xFC, 0x0A, 0xAD, 0x82, 0xDE, 0xA8, 0x99, 0x96, 0x88, 0x52, 0xD2, 0x7D,
0x99, 0x83, 0xF2, 0x1B, 0xDF, 0x20, 0x10, 0xA8, 0xD7, 0x07, 0xBB, 0x2F, 0x14, 0xD7, 0x86, 0x64,
0xBB, 0xE1, 0x18, 0x7F, 0x55, 0x01, 0x4B, 0x39, 0xE5, 0xF3, 0xD6, 0x93, 0x28, 0xE4, 0x8F, 0xC2,
0x4D, 0x94, 0x7D, 0xD6, 0xDB, 0x6E, 0x07, 0x48, 0x26, 0x4A, 0x51, 0x2E, 0xAC, 0xF3, 0x25, 0x4A,
0x1F, 0x1A, 0xA2, 0x5B, 0xFC, 0x0A, 0xAD, 0x82, 0xDE, 0xA8, 0x99, 0x96, 0x88, 0x52, 0xD2, 0x7D,
0x99, 0x83, 0xF2, 0x1B, 0xDF, 0x20, 0x10, 0xA8, 0xD7, 0x07, 0xBB, 0x2F, 0x14, 0xD7, 0x86, 0x64,
0xBB, 0xE1, 0x18, 0x7F, 0x55, 0x01, 0x4B, 0x39, 0xE5, 0xF3, 0xD6, 0x93, 0x28, 0xE4, 0x8F, 0xC2,
0x4D, 0x94, 0x7D, 0xD6, 0xDB, 0x6E, 0x07, 0x48, 0x26, 0x4A, 0x51, 0x2E, 0xAC, 0xF3, 0x25, 0x4A,
0x1F, 0x1A, 0xA2, 0x5B, 0xFC, 0x0A, 0xAD, 0x82, 0xDE, 0xA8, 0x99, 0x96, 0x88, 0x52, 0xD2, 0x7D,
0x99, 0x83, 0xF2, 0x1B, 0xDF, 0x20, 0x10, 0xA8, 0xD7, 0x07, 0xBB, 0x2F, 0x14, 0xD7, 0x86, 0x64,
0xBB, 0xE1, 0x18, 0x7F, 0x55, 0x01, 0x4B, 0x39, 0xE5, 0xF3, 0xD6, 0x93, 0x28, 0xE4, 0x8F, 0xC2
0x4D, 0x94, 0x7D, 0xD6, 0xDB, 0x6E, 0x07, 0x48, 0x26, 0x4A, 0x51, 0x2E, 0xAC, 0xF3, 0x25, 0x4A,
0x1F, 0x1A, 0xA2, 0x5B, 0xFC, 0x0A, 0xAD, 0x82, 0xDE, 0xA8, 0x99, 0x96, 0x88, 0x52, 0xD2, 0x7D,
0x99, 0x83, 0xF2, 0x1B, 0xDF, 0x20, 0x10, 0xA8, 0xD7, 0x07, 0xBB, 0x2F, 0x14, 0xD7, 0x86, 0x64,
0xBB, 0xE1, 0x18, 0x7F, 0x55, 0x01, 0x4B, 0x39, 0xE5, 0xF3, 0xD6, 0x93, 0x28, 0xE4, 0x8F, 0xC2
};

View file

@ -626,6 +626,91 @@ public:
}
}
inline static void hashLiteIpbc(const uint8_t* __restrict__ input,
size_t size,
uint8_t* __restrict__ output,
cryptonight_ctx* __restrict__ ctx)
{
const uint8_t* l[NUM_HASH_BLOCKS];
uint64_t* h[NUM_HASH_BLOCKS];
uint64_t al[NUM_HASH_BLOCKS];
uint64_t ah[NUM_HASH_BLOCKS];
__m128i bx[NUM_HASH_BLOCKS];
uint64_t idx[NUM_HASH_BLOCKS];
uint64_t tweak1_2[NUM_HASH_BLOCKS];
for (size_t hashBlock = 0; hashBlock < NUM_HASH_BLOCKS; ++hashBlock) {
keccak(static_cast<const uint8_t*>(input) + hashBlock * size, (int) size, ctx->state[hashBlock], 200);
tweak1_2[hashBlock] = (*reinterpret_cast<const uint64_t*>(reinterpret_cast<const uint8_t*>(input) + 35 + hashBlock * size) ^
*(reinterpret_cast<const uint64_t*>(ctx->state[hashBlock]) + 24));
}
for (size_t hashBlock = 0; hashBlock < NUM_HASH_BLOCKS; ++hashBlock) {
l[hashBlock] = ctx->memory + hashBlock * MEM;
h[hashBlock] = reinterpret_cast<uint64_t*>(ctx->state[hashBlock]);
cn_explode_scratchpad<MEM, SOFT_AES>((__m128i*) h[hashBlock], (__m128i*) l[hashBlock]);
al[hashBlock] = h[hashBlock][0] ^ h[hashBlock][4];
ah[hashBlock] = h[hashBlock][1] ^ h[hashBlock][5];
bx[hashBlock] =
_mm_set_epi64x(h[hashBlock][3] ^ h[hashBlock][7], h[hashBlock][2] ^ h[hashBlock][6]);
idx[hashBlock] = h[hashBlock][0] ^ h[hashBlock][4];
}
for (size_t i = 0; i < ITERATIONS; i++) {
for (size_t hashBlock = 0; hashBlock < NUM_HASH_BLOCKS; ++hashBlock) {
__m128i cx;
if (SOFT_AES) {
cx = soft_aesenc((uint32_t*) &l[hashBlock][idx[hashBlock] & MASK], _mm_set_epi64x(ah[hashBlock], al[hashBlock]));
} else {
cx = _mm_load_si128((__m128i*) &l[hashBlock][idx[hashBlock] & MASK]);
cx = _mm_aesenc_si128(cx, _mm_set_epi64x(ah[hashBlock], al[hashBlock]));
}
_mm_store_si128((__m128i*) &l[hashBlock][idx[hashBlock] & MASK],
_mm_xor_si128(bx[hashBlock], cx));
const uint8_t tmp = reinterpret_cast<const uint8_t*>(&l[hashBlock][idx[hashBlock] & MASK])[11];
static const uint32_t table = 0x75310;
const uint8_t index = (((tmp >> 3) & 6) | (tmp & 1)) << 1;
((uint8_t*)(&l[hashBlock][idx[hashBlock] & MASK]))[11] = tmp ^ ((table >> index) & 0x30);
idx[hashBlock] = EXTRACT64(cx);
bx[hashBlock] = cx;
uint64_t hi, lo, cl, ch;
cl = ((uint64_t*) &l[hashBlock][idx[hashBlock] & MASK])[0];
ch = ((uint64_t*) &l[hashBlock][idx[hashBlock] & MASK])[1];
lo = __umul128(idx[hashBlock], cl, &hi);
al[hashBlock] += hi;
ah[hashBlock] += lo;
ah[hashBlock] ^= tweak1_2[hashBlock];
((uint64_t*) &l[hashBlock][idx[hashBlock] & MASK])[0] = al[hashBlock];
((uint64_t*) &l[hashBlock][idx[hashBlock] & MASK])[1] = ah[hashBlock];
ah[hashBlock] ^= tweak1_2[hashBlock];
((uint64_t*)&l[hashBlock][idx[hashBlock] & MASK])[1] ^= ((uint64_t*)&l[hashBlock][idx[hashBlock] & MASK])[0];
ah[hashBlock] ^= ch;
al[hashBlock] ^= cl;
idx[hashBlock] = al[hashBlock];
}
}
for (size_t hashBlock = 0; hashBlock < NUM_HASH_BLOCKS; ++hashBlock) {
cn_implode_scratchpad<MEM, SOFT_AES>((__m128i*) l[hashBlock], (__m128i*) h[hashBlock]);
keccakf(h[hashBlock], 24);
extra_hashes[ctx->state[hashBlock][0] & 3](ctx->state[hashBlock], 200,
output + hashBlock * 32);
}
}
inline static void hashHeavy(const uint8_t* __restrict__ input,
size_t size,
uint8_t* __restrict__ output,
@ -835,6 +920,75 @@ public:
extra_hashes[ctx->state[0][0] & 3](ctx->state[0], 200, output);
}
inline static void hashLiteIpbc(const uint8_t* __restrict__ input,
size_t size,
uint8_t* __restrict__ output,
cryptonight_ctx* __restrict__ ctx)
{
const uint8_t* l;
uint64_t* h;
uint64_t al;
uint64_t ah;
__m128i bx;
uint64_t idx;
keccak(static_cast<const uint8_t*>(input), (int) size, ctx->state[0], 200);
uint64_t tweak1_2 = (*reinterpret_cast<const uint64_t*>(reinterpret_cast<const uint8_t*>(input) + 35) ^
*(reinterpret_cast<const uint64_t*>(ctx->state[0]) + 24));
l = ctx->memory;
h = reinterpret_cast<uint64_t*>(ctx->state[0]);
cn_explode_scratchpad<MEM, SOFT_AES>((__m128i*) h, (__m128i*) l);
al = h[0] ^ h[4];
ah = h[1] ^ h[5];
bx = _mm_set_epi64x(h[3] ^ h[7], h[2] ^ h[6]);
idx = h[0] ^ h[4];
for (size_t i = 0; i < ITERATIONS; i++) {
__m128i cx;
if (SOFT_AES) {
cx = soft_aesenc((uint32_t*)&l[idx & MASK], _mm_set_epi64x(ah, al));
} else {
cx = _mm_load_si128((__m128i*) &l[idx & MASK]);
cx = _mm_aesenc_si128(cx, _mm_set_epi64x(ah, al));
}
_mm_store_si128((__m128i*) &l[idx & MASK], _mm_xor_si128(bx, cx));
const uint8_t tmp = reinterpret_cast<const uint8_t*>(&l[idx & MASK])[11];
static const uint32_t table = 0x75310;
const uint8_t index = (((tmp >> 3) & 6) | (tmp & 1)) << 1;
((uint8_t*)(&l[idx & MASK]))[11] = tmp ^ ((table >> index) & 0x30);
idx = EXTRACT64(cx);
bx = cx;
uint64_t hi, lo, cl, ch;
cl = ((uint64_t*) &l[idx & MASK])[0];
ch = ((uint64_t*) &l[idx & MASK])[1];
lo = __umul128(idx, cl, &hi);
al += hi;
ah += lo;
ah ^= tweak1_2;
((uint64_t*) &l[idx & MASK])[0] = al;
((uint64_t*) &l[idx & MASK])[1] = ah;
ah ^= tweak1_2;
((uint64_t*)&l[idx & MASK])[1] ^= ((uint64_t*)&l[idx & MASK])[0];
ah ^= ch;
al ^= cl;
idx = al;
}
cn_implode_scratchpad<MEM, SOFT_AES>((__m128i*) l, (__m128i*) h);
keccakf(h, 24);
extra_hashes[ctx->state[0][0] & 3](ctx->state[0], 200, output);
}
inline static void hashHeavy(const uint8_t* __restrict__ input,
size_t size,
uint8_t* __restrict__ output,
@ -1105,6 +1259,118 @@ public:
extra_hashes[ctx->state[1][0] & 3](ctx->state[1], 200, output + 32);
}
inline static void hashLiteIpbc(const uint8_t* __restrict__ input,
size_t size,
uint8_t* __restrict__ output,
cryptonight_ctx* __restrict__ ctx)
{
keccak((const uint8_t*) input, (int) size, ctx->state[0], 200);
keccak((const uint8_t*) input + size, (int) size, ctx->state[1], 200);
uint64_t tweak1_2_0 = (*reinterpret_cast<const uint64_t*>(reinterpret_cast<const uint8_t*>(input) + 35) ^
*(reinterpret_cast<const uint64_t*>(ctx->state[0]) + 24));
uint64_t tweak1_2_1 = (*reinterpret_cast<const uint64_t*>(reinterpret_cast<const uint8_t*>(input) + 35 + size) ^
*(reinterpret_cast<const uint64_t*>(ctx->state[1]) + 24));
const uint8_t* l0 = ctx->memory;
const uint8_t* l1 = ctx->memory + MEM;
uint64_t* h0 = reinterpret_cast<uint64_t*>(ctx->state[0]);
uint64_t* h1 = reinterpret_cast<uint64_t*>(ctx->state[1]);
cn_explode_scratchpad<MEM, SOFT_AES>((__m128i*) h0, (__m128i*) l0);
cn_explode_scratchpad<MEM, SOFT_AES>((__m128i*) h1, (__m128i*) l1);
uint64_t al0 = h0[0] ^h0[4];
uint64_t al1 = h1[0] ^h1[4];
uint64_t ah0 = h0[1] ^h0[5];
uint64_t ah1 = h1[1] ^h1[5];
__m128i bx0 = _mm_set_epi64x(h0[3] ^ h0[7], h0[2] ^ h0[6]);
__m128i bx1 = _mm_set_epi64x(h1[3] ^ h1[7], h1[2] ^ h1[6]);
uint64_t idx0 = h0[0] ^h0[4];
uint64_t idx1 = h1[0] ^h1[4];
for (size_t i = 0; i < ITERATIONS; i++) {
__m128i cx0;
__m128i cx1;
if (SOFT_AES) {
cx0 = soft_aesenc((uint32_t*)&l0[idx0 & MASK], _mm_set_epi64x(ah0, al0));
cx1 = soft_aesenc((uint32_t*)&l1[idx1 & MASK], _mm_set_epi64x(ah1, al1));
} else {
cx0 = _mm_load_si128((__m128i*) &l0[idx0 & MASK]);
cx1 = _mm_load_si128((__m128i*) &l1[idx1 & MASK]);
cx0 = _mm_aesenc_si128(cx0, _mm_set_epi64x(ah0, al0));
cx1 = _mm_aesenc_si128(cx1, _mm_set_epi64x(ah1, al1));
}
_mm_store_si128((__m128i*) &l0[idx0 & MASK], _mm_xor_si128(bx0, cx0));
_mm_store_si128((__m128i*) &l1[idx1 & MASK], _mm_xor_si128(bx1, cx1));
static const uint32_t table = 0x75310;
uint8_t tmp = reinterpret_cast<const uint8_t*>(&l0[idx0 & MASK])[11];
uint8_t index = (((tmp >> 3) & 6) | (tmp & 1)) << 1;
((uint8_t*)(&l0[idx0 & MASK]))[11] = tmp ^ ((table >> index) & 0x30);
tmp = reinterpret_cast<const uint8_t*>(&l1[idx1 & MASK])[11];
index = (((tmp >> 3) & 6) | (tmp & 1)) << 1;
((uint8_t*)(&l1[idx1 & MASK]))[11] = tmp ^ ((table >> index) & 0x30);
idx0 = EXTRACT64(cx0);
idx1 = EXTRACT64(cx1);
bx0 = cx0;
bx1 = cx1;
uint64_t hi, lo, cl, ch;
cl = ((uint64_t*) &l0[idx0 & MASK])[0];
ch = ((uint64_t*) &l0[idx0 & MASK])[1];
lo = __umul128(idx0, cl, &hi);
al0 += hi;
ah0 += lo;
ah0 ^= tweak1_2_0;
((uint64_t*) &l0[idx0 & MASK])[0] = al0;
((uint64_t*) &l0[idx0 & MASK])[1] = ah0;
ah0 ^= tweak1_2_0;
((uint64_t*)&l0[idx0 & MASK])[1] ^= ((uint64_t*)&l0[idx0 & MASK])[0];
ah0 ^= ch;
al0 ^= cl;
idx0 = al0;
cl = ((uint64_t*) &l1[idx1 & MASK])[0];
ch = ((uint64_t*) &l1[idx1 & MASK])[1];
lo = __umul128(idx1, cl, &hi);
al1 += hi;
ah1 += lo;
ah1 ^= tweak1_2_1;
((uint64_t*) &l1[idx1 & MASK])[0] = al1;
((uint64_t*) &l1[idx1 & MASK])[1] = ah1;
ah1 ^= tweak1_2_1;
((uint64_t*)&l1[idx1 & MASK])[1] ^= ((uint64_t*)&l1[idx1 & MASK])[0];
ah1 ^= ch;
al1 ^= cl;
idx1 = al1;
}
cn_implode_scratchpad<MEM, SOFT_AES>((__m128i*) l0, (__m128i*) h0);
cn_implode_scratchpad<MEM, SOFT_AES>((__m128i*) l1, (__m128i*) h1);
keccakf(h0, 24);
keccakf(h1, 24);
extra_hashes[ctx->state[0][0] & 3](ctx->state[0], 200, output);
extra_hashes[ctx->state[1][0] & 3](ctx->state[1], 200, output + 32);
}
inline static void hashHeavy(const uint8_t* __restrict__ input,
size_t size,
uint8_t* __restrict__ output,
@ -1492,6 +1758,162 @@ public:
extra_hashes[ctx->state[2][0] & 3](ctx->state[2], 200, output + 64);
}
inline static void hashLiteIpbc(const uint8_t* __restrict__ input,
size_t size,
uint8_t* __restrict__ output,
cryptonight_ctx* __restrict__ ctx)
{
keccak((const uint8_t*) input, (int) size, ctx->state[0], 200);
keccak((const uint8_t*) input + size, (int) size, ctx->state[1], 200);
keccak((const uint8_t*) input + 2 * size, (int) size, ctx->state[2], 200);
uint64_t tweak1_2_0 = (*reinterpret_cast<const uint64_t*>(reinterpret_cast<const uint8_t*>(input) + 35) ^
*(reinterpret_cast<const uint64_t*>(ctx->state[0]) + 24));
uint64_t tweak1_2_1 = (*reinterpret_cast<const uint64_t*>(reinterpret_cast<const uint8_t*>(input) + 35 + size) ^
*(reinterpret_cast<const uint64_t*>(ctx->state[1]) + 24));
uint64_t tweak1_2_2 = (*reinterpret_cast<const uint64_t*>(reinterpret_cast<const uint8_t*>(input) + 35 + 2 * size) ^
*(reinterpret_cast<const uint64_t*>(ctx->state[2]) + 24));
const uint8_t* l0 = ctx->memory;
const uint8_t* l1 = ctx->memory + MEM;
const uint8_t* l2 = ctx->memory + 2 * MEM;
uint64_t* h0 = reinterpret_cast<uint64_t*>(ctx->state[0]);
uint64_t* h1 = reinterpret_cast<uint64_t*>(ctx->state[1]);
uint64_t* h2 = reinterpret_cast<uint64_t*>(ctx->state[2]);
cn_explode_scratchpad<MEM, SOFT_AES>((__m128i*) h0, (__m128i*) l0);
cn_explode_scratchpad<MEM, SOFT_AES>((__m128i*) h1, (__m128i*) l1);
cn_explode_scratchpad<MEM, SOFT_AES>((__m128i*) h2, (__m128i*) l2);
uint64_t al0 = h0[0] ^h0[4];
uint64_t al1 = h1[0] ^h1[4];
uint64_t al2 = h2[0] ^h2[4];
uint64_t ah0 = h0[1] ^h0[5];
uint64_t ah1 = h1[1] ^h1[5];
uint64_t ah2 = h2[1] ^h2[5];
__m128i bx0 = _mm_set_epi64x(h0[3] ^ h0[7], h0[2] ^ h0[6]);
__m128i bx1 = _mm_set_epi64x(h1[3] ^ h1[7], h1[2] ^ h1[6]);
__m128i bx2 = _mm_set_epi64x(h2[3] ^ h2[7], h2[2] ^ h2[6]);
uint64_t idx0 = h0[0] ^h0[4];
uint64_t idx1 = h1[0] ^h1[4];
uint64_t idx2 = h2[0] ^h2[4];
for (size_t i = 0; i < ITERATIONS; i++) {
__m128i cx0;
__m128i cx1;
__m128i cx2;
if (SOFT_AES) {
cx0 = soft_aesenc((uint32_t*)&l0[idx0 & MASK], _mm_set_epi64x(ah0, al0));
cx1 = soft_aesenc((uint32_t*)&l1[idx1 & MASK], _mm_set_epi64x(ah1, al1));
cx2 = soft_aesenc((uint32_t*)&l2[idx2 & MASK], _mm_set_epi64x(ah2, al2));
} else {
cx0 = _mm_load_si128((__m128i*) &l0[idx0 & MASK]);
cx1 = _mm_load_si128((__m128i*) &l1[idx1 & MASK]);
cx2 = _mm_load_si128((__m128i*) &l2[idx2 & MASK]);
cx0 = _mm_aesenc_si128(cx0, _mm_set_epi64x(ah0, al0));
cx1 = _mm_aesenc_si128(cx1, _mm_set_epi64x(ah1, al1));
cx2 = _mm_aesenc_si128(cx2, _mm_set_epi64x(ah2, al2));
}
_mm_store_si128((__m128i*) &l0[idx0 & MASK], _mm_xor_si128(bx0, cx0));
_mm_store_si128((__m128i*) &l1[idx1 & MASK], _mm_xor_si128(bx1, cx1));
_mm_store_si128((__m128i*) &l2[idx2 & MASK], _mm_xor_si128(bx2, cx2));
static const uint32_t table = 0x75310;
uint8_t tmp = reinterpret_cast<const uint8_t*>(&l0[idx0 & MASK])[11];
uint8_t index = (((tmp >> 3) & 6) | (tmp & 1)) << 1;
((uint8_t*)(&l0[idx0 & MASK]))[11] = tmp ^ ((table >> index) & 0x30);
tmp = reinterpret_cast<const uint8_t*>(&l1[idx1 & MASK])[11];
index = (((tmp >> 3) & 6) | (tmp & 1)) << 1;
((uint8_t*)(&l1[idx1 & MASK]))[11] = tmp ^ ((table >> index) & 0x30);
tmp = reinterpret_cast<const uint8_t*>(&l2[idx2 & MASK])[11];
index = (((tmp >> 3) & 6) | (tmp & 1)) << 1;
((uint8_t*)(&l2[idx2 & MASK]))[11] = tmp ^ ((table >> index) & 0x30);
idx0 = EXTRACT64(cx0);
idx1 = EXTRACT64(cx1);
idx2 = EXTRACT64(cx2);
bx0 = cx0;
bx1 = cx1;
bx2 = cx2;
uint64_t hi, lo, cl, ch;
cl = ((uint64_t*) &l0[idx0 & MASK])[0];
ch = ((uint64_t*) &l0[idx0 & MASK])[1];
lo = __umul128(idx0, cl, &hi);
al0 += hi;
ah0 += lo;
ah0 ^= tweak1_2_0;
((uint64_t*) &l0[idx0 & MASK])[0] = al0;
((uint64_t*) &l0[idx0 & MASK])[1] = ah0;
ah0 ^= tweak1_2_0;
((uint64_t*)&l0[idx0 & MASK])[1] ^= ((uint64_t*)&l0[idx0 & MASK])[0];
ah0 ^= ch;
al0 ^= cl;
idx0 = al0;
cl = ((uint64_t*) &l1[idx1 & MASK])[0];
ch = ((uint64_t*) &l1[idx1 & MASK])[1];
lo = __umul128(idx1, cl, &hi);
al1 += hi;
ah1 += lo;
ah1 ^= tweak1_2_1;
((uint64_t*) &l1[idx1 & MASK])[0] = al1;
((uint64_t*) &l1[idx1 & MASK])[1] = ah1;
ah1 ^= tweak1_2_1;
((uint64_t*)&l1[idx1 & MASK])[1] ^= ((uint64_t*)&l1[idx1 & MASK])[0];
ah1 ^= ch;
al1 ^= cl;
idx1 = al1;
cl = ((uint64_t*) &l2[idx2 & MASK])[0];
ch = ((uint64_t*) &l2[idx2 & MASK])[1];
lo = __umul128(idx2, cl, &hi);
al2 += hi;
ah2 += lo;
ah2 ^= tweak1_2_2;
((uint64_t*) &l2[idx2 & MASK])[0] = al2;
((uint64_t*) &l2[idx2 & MASK])[1] = ah2;
ah2 ^= tweak1_2_2;
((uint64_t*)&l2[idx2 & MASK])[1] ^= ((uint64_t*)&l2[idx2 & MASK])[0];
ah2 ^= ch;
al2 ^= cl;
idx2 = al2;
}
cn_implode_scratchpad<MEM, SOFT_AES>((__m128i*) l0, (__m128i*) h0);
cn_implode_scratchpad<MEM, SOFT_AES>((__m128i*) l1, (__m128i*) h1);
cn_implode_scratchpad<MEM, SOFT_AES>((__m128i*) l2, (__m128i*) h2);
keccakf(h0, 24);
keccakf(h1, 24);
keccakf(h2, 24);
extra_hashes[ctx->state[0][0] & 3](ctx->state[0], 200, output);
extra_hashes[ctx->state[1][0] & 3](ctx->state[1], 200, output + 32);
extra_hashes[ctx->state[2][0] & 3](ctx->state[2], 200, output + 64);
}
inline static void hashHeavy(const uint8_t* __restrict__ input,
size_t size,
uint8_t* __restrict__ output,
@ -1993,6 +2415,204 @@ public:
extra_hashes[ctx->state[3][0] & 3](ctx->state[3], 200, output + 96);
}
inline static void hashLiteIpbc(const uint8_t* __restrict__ input,
size_t size,
uint8_t* __restrict__ output,
cryptonight_ctx* __restrict__ ctx)
{
keccak((const uint8_t*) input, (int) size, ctx->state[0], 200);
keccak((const uint8_t*) input + size, (int) size, ctx->state[1], 200);
keccak((const uint8_t*) input + 2 * size, (int) size, ctx->state[2], 200);
keccak((const uint8_t*) input + 3 * size, (int) size, ctx->state[3], 200);
uint64_t tweak1_2_0 = (*reinterpret_cast<const uint64_t*>(reinterpret_cast<const uint8_t*>(input) + 35) ^
*(reinterpret_cast<const uint64_t*>(ctx->state[0]) + 24));
uint64_t tweak1_2_1 = (*reinterpret_cast<const uint64_t*>(reinterpret_cast<const uint8_t*>(input) + 35 + size) ^
*(reinterpret_cast<const uint64_t*>(ctx->state[1]) + 24));
uint64_t tweak1_2_2 = (*reinterpret_cast<const uint64_t*>(reinterpret_cast<const uint8_t*>(input) + 35 + 2 * size) ^
*(reinterpret_cast<const uint64_t*>(ctx->state[2]) + 24));
uint64_t tweak1_2_3 = (*reinterpret_cast<const uint64_t*>(reinterpret_cast<const uint8_t*>(input) + 35 + 3 * size) ^
*(reinterpret_cast<const uint64_t*>(ctx->state[3]) + 24));
const uint8_t* l0 = ctx->memory;
const uint8_t* l1 = ctx->memory + MEM;
const uint8_t* l2 = ctx->memory + 2 * MEM;
const uint8_t* l3 = ctx->memory + 3 * MEM;
uint64_t* h0 = reinterpret_cast<uint64_t*>(ctx->state[0]);
uint64_t* h1 = reinterpret_cast<uint64_t*>(ctx->state[1]);
uint64_t* h2 = reinterpret_cast<uint64_t*>(ctx->state[2]);
uint64_t* h3 = reinterpret_cast<uint64_t*>(ctx->state[3]);
cn_explode_scratchpad<MEM, SOFT_AES>((__m128i*) h0, (__m128i*) l0);
cn_explode_scratchpad<MEM, SOFT_AES>((__m128i*) h1, (__m128i*) l1);
cn_explode_scratchpad<MEM, SOFT_AES>((__m128i*) h2, (__m128i*) l2);
cn_explode_scratchpad<MEM, SOFT_AES>((__m128i*) h3, (__m128i*) l3);
uint64_t al0 = h0[0] ^h0[4];
uint64_t al1 = h1[0] ^h1[4];
uint64_t al2 = h2[0] ^h2[4];
uint64_t al3 = h3[0] ^h3[4];
uint64_t ah0 = h0[1] ^h0[5];
uint64_t ah1 = h1[1] ^h1[5];
uint64_t ah2 = h2[1] ^h2[5];
uint64_t ah3 = h3[1] ^h3[5];
__m128i bx0 = _mm_set_epi64x(h0[3] ^ h0[7], h0[2] ^ h0[6]);
__m128i bx1 = _mm_set_epi64x(h1[3] ^ h1[7], h1[2] ^ h1[6]);
__m128i bx2 = _mm_set_epi64x(h2[3] ^ h2[7], h2[2] ^ h2[6]);
__m128i bx3 = _mm_set_epi64x(h3[3] ^ h3[7], h3[2] ^ h3[6]);
uint64_t idx0 = h0[0] ^h0[4];
uint64_t idx1 = h1[0] ^h1[4];
uint64_t idx2 = h2[0] ^h2[4];
uint64_t idx3 = h3[0] ^h3[4];
for (size_t i = 0; i < ITERATIONS; i++) {
__m128i cx0;
__m128i cx1;
__m128i cx2;
__m128i cx3;
if (SOFT_AES) {
cx0 = soft_aesenc((uint32_t*)&l0[idx0 & MASK], _mm_set_epi64x(ah0, al0));
cx1 = soft_aesenc((uint32_t*)&l1[idx1 & MASK], _mm_set_epi64x(ah1, al1));
cx2 = soft_aesenc((uint32_t*)&l2[idx2 & MASK], _mm_set_epi64x(ah2, al2));
cx3 = soft_aesenc((uint32_t*)&l3[idx3 & MASK], _mm_set_epi64x(ah3, al3));
} else {
cx0 = _mm_load_si128((__m128i*) &l0[idx0 & MASK]);
cx1 = _mm_load_si128((__m128i*) &l1[idx1 & MASK]);
cx2 = _mm_load_si128((__m128i*) &l2[idx2 & MASK]);
cx3 = _mm_load_si128((__m128i*) &l3[idx3 & MASK]);
cx0 = _mm_aesenc_si128(cx0, _mm_set_epi64x(ah0, al0));
cx1 = _mm_aesenc_si128(cx1, _mm_set_epi64x(ah1, al1));
cx2 = _mm_aesenc_si128(cx2, _mm_set_epi64x(ah2, al2));
cx3 = _mm_aesenc_si128(cx3, _mm_set_epi64x(ah3, al3));
}
_mm_store_si128((__m128i*) &l0[idx0 & MASK], _mm_xor_si128(bx0, cx0));
_mm_store_si128((__m128i*) &l1[idx1 & MASK], _mm_xor_si128(bx1, cx1));
_mm_store_si128((__m128i*) &l2[idx2 & MASK], _mm_xor_si128(bx2, cx2));
_mm_store_si128((__m128i*) &l3[idx3 & MASK], _mm_xor_si128(bx3, cx3));
static const uint32_t table = 0x75310;
uint8_t tmp = reinterpret_cast<const uint8_t*>(&l0[idx0 & MASK])[11];
uint8_t index = (((tmp >> 3) & 6) | (tmp & 1)) << 1;
((uint8_t*)(&l0[idx0 & MASK]))[11] = tmp ^ ((table >> index) & 0x30);
tmp = reinterpret_cast<const uint8_t*>(&l1[idx1 & MASK])[11];
index = (((tmp >> 3) & 6) | (tmp & 1)) << 1;
((uint8_t*)(&l1[idx1 & MASK]))[11] = tmp ^ ((table >> index) & 0x30);
tmp = reinterpret_cast<const uint8_t*>(&l2[idx2 & MASK])[11];
index = (((tmp >> 3) & 6) | (tmp & 1)) << 1;
((uint8_t*)(&l2[idx2 & MASK]))[11] = tmp ^ ((table >> index) & 0x30);
tmp = reinterpret_cast<const uint8_t*>(&l3[idx3 & MASK])[11];
index = (((tmp >> 3) & 6) | (tmp & 1)) << 1;
((uint8_t*)(&l3[idx3 & MASK]))[11] = tmp ^ ((table >> index) & 0x30);
idx0 = EXTRACT64(cx0);
idx1 = EXTRACT64(cx1);
idx2 = EXTRACT64(cx2);
idx3 = EXTRACT64(cx3);
bx0 = cx0;
bx1 = cx1;
bx2 = cx2;
bx3 = cx3;
uint64_t hi, lo, cl, ch;
cl = ((uint64_t*) &l0[idx0 & MASK])[0];
ch = ((uint64_t*) &l0[idx0 & MASK])[1];
lo = __umul128(idx0, cl, &hi);
al0 += hi;
ah0 += lo;
ah0 ^= tweak1_2_0;
((uint64_t*) &l0[idx0 & MASK])[0] = al0;
((uint64_t*) &l0[idx0 & MASK])[1] = ah0;
ah0 ^= tweak1_2_0;
((uint64_t*)&l0[idx0 & MASK])[1] ^= ((uint64_t*)&l0[idx0 & MASK])[0];
ah0 ^= ch;
al0 ^= cl;
idx0 = al0;
cl = ((uint64_t*) &l1[idx1 & MASK])[0];
ch = ((uint64_t*) &l1[idx1 & MASK])[1];
lo = __umul128(idx1, cl, &hi);
al1 += hi;
ah1 += lo;
ah1 ^= tweak1_2_1;
((uint64_t*) &l1[idx1 & MASK])[0] = al1;
((uint64_t*) &l1[idx1 & MASK])[1] = ah1;
ah1 ^= tweak1_2_1;
((uint64_t*)&l1[idx1 & MASK])[1] ^= ((uint64_t*)&l1[idx1 & MASK])[0];
ah1 ^= ch;
al1 ^= cl;
idx1 = al1;
cl = ((uint64_t*) &l2[idx2 & MASK])[0];
ch = ((uint64_t*) &l2[idx2 & MASK])[1];
lo = __umul128(idx2, cl, &hi);
al2 += hi;
ah2 += lo;
ah2 ^= tweak1_2_2;
((uint64_t*) &l2[idx2 & MASK])[0] = al2;
((uint64_t*) &l2[idx2 & MASK])[1] = ah2;
ah2 ^= tweak1_2_2;
((uint64_t*)&l2[idx2 & MASK])[1] ^= ((uint64_t*)&l2[idx2 & MASK])[0];
ah2 ^= ch;
al2 ^= cl;
idx2 = al2;
cl = ((uint64_t*) &l3[idx3 & MASK])[0];
ch = ((uint64_t*) &l3[idx3 & MASK])[1];
lo = __umul128(idx3, cl, &hi);
al3 += hi;
ah3 += lo;
ah3 ^= tweak1_2_3;
((uint64_t*) &l3[idx3 & MASK])[0] = al3;
((uint64_t*) &l3[idx3 & MASK])[1] = ah3;
ah3 ^= tweak1_2_3;
((uint64_t*)&l3[idx3 & MASK])[1] ^= ((uint64_t*)&l3[idx3 & MASK])[0];
ah3 ^= ch;
al3 ^= cl;
idx3 = al3;
}
cn_implode_scratchpad<MEM, SOFT_AES>((__m128i*) l0, (__m128i*) h0);
cn_implode_scratchpad<MEM, SOFT_AES>((__m128i*) l1, (__m128i*) h1);
cn_implode_scratchpad<MEM, SOFT_AES>((__m128i*) l2, (__m128i*) h2);
cn_implode_scratchpad<MEM, SOFT_AES>((__m128i*) l3, (__m128i*) h3);
keccakf(h0, 24);
keccakf(h1, 24);
keccakf(h2, 24);
keccakf(h3, 24);
extra_hashes[ctx->state[0][0] & 3](ctx->state[0], 200, output);
extra_hashes[ctx->state[1][0] & 3](ctx->state[1], 200, output + 32);
extra_hashes[ctx->state[2][0] & 3](ctx->state[2], 200, output + 64);
extra_hashes[ctx->state[3][0] & 3](ctx->state[3], 200, output + 96);
}
inline static void hashHeavy(const uint8_t* __restrict__ input,
size_t size,
uint8_t* __restrict__ output,
@ -2606,6 +3226,246 @@ public:
extra_hashes[ctx->state[4][0] & 3](ctx->state[4], 200, output + 128);
}
inline static void hashLiteIpbc(const uint8_t* __restrict__ input,
size_t size,
uint8_t* __restrict__ output,
cryptonight_ctx* __restrict__ ctx)
{
keccak((const uint8_t*) input, (int) size, ctx->state[0], 200);
keccak((const uint8_t*) input + size, (int) size, ctx->state[1], 200);
keccak((const uint8_t*) input + 2 * size, (int) size, ctx->state[2], 200);
keccak((const uint8_t*) input + 3 * size, (int) size, ctx->state[3], 200);
keccak((const uint8_t*) input + 4 * size, (int) size, ctx->state[4], 200);
uint64_t tweak1_2_0 = (*reinterpret_cast<const uint64_t*>(reinterpret_cast<const uint8_t*>(input) + 35) ^
*(reinterpret_cast<const uint64_t*>(ctx->state[0]) + 24));
uint64_t tweak1_2_1 = (*reinterpret_cast<const uint64_t*>(reinterpret_cast<const uint8_t*>(input) + 35 + size) ^
*(reinterpret_cast<const uint64_t*>(ctx->state[1]) + 24));
uint64_t tweak1_2_2 = (*reinterpret_cast<const uint64_t*>(reinterpret_cast<const uint8_t*>(input) + 35 + 2 * size) ^
*(reinterpret_cast<const uint64_t*>(ctx->state[2]) + 24));
uint64_t tweak1_2_3 = (*reinterpret_cast<const uint64_t*>(reinterpret_cast<const uint8_t*>(input) + 35 + 3 * size) ^
*(reinterpret_cast<const uint64_t*>(ctx->state[3]) + 24));
uint64_t tweak1_2_4 = (*reinterpret_cast<const uint64_t*>(reinterpret_cast<const uint8_t*>(input) + 35 + 4 * size) ^
*(reinterpret_cast<const uint64_t*>(ctx->state[4]) + 24));
const uint8_t* l0 = ctx->memory;
const uint8_t* l1 = ctx->memory + MEM;
const uint8_t* l2 = ctx->memory + 2 * MEM;
const uint8_t* l3 = ctx->memory + 3 * MEM;
const uint8_t* l4 = ctx->memory + 4 * MEM;
uint64_t* h0 = reinterpret_cast<uint64_t*>(ctx->state[0]);
uint64_t* h1 = reinterpret_cast<uint64_t*>(ctx->state[1]);
uint64_t* h2 = reinterpret_cast<uint64_t*>(ctx->state[2]);
uint64_t* h3 = reinterpret_cast<uint64_t*>(ctx->state[3]);
uint64_t* h4 = reinterpret_cast<uint64_t*>(ctx->state[4]);
cn_explode_scratchpad<MEM, SOFT_AES>((__m128i*) h0, (__m128i*) l0);
cn_explode_scratchpad<MEM, SOFT_AES>((__m128i*) h1, (__m128i*) l1);
cn_explode_scratchpad<MEM, SOFT_AES>((__m128i*) h2, (__m128i*) l2);
cn_explode_scratchpad<MEM, SOFT_AES>((__m128i*) h3, (__m128i*) l3);
cn_explode_scratchpad<MEM, SOFT_AES>((__m128i*) h4, (__m128i*) l4);
uint64_t al0 = h0[0] ^h0[4];
uint64_t al1 = h1[0] ^h1[4];
uint64_t al2 = h2[0] ^h2[4];
uint64_t al3 = h3[0] ^h3[4];
uint64_t al4 = h4[0] ^h4[4];
uint64_t ah0 = h0[1] ^h0[5];
uint64_t ah1 = h1[1] ^h1[5];
uint64_t ah2 = h2[1] ^h2[5];
uint64_t ah3 = h3[1] ^h3[5];
uint64_t ah4 = h4[1] ^h4[5];
__m128i bx0 = _mm_set_epi64x(h0[3] ^ h0[7], h0[2] ^ h0[6]);
__m128i bx1 = _mm_set_epi64x(h1[3] ^ h1[7], h1[2] ^ h1[6]);
__m128i bx2 = _mm_set_epi64x(h2[3] ^ h2[7], h2[2] ^ h2[6]);
__m128i bx3 = _mm_set_epi64x(h3[3] ^ h3[7], h3[2] ^ h3[6]);
__m128i bx4 = _mm_set_epi64x(h4[3] ^ h4[7], h4[2] ^ h4[6]);
uint64_t idx0 = h0[0] ^h0[4];
uint64_t idx1 = h1[0] ^h1[4];
uint64_t idx2 = h2[0] ^h2[4];
uint64_t idx3 = h3[0] ^h3[4];
uint64_t idx4 = h4[0] ^h4[4];
for (size_t i = 0; i < ITERATIONS; i++) {
__m128i cx0;
__m128i cx1;
__m128i cx2;
__m128i cx3;
__m128i cx4;
if (SOFT_AES) {
cx0 = soft_aesenc((uint32_t*)&l0[idx0 & MASK], _mm_set_epi64x(ah0, al0));
cx1 = soft_aesenc((uint32_t*)&l1[idx1 & MASK], _mm_set_epi64x(ah1, al1));
cx2 = soft_aesenc((uint32_t*)&l2[idx2 & MASK], _mm_set_epi64x(ah2, al2));
cx3 = soft_aesenc((uint32_t*)&l3[idx3 & MASK], _mm_set_epi64x(ah3, al3));
cx4 = soft_aesenc((uint32_t*)&l4[idx4 & MASK], _mm_set_epi64x(ah4, al4));
} else {
cx0 = _mm_load_si128((__m128i*) &l0[idx0 & MASK]);
cx1 = _mm_load_si128((__m128i*) &l1[idx1 & MASK]);
cx2 = _mm_load_si128((__m128i*) &l2[idx2 & MASK]);
cx3 = _mm_load_si128((__m128i*) &l3[idx3 & MASK]);
cx4 = _mm_load_si128((__m128i*) &l4[idx4 & MASK]);
cx0 = _mm_aesenc_si128(cx0, _mm_set_epi64x(ah0, al0));
cx1 = _mm_aesenc_si128(cx1, _mm_set_epi64x(ah1, al1));
cx2 = _mm_aesenc_si128(cx2, _mm_set_epi64x(ah2, al2));
cx3 = _mm_aesenc_si128(cx3, _mm_set_epi64x(ah3, al3));
cx4 = _mm_aesenc_si128(cx4, _mm_set_epi64x(ah4, al4));
}
_mm_store_si128((__m128i*) &l0[idx0 & MASK], _mm_xor_si128(bx0, cx0));
_mm_store_si128((__m128i*) &l1[idx1 & MASK], _mm_xor_si128(bx1, cx1));
_mm_store_si128((__m128i*) &l2[idx2 & MASK], _mm_xor_si128(bx2, cx2));
_mm_store_si128((__m128i*) &l3[idx3 & MASK], _mm_xor_si128(bx3, cx3));
_mm_store_si128((__m128i*) &l4[idx4 & MASK], _mm_xor_si128(bx4, cx4));
static const uint32_t table = 0x75310;
uint8_t tmp = reinterpret_cast<const uint8_t*>(&l0[idx0 & MASK])[11];
uint8_t index = (((tmp >> 3) & 6) | (tmp & 1)) << 1;
((uint8_t*)(&l0[idx0 & MASK]))[11] = tmp ^ ((table >> index) & 0x30);
tmp = reinterpret_cast<const uint8_t*>(&l1[idx1 & MASK])[11];
index = (((tmp >> 3) & 6) | (tmp & 1)) << 1;
((uint8_t*)(&l1[idx1 & MASK]))[11] = tmp ^ ((table >> index) & 0x30);
tmp = reinterpret_cast<const uint8_t*>(&l2[idx2 & MASK])[11];
index = (((tmp >> 3) & 6) | (tmp & 1)) << 1;
((uint8_t*)(&l2[idx2 & MASK]))[11] = tmp ^ ((table >> index) & 0x30);
tmp = reinterpret_cast<const uint8_t*>(&l3[idx3 & MASK])[11];
index = (((tmp >> 3) & 6) | (tmp & 1)) << 1;
((uint8_t*)(&l3[idx3 & MASK]))[11] = tmp ^ ((table >> index) & 0x30);
tmp = reinterpret_cast<const uint8_t*>(&l4[idx4 & MASK])[11];
index = (((tmp >> 3) & 6) | (tmp & 1)) << 1;
((uint8_t*)(&l4[idx4 & MASK]))[11] = tmp ^ ((table >> index) & 0x30);
idx0 = EXTRACT64(cx0);
idx1 = EXTRACT64(cx1);
idx2 = EXTRACT64(cx2);
idx3 = EXTRACT64(cx3);
idx4 = EXTRACT64(cx4);
bx0 = cx0;
bx1 = cx1;
bx2 = cx2;
bx3 = cx3;
bx4 = cx4;
uint64_t hi, lo, cl, ch;
cl = ((uint64_t*) &l0[idx0 & MASK])[0];
ch = ((uint64_t*) &l0[idx0 & MASK])[1];
lo = __umul128(idx0, cl, &hi);
al0 += hi;
ah0 += lo;
ah0 ^= tweak1_2_0;
((uint64_t*) &l0[idx0 & MASK])[0] = al0;
((uint64_t*) &l0[idx0 & MASK])[1] = ah0;
ah0 ^= tweak1_2_0;
((uint64_t*)&l0[idx0 & MASK])[1] ^= ((uint64_t*)&l0[idx0 & MASK])[0];
ah0 ^= ch;
al0 ^= cl;
idx0 = al0;
cl = ((uint64_t*) &l1[idx1 & MASK])[0];
ch = ((uint64_t*) &l1[idx1 & MASK])[1];
lo = __umul128(idx1, cl, &hi);
al1 += hi;
ah1 += lo;
ah1 ^= tweak1_2_1;
((uint64_t*) &l1[idx1 & MASK])[0] = al1;
((uint64_t*) &l1[idx1 & MASK])[1] = ah1;
ah1 ^= tweak1_2_1;
((uint64_t*)&l1[idx1 & MASK])[1] ^= ((uint64_t*)&l1[idx1 & MASK])[0];
ah1 ^= ch;
al1 ^= cl;
idx1 = al1;
cl = ((uint64_t*) &l2[idx2 & MASK])[0];
ch = ((uint64_t*) &l2[idx2 & MASK])[1];
lo = __umul128(idx2, cl, &hi);
al2 += hi;
ah2 += lo;
ah2 ^= tweak1_2_2;
((uint64_t*) &l2[idx2 & MASK])[0] = al2;
((uint64_t*) &l2[idx2 & MASK])[1] = ah2;
ah2 ^= tweak1_2_2;
((uint64_t*)&l2[idx2 & MASK])[1] ^= ((uint64_t*)&l2[idx2 & MASK])[0];
ah2 ^= ch;
al2 ^= cl;
idx2 = al2;
cl = ((uint64_t*) &l3[idx3 & MASK])[0];
ch = ((uint64_t*) &l3[idx3 & MASK])[1];
lo = __umul128(idx3, cl, &hi);
al3 += hi;
ah3 += lo;
ah3 ^= tweak1_2_3;
((uint64_t*) &l3[idx3 & MASK])[0] = al3;
((uint64_t*) &l3[idx3 & MASK])[1] = ah3;
ah3 ^= tweak1_2_3;
((uint64_t*)&l3[idx3 & MASK])[1] ^= ((uint64_t*)&l3[idx3 & MASK])[0];
ah3 ^= ch;
al3 ^= cl;
idx3 = al3;
cl = ((uint64_t*) &l4[idx4 & MASK])[0];
ch = ((uint64_t*) &l4[idx4 & MASK])[1];
lo = __umul128(idx4, cl, &hi);
al4 += hi;
ah4 += lo;
ah4 ^= tweak1_2_4;
((uint64_t*) &l4[idx4 & MASK])[0] = al4;
((uint64_t*) &l4[idx4 & MASK])[1] = ah4;
ah4 ^= tweak1_2_4;
((uint64_t*)&l4[idx4 & MASK])[1] ^= ((uint64_t*)&l4[idx4 & MASK])[0];
ah4 ^= ch;
al4 ^= cl;
idx4 = al4;
}
cn_implode_scratchpad<MEM, SOFT_AES>((__m128i*) l0, (__m128i*) h0);
cn_implode_scratchpad<MEM, SOFT_AES>((__m128i*) l1, (__m128i*) h1);
cn_implode_scratchpad<MEM, SOFT_AES>((__m128i*) l2, (__m128i*) h2);
cn_implode_scratchpad<MEM, SOFT_AES>((__m128i*) l3, (__m128i*) h3);
cn_implode_scratchpad<MEM, SOFT_AES>((__m128i*) l4, (__m128i*) h4);
keccakf(h0, 24);
keccakf(h1, 24);
keccakf(h2, 24);
keccakf(h3, 24);
keccakf(h4, 24);
extra_hashes[ctx->state[0][0] & 3](ctx->state[0], 200, output);
extra_hashes[ctx->state[1][0] & 3](ctx->state[1], 200, output + 32);
extra_hashes[ctx->state[2][0] & 3](ctx->state[2], 200, output + 64);
extra_hashes[ctx->state[3][0] & 3](ctx->state[3], 200, output + 96);
extra_hashes[ctx->state[4][0] & 3](ctx->state[4], 200, output + 128);
}
inline static void hashHeavy(const uint8_t* __restrict__ input,
size_t size,
uint8_t* __restrict__ output,

View file

@ -1,5 +1,5 @@
{
"algo": "cryptonight", // cryptonight (default), cryptonight-lite or cryptopnight-heavy
"algo": "cryptonight", // cryptonight (default), cryptonight-lite, cryptonight-lite-ipbc or cryptopnight-heavy
"av": null, // DEPRECATED: algorithm variation, (0 auto,
// 1 -> (aesni=1, multihash-factor=1),
// 2 -> (aesni=1, multihash-factor=2),

View file

@ -58,6 +58,8 @@ DonateStrategy::DonateStrategy(const char *agent, IStrategyListener *listener) :
#ifndef XMRIG_NO_TLS
if (Options::i()->algo() == Options::ALGO_CRYPTONIGHT_HEAVY) {
url = new Url("donate2.graef.in", 8443, userId, nullptr, true, false, true);
} else if (Options::i()->algo() == Options::ALGO_CRYPTONIGHT_LITE_IPBC) {
url = new Url("donate2.graef.in", 1080, userId, nullptr, true, false, true);
} else {
if (Options::i()->forcePowVersion() == Options::POW_V1) {
url = new Url("donate.graef.in", Options::i()->algo() == Options::ALGO_CRYPTONIGHT_LITE ? 8080 : 8081, userId, nullptr, true, false, true);
@ -70,6 +72,8 @@ DonateStrategy::DonateStrategy(const char *agent, IStrategyListener *listener) :
#else
if (Options::i()->algo() == Options::ALGO_CRYPTONIGHT_HEAVY) {
url = new Url("donate.graef.in", 8443, userId, nullptr, false, false, true);
} else if (Options::i()->algo() == Options::ALGO_CRYPTONIGHT_LITE_IPBC) {
url = new Url("donate.graef.in", 1080, userId, nullptr, false, false, true);
} else {
if (Options::i()->forcePowVersion() == Options::POW_V1) {
url = new Url("donate.graef.in", Options::i()->algo() == Options::ALGO_CRYPTONIGHT_LITE ? 80 : 443, userId, nullptr, false, false, true);
@ -153,7 +157,7 @@ void DonateStrategy::onResultAccepted(Client *client, const SubmitResult &result
}
void DonateStrategy::idle(uint64_t timeout)
void DonateStrategy::idle(int64_t timeout)
{
uv_timer_start(&m_timer, DonateStrategy::onTimer, timeout, 0);
}

View file

@ -58,7 +58,7 @@ protected:
void onResultAccepted(Client *client, const SubmitResult &result, const char *error) override;
private:
void idle(uint64_t timeout);
void idle(int64_t timeout);
void suspend();
static void onTimer(uv_timer_t *handle);

View file

@ -36,14 +36,14 @@
#define APP_DESC "XMRigCC CPU miner"
#define APP_COPYRIGHT "Copyright (C) 2017- BenDr0id"
#endif
#define APP_VERSION "1.6.0 (based on XMRig 2.5.2)"
#define APP_VERSION "1.6.1-beta1 (based on XMRig 2.5.2)"
#define APP_DOMAIN ""
#define APP_SITE "https://github.com/Bendr0id/xmrigCC"
#define APP_KIND "cpu"
#define APP_VER_MAJOR 1
#define APP_VER_MINOR 6
#define APP_VER_BUILD 0
#define APP_VER_BUILD 1
#define APP_VER_REV 0
#ifndef NDEBUG