From 1474d3fe53328e1f9485406469c8dba523820b4d Mon Sep 17 00:00:00 2001 From: XMRig Date: Fri, 21 Apr 2017 10:40:11 +0300 Subject: [PATCH] Rename algo variants again, should be final numbers. --- CMakeLists.txt | 7 +- algo/cryptonight/bmi2/CMakeLists.txt | 2 +- algo/cryptonight/cryptonight_av1_aesni.c | 356 ++++++++++-------- algo/cryptonight/cryptonight_av1_aesni32.c | 239 ------------ algo/cryptonight/cryptonight_av2_aesni_bmi2.c | 211 ----------- ...ni_stak.c => cryptonight_av2_aesni_stak.c} | 2 +- algo/cryptonight/cryptonight_av3_aesni_alt.c | 216 ----------- ...refetch.c => cryptonight_av3_aesni_bmi2.c} | 6 +- ...c => cryptonight_av5_aesni_experimental.c} | 2 +- algo/cryptonight/cryptonight_common.c | 29 +- options.h | 8 +- test/cryptonight/CMakeLists.txt | 8 +- test/cryptonight/bmi2/CMakeLists.txt | 2 +- test/cryptonight/cryptonight.c | 44 +-- 14 files changed, 238 insertions(+), 894 deletions(-) delete mode 100644 algo/cryptonight/cryptonight_av1_aesni32.c delete mode 100644 algo/cryptonight/cryptonight_av2_aesni_bmi2.c rename algo/cryptonight/{cryptonight_av5_aesni_stak.c => cryptonight_av2_aesni_stak.c} (99%) delete mode 100644 algo/cryptonight/cryptonight_av3_aesni_alt.c rename algo/cryptonight/{cryptonight_av6_aesni_stak_no_prefetch.c => cryptonight_av3_aesni_bmi2.c} (97%) rename algo/cryptonight/{cryptonight_av7_aesni_experimental.c => cryptonight_av5_aesni_experimental.c} (99%) diff --git a/CMakeLists.txt b/CMakeLists.txt index 9aacdcba7..60cb047bc 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -101,11 +101,10 @@ if (CMAKE_SIZEOF_VOID_P EQUAL 8) set(CRYPTONIGHT64 algo/cryptonight/cryptonight_av1_aesni.c - algo/cryptonight/cryptonight_av3_aesni_alt.c + algo/cryptonight/cryptonight_av2_aesni_stak.c + algo/cryptonight/cryptonight_av3_aesni_bmi2.c algo/cryptonight/cryptonight_av4_softaes.c - algo/cryptonight/cryptonight_av5_aesni_stak.c - algo/cryptonight/cryptonight_av6_aesni_stak_no_prefetch.c - algo/cryptonight/cryptonight_av7_aesni_experimental.c + algo/cryptonight/cryptonight_av5_aesni_experimental.c ) add_executable(xmrig ${HEADERS} ${HEADERS_CRYPTO} ${SOURCES} ${SOURCES_CRYPTO} ${HEADERS_UTILS} ${SOURCES_UTILS} ${HEADERS_COMPAT} ${SOURCES_COMPAT} ${SOURCES_OS} ${CRYPTONIGHT64}) diff --git a/algo/cryptonight/bmi2/CMakeLists.txt b/algo/cryptonight/bmi2/CMakeLists.txt index 03c1e3f7f..c9a3fd856 100644 --- a/algo/cryptonight/bmi2/CMakeLists.txt +++ b/algo/cryptonight/bmi2/CMakeLists.txt @@ -1,2 +1,2 @@ set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -mbmi2") -add_library(cryptonight_av3_aesni_bmi2 STATIC ../cryptonight_av2_aesni_bmi2.c) +add_library(cryptonight_av3_aesni_bmi2 STATIC ../cryptonight_av3_aesni_bmi2.c) diff --git a/algo/cryptonight/cryptonight_av1_aesni.c b/algo/cryptonight/cryptonight_av1_aesni.c index cf28a4629..fb7d45fd6 100644 --- a/algo/cryptonight/cryptonight_av1_aesni.c +++ b/algo/cryptonight/cryptonight_av1_aesni.c @@ -4,6 +4,7 @@ * Copyright 2014 Lucas Jones * Copyright 2014-2016 Wolf9466 * Copyright 2016 Jay D Dee + * Copyright 2017 fireice-uk * Copyright 2016-2017 XMRig * * @@ -28,186 +29,241 @@ #include "crypto/c_keccak.h" -static inline void ExpandAESKey256_sub1(__m128i *tmp1, __m128i *tmp2) +#ifdef __GNUC__ +static inline uint64_t _umul128(uint64_t a, uint64_t b, uint64_t* hi) +{ + unsigned __int128 r = (unsigned __int128)a * (unsigned __int128)b; + *hi = r >> 64; + return (uint64_t)r; +} +#endif + +#define aes_genkey_sub(imm8) \ + __m128i xout1 = _mm_aeskeygenassist_si128(*xout2, (imm8)); \ + xout1 = _mm_shuffle_epi32(xout1, 0xFF); \ + *xout0 = sl_xor(*xout0); \ + *xout0 = _mm_xor_si128(*xout0, xout1); \ + xout1 = _mm_aeskeygenassist_si128(*xout0, 0x00);\ + xout1 = _mm_shuffle_epi32(xout1, 0xAA); \ + *xout2 = sl_xor(*xout2); \ + *xout2 = _mm_xor_si128(*xout2, xout1); \ + + +// This will shift and xor tmp1 into itself as 4 32-bit vals such as +// sl_xor(a1 a2 a3 a4) = a1 (a2^a1) (a3^a2^a1) (a4^a3^a2^a1) +static inline __m128i sl_xor(__m128i tmp1) { __m128i tmp4; - *tmp2 = _mm_shuffle_epi32(*tmp2, 0xFF); - tmp4 = _mm_slli_si128(*tmp1, 0x04); - *tmp1 = _mm_xor_si128(*tmp1, tmp4); + tmp4 = _mm_slli_si128(tmp1, 0x04); + tmp1 = _mm_xor_si128(tmp1, tmp4); tmp4 = _mm_slli_si128(tmp4, 0x04); - *tmp1 = _mm_xor_si128(*tmp1, tmp4); + tmp1 = _mm_xor_si128(tmp1, tmp4); tmp4 = _mm_slli_si128(tmp4, 0x04); - *tmp1 = _mm_xor_si128(*tmp1, tmp4); - *tmp1 = _mm_xor_si128(*tmp1, *tmp2); + tmp1 = _mm_xor_si128(tmp1, tmp4); + return tmp1; } -static inline void ExpandAESKey256_sub2(__m128i *tmp1, __m128i *tmp3) -{ - __m128i tmp2, tmp4; - tmp4 = _mm_aeskeygenassist_si128(*tmp1, 0x00); - tmp2 = _mm_shuffle_epi32(tmp4, 0xAA); - tmp4 = _mm_slli_si128(*tmp3, 0x04); - *tmp3 = _mm_xor_si128(*tmp3, tmp4); - tmp4 = _mm_slli_si128(tmp4, 0x04); - *tmp3 = _mm_xor_si128(*tmp3, tmp4); - tmp4 = _mm_slli_si128(tmp4, 0x04); - *tmp3 = _mm_xor_si128(*tmp3, tmp4); - *tmp3 = _mm_xor_si128(*tmp3, tmp2); +static inline void aes_genkey_sub1(__m128i* xout0, __m128i* xout2) +{ + aes_genkey_sub(0x1) } -// Special thanks to Intel for helping me -// with ExpandAESKey256() and its subroutines -static inline void ExpandAESKey256(char *keybuf) + +static inline void aes_genkey_sub2(__m128i* xout0, __m128i* xout2) { - __m128i tmp1, tmp2, tmp3, *keys; - - keys = (__m128i *)keybuf; - - tmp1 = _mm_load_si128((__m128i *)keybuf); - tmp3 = _mm_load_si128((__m128i *)(keybuf+0x10)); - - tmp2 = _mm_aeskeygenassist_si128(tmp3, 0x01); - ExpandAESKey256_sub1(&tmp1, &tmp2); - keys[2] = tmp1; - ExpandAESKey256_sub2(&tmp1, &tmp3); - keys[3] = tmp3; - - tmp2 = _mm_aeskeygenassist_si128(tmp3, 0x02); - ExpandAESKey256_sub1(&tmp1, &tmp2); - keys[4] = tmp1; - ExpandAESKey256_sub2(&tmp1, &tmp3); - keys[5] = tmp3; - - tmp2 = _mm_aeskeygenassist_si128(tmp3, 0x04); - ExpandAESKey256_sub1(&tmp1, &tmp2); - keys[6] = tmp1; - ExpandAESKey256_sub2(&tmp1, &tmp3); - keys[7] = tmp3; - - tmp2 = _mm_aeskeygenassist_si128(tmp3, 0x08); - ExpandAESKey256_sub1(&tmp1, &tmp2); - keys[8] = tmp1; - ExpandAESKey256_sub2(&tmp1, &tmp3); - keys[9] = tmp3; - - tmp2 = _mm_aeskeygenassist_si128(tmp3, 0x10); - ExpandAESKey256_sub1(&tmp1, &tmp2); - keys[10] = tmp1; - ExpandAESKey256_sub2(&tmp1, &tmp3); - keys[11] = tmp3; - - tmp2 = _mm_aeskeygenassist_si128(tmp3, 0x20); - ExpandAESKey256_sub1(&tmp1, &tmp2); - keys[12] = tmp1; - ExpandAESKey256_sub2(&tmp1, &tmp3); - keys[13] = tmp3; - - tmp2 = _mm_aeskeygenassist_si128(tmp3, 0x40); - ExpandAESKey256_sub1(&tmp1, &tmp2); - keys[14] = tmp1; + aes_genkey_sub(0x2) } -void cryptonight_av1_aesni(void *restrict output, const void *restrict input, const char *restrict memory, struct cryptonight_ctx *restrict ctx) + +static inline void aes_genkey_sub4(__m128i* xout0, __m128i* xout2) { - uint64_t* state = ctx->state.hs.w; + aes_genkey_sub(0x4) +} - keccak((const uint8_t *)input, 76, (uint8_t *) state, 200); - uint8_t ExpandedKey[256]; - size_t i, j; - memcpy(ctx->text, ctx->state.init, INIT_SIZE_BYTE); - memcpy(ExpandedKey, ctx->state.hs.b, AES_KEY_SIZE); - ExpandAESKey256(ExpandedKey); +static inline void aes_genkey_sub8(__m128i* xout0, __m128i* xout2) +{ + aes_genkey_sub(0x8) +} - __m128i *longoutput, *expkey, *xmminput; - longoutput = (__m128i *) memory; - expkey = (__m128i *)ExpandedKey; - xmminput = (__m128i *)ctx->text; - for (i = 0; __builtin_expect(i < MEMORY, 1); i += INIT_SIZE_BYTE) +static inline void aes_genkey(const __m128i* memory, __m128i* k0, __m128i* k1, __m128i* k2, __m128i* k3, __m128i* k4, __m128i* k5, __m128i* k6, __m128i* k7, __m128i* k8, __m128i* k9) +{ + __m128i xout0 = _mm_load_si128(memory); + __m128i xout2 = _mm_load_si128(memory + 1); + *k0 = xout0; + *k1 = xout2; + + aes_genkey_sub1(&xout0, &xout2); + *k2 = xout0; + *k3 = xout2; + + aes_genkey_sub2(&xout0, &xout2); + *k4 = xout0; + *k5 = xout2; + + aes_genkey_sub4(&xout0, &xout2); + *k6 = xout0; + *k7 = xout2; + + aes_genkey_sub8(&xout0, &xout2); + *k8 = xout0; + *k9 = xout2; +} + + +static inline void aes_round(__m128i key, __m128i* x0, __m128i* x1, __m128i* x2, __m128i* x3, __m128i* x4, __m128i* x5, __m128i* x6, __m128i* x7) +{ + *x0 = _mm_aesenc_si128(*x0, key); + *x1 = _mm_aesenc_si128(*x1, key); + *x2 = _mm_aesenc_si128(*x2, key); + *x3 = _mm_aesenc_si128(*x3, key); + *x4 = _mm_aesenc_si128(*x4, key); + *x5 = _mm_aesenc_si128(*x5, key); + *x6 = _mm_aesenc_si128(*x6, key); + *x7 = _mm_aesenc_si128(*x7, key); +} + + +static inline void cn_explode_scratchpad(const __m128i* input, __m128i* output) +{ + // This is more than we have registers, compiler will assign 2 keys on the stack + __m128i xin0, xin1, xin2, xin3, xin4, xin5, xin6, xin7; + __m128i k0, k1, k2, k3, k4, k5, k6, k7, k8, k9; + + aes_genkey(input, &k0, &k1, &k2, &k3, &k4, &k5, &k6, &k7, &k8, &k9); + + xin0 = _mm_load_si128(input + 4); + xin1 = _mm_load_si128(input + 5); + xin2 = _mm_load_si128(input + 6); + xin3 = _mm_load_si128(input + 7); + xin4 = _mm_load_si128(input + 8); + xin5 = _mm_load_si128(input + 9); + xin6 = _mm_load_si128(input + 10); + xin7 = _mm_load_si128(input + 11); + + for (size_t i = 0; i < MEMORY / sizeof(__m128i); i += 8) { + aes_round(k0, &xin0, &xin1, &xin2, &xin3, &xin4, &xin5, &xin6, &xin7); + aes_round(k1, &xin0, &xin1, &xin2, &xin3, &xin4, &xin5, &xin6, &xin7); + aes_round(k2, &xin0, &xin1, &xin2, &xin3, &xin4, &xin5, &xin6, &xin7); + aes_round(k3, &xin0, &xin1, &xin2, &xin3, &xin4, &xin5, &xin6, &xin7); + aes_round(k4, &xin0, &xin1, &xin2, &xin3, &xin4, &xin5, &xin6, &xin7); + aes_round(k5, &xin0, &xin1, &xin2, &xin3, &xin4, &xin5, &xin6, &xin7); + aes_round(k6, &xin0, &xin1, &xin2, &xin3, &xin4, &xin5, &xin6, &xin7); + aes_round(k7, &xin0, &xin1, &xin2, &xin3, &xin4, &xin5, &xin6, &xin7); + aes_round(k8, &xin0, &xin1, &xin2, &xin3, &xin4, &xin5, &xin6, &xin7); + aes_round(k9, &xin0, &xin1, &xin2, &xin3, &xin4, &xin5, &xin6, &xin7); + + _mm_store_si128(output + i + 0, xin0); + _mm_store_si128(output + i + 1, xin1); + _mm_store_si128(output + i + 2, xin2); + _mm_store_si128(output + i + 3, xin3); + _mm_prefetch((const char*)output + i + 0, _MM_HINT_T2); + _mm_store_si128(output + i + 4, xin4); + _mm_store_si128(output + i + 5, xin5); + _mm_store_si128(output + i + 6, xin6); + _mm_store_si128(output + i + 7, xin7); + _mm_prefetch((const char*)output + i + 4, _MM_HINT_T2); + } +} + + +static inline void cn_implode_scratchpad(const __m128i* input, __m128i* output) +{ + // This is more than we have registers, compiler will assign 2 keys on the stack + __m128i xout0, xout1, xout2, xout3, xout4, xout5, xout6, xout7; + __m128i k0, k1, k2, k3, k4, k5, k6, k7, k8, k9; + + aes_genkey(output + 2, &k0, &k1, &k2, &k3, &k4, &k5, &k6, &k7, &k8, &k9); + + xout0 = _mm_load_si128(output + 4); + xout1 = _mm_load_si128(output + 5); + xout2 = _mm_load_si128(output + 6); + xout3 = _mm_load_si128(output + 7); + xout4 = _mm_load_si128(output + 8); + xout5 = _mm_load_si128(output + 9); + xout6 = _mm_load_si128(output + 10); + xout7 = _mm_load_si128(output + 11); + + for (size_t i = 0; i < MEMORY / sizeof(__m128i); i += 8) { - for(j = 0; j < 10; j++) - { - xmminput[0] = _mm_aesenc_si128(xmminput[0], expkey[j]); - xmminput[1] = _mm_aesenc_si128(xmminput[1], expkey[j]); - xmminput[2] = _mm_aesenc_si128(xmminput[2], expkey[j]); - xmminput[3] = _mm_aesenc_si128(xmminput[3], expkey[j]); - xmminput[4] = _mm_aesenc_si128(xmminput[4], expkey[j]); - xmminput[5] = _mm_aesenc_si128(xmminput[5], expkey[j]); - xmminput[6] = _mm_aesenc_si128(xmminput[6], expkey[j]); - xmminput[7] = _mm_aesenc_si128(xmminput[7], expkey[j]); - } - _mm_store_si128(&(longoutput[(i >> 4)]), xmminput[0]); - _mm_store_si128(&(longoutput[(i >> 4) + 1]), xmminput[1]); - _mm_store_si128(&(longoutput[(i >> 4) + 2]), xmminput[2]); - _mm_store_si128(&(longoutput[(i >> 4) + 3]), xmminput[3]); - _mm_store_si128(&(longoutput[(i >> 4) + 4]), xmminput[4]); - _mm_store_si128(&(longoutput[(i >> 4) + 5]), xmminput[5]); - _mm_store_si128(&(longoutput[(i >> 4) + 6]), xmminput[6]); - _mm_store_si128(&(longoutput[(i >> 4) + 7]), xmminput[7]); + _mm_prefetch((const char*)input + i + 0, _MM_HINT_NTA); + xout0 = _mm_xor_si128(_mm_load_si128(input + i + 0), xout0); + xout1 = _mm_xor_si128(_mm_load_si128(input + i + 1), xout1); + xout2 = _mm_xor_si128(_mm_load_si128(input + i + 2), xout2); + xout3 = _mm_xor_si128(_mm_load_si128(input + i + 3), xout3); + _mm_prefetch((const char*)input + i + 4, _MM_HINT_NTA); + xout4 = _mm_xor_si128(_mm_load_si128(input + i + 4), xout4); + xout5 = _mm_xor_si128(_mm_load_si128(input + i + 5), xout5); + xout6 = _mm_xor_si128(_mm_load_si128(input + i + 6), xout6); + xout7 = _mm_xor_si128(_mm_load_si128(input + i + 7), xout7); + + aes_round(k0, &xout0, &xout1, &xout2, &xout3, &xout4, &xout5, &xout6, &xout7); + aes_round(k1, &xout0, &xout1, &xout2, &xout3, &xout4, &xout5, &xout6, &xout7); + aes_round(k2, &xout0, &xout1, &xout2, &xout3, &xout4, &xout5, &xout6, &xout7); + aes_round(k3, &xout0, &xout1, &xout2, &xout3, &xout4, &xout5, &xout6, &xout7); + aes_round(k4, &xout0, &xout1, &xout2, &xout3, &xout4, &xout5, &xout6, &xout7); + aes_round(k5, &xout0, &xout1, &xout2, &xout3, &xout4, &xout5, &xout6, &xout7); + aes_round(k6, &xout0, &xout1, &xout2, &xout3, &xout4, &xout5, &xout6, &xout7); + aes_round(k7, &xout0, &xout1, &xout2, &xout3, &xout4, &xout5, &xout6, &xout7); + aes_round(k8, &xout0, &xout1, &xout2, &xout3, &xout4, &xout5, &xout6, &xout7); + aes_round(k9, &xout0, &xout1, &xout2, &xout3, &xout4, &xout5, &xout6, &xout7); } - uint64_t a[2] __attribute((aligned(16))) = { state[0] ^ state[4], state[1] ^ state[5] }; - uint64_t c __attribute((aligned(16))); - uint64_t d[2] __attribute((aligned(16))); + _mm_store_si128(output + 4, xout0); + _mm_store_si128(output + 5, xout1); + _mm_store_si128(output + 6, xout2); + _mm_store_si128(output + 7, xout3); + _mm_store_si128(output + 8, xout4); + _mm_store_si128(output + 9, xout5); + _mm_store_si128(output + 10, xout6); + _mm_store_si128(output + 11, xout7); +} - __m128i a_x = _mm_load_si128((__m128i *) &memory[a[0] & 0x1FFFF0]); - __m128i b_x = _mm_set_epi64x(state[3] ^ state[7], state[2] ^ state[6]); - for (i = 0; __builtin_expect(i < 0x80000, 1); i++) { - __m128i c_x = _mm_aesenc_si128(a_x, _mm_load_si128((__m128i *) a)); - c = _mm_cvtsi128_si64(c_x); +void cryptonight_av1_aesni(void *restrict output, const void *restrict input, char *restrict memory, struct cryptonight_ctx *restrict ctx) +{ + keccak((const uint8_t *) input, 76, (uint8_t *) &ctx->state.hs, 200); - uint64_t *restrict d_ptr = (uint64_t *) &memory[c & 0x1FFFF0]; - _mm_store_si128((__m128i *) &memory[a[0] & 0x1FFFF0], _mm_xor_si128(b_x, c_x)); - b_x = c_x; + cn_explode_scratchpad((__m128i*) &ctx->state.hs, (__m128i*) memory); - d[0] = d_ptr[0]; - d[1] = d_ptr[1]; + const uint8_t* l0 = memory; + uint64_t* h0 = (uint64_t*) &ctx->state.hs; - { - unsigned __int128 res = (unsigned __int128) c * d[0]; + uint64_t al0 = h0[0] ^ h0[4]; + uint64_t ah0 = h0[1] ^ h0[5]; + __m128i bx0 = _mm_set_epi64x(h0[3] ^ h0[7], h0[2] ^ h0[6]); - d_ptr[0] = a[0] += res >> 64; - d_ptr[1] = a[1] += (uint64_t) res; - } + uint64_t idx0 = h0[0] ^ h0[4]; - a[0] ^= d[0]; - a[1] ^= d[1]; + for (size_t i = 0; __builtin_expect(i < 0x80000, 1); i++) { + __m128i cx; + cx = _mm_load_si128((__m128i *)&l0[idx0 & 0x1FFFF0]); + cx = _mm_aesenc_si128(cx, _mm_set_epi64x(ah0, al0)); - a_x = _mm_load_si128((__m128i *) &memory[a[0] & 0x1FFFF0]); + _mm_store_si128((__m128i *)&l0[idx0 & 0x1FFFF0], _mm_xor_si128(bx0, cx)); + idx0 = _mm_cvtsi128_si64(cx); + bx0 = cx; + + uint64_t hi, lo, cl, ch; + cl = ((uint64_t*)&l0[idx0 & 0x1FFFF0])[0]; + ch = ((uint64_t*)&l0[idx0 & 0x1FFFF0])[1]; + lo = _umul128(idx0, cl, &hi); + + al0 += hi; + ah0 += lo; + + ((uint64_t*)&l0[idx0 & 0x1FFFF0])[0] = al0; + ((uint64_t*)&l0[idx0 & 0x1FFFF0])[1] = ah0; + + ah0 ^= ch; + al0 ^= cl; + idx0 = al0; } - memcpy(ctx->text, ctx->state.init, INIT_SIZE_BYTE); - memcpy(ExpandedKey, &ctx->state.hs.b[32], AES_KEY_SIZE); - ExpandAESKey256(ExpandedKey); + cn_implode_scratchpad((__m128i*) memory, (__m128i*) &ctx->state.hs); - for (i = 0; __builtin_expect(i < MEMORY, 1); i += INIT_SIZE_BYTE) { - xmminput[0] = _mm_xor_si128(longoutput[(i >> 4)], xmminput[0]); - xmminput[1] = _mm_xor_si128(longoutput[(i >> 4) + 1], xmminput[1]); - xmminput[2] = _mm_xor_si128(longoutput[(i >> 4) + 2], xmminput[2]); - xmminput[3] = _mm_xor_si128(longoutput[(i >> 4) + 3], xmminput[3]); - xmminput[4] = _mm_xor_si128(longoutput[(i >> 4) + 4], xmminput[4]); - xmminput[5] = _mm_xor_si128(longoutput[(i >> 4) + 5], xmminput[5]); - xmminput[6] = _mm_xor_si128(longoutput[(i >> 4) + 6], xmminput[6]); - xmminput[7] = _mm_xor_si128(longoutput[(i >> 4) + 7], xmminput[7]); - - for(j = 0; j < 10; j++) - { - xmminput[0] = _mm_aesenc_si128(xmminput[0], expkey[j]); - xmminput[1] = _mm_aesenc_si128(xmminput[1], expkey[j]); - xmminput[2] = _mm_aesenc_si128(xmminput[2], expkey[j]); - xmminput[3] = _mm_aesenc_si128(xmminput[3], expkey[j]); - xmminput[4] = _mm_aesenc_si128(xmminput[4], expkey[j]); - xmminput[5] = _mm_aesenc_si128(xmminput[5], expkey[j]); - xmminput[6] = _mm_aesenc_si128(xmminput[6], expkey[j]); - xmminput[7] = _mm_aesenc_si128(xmminput[7], expkey[j]); - } - - } - - memcpy(ctx->state.init, ctx->text, INIT_SIZE_BYTE); - keccakf((uint64_t *) state, 24); + keccakf((uint64_t*) &ctx->state.hs, 24); extra_hashes[ctx->state.hs.b[0] & 3](&ctx->state, 200, output); } diff --git a/algo/cryptonight/cryptonight_av1_aesni32.c b/algo/cryptonight/cryptonight_av1_aesni32.c deleted file mode 100644 index 5ca311f4a..000000000 --- a/algo/cryptonight/cryptonight_av1_aesni32.c +++ /dev/null @@ -1,239 +0,0 @@ -/* XMRig - * Copyright 2010 Jeff Garzik - * Copyright 2012-2014 pooler - * Copyright 2014 Lucas Jones - * Copyright 2014-2016 Wolf9466 - * Copyright 2016 Jay D Dee - * Copyright 2016-2017 XMRig - * - * - * This program is free software: you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program. If not, see . - */ - -#include -#include - -#include "cryptonight.h" -#include "crypto/c_keccak.h" - - -static inline uint64_t mul128(uint64_t multiplier, uint64_t multiplicand, uint64_t *product_hi) { - // multiplier = ab = a * 2^32 + b - // multiplicand = cd = c * 2^32 + d - // ab * cd = a * c * 2^64 + (a * d + b * c) * 2^32 + b * d - uint64_t a = multiplier >> 32; - uint64_t b = multiplier & 0xFFFFFFFF; - uint64_t c = multiplicand >> 32; - uint64_t d = multiplicand & 0xFFFFFFFF; - - //uint64_t ac = a * c; - uint64_t ad = a * d; - //uint64_t bc = b * c; - uint64_t bd = b * d; - - uint64_t adbc = ad + (b * c); - uint64_t adbc_carry = adbc < ad ? 1 : 0; - - // multiplier * multiplicand = product_hi * 2^64 + product_lo - uint64_t product_lo = bd + (adbc << 32); - uint64_t product_lo_carry = product_lo < bd ? 1 : 0; - *product_hi = (a * c) + (adbc >> 32) + (adbc_carry << 32) + product_lo_carry; - - return product_lo; -} - - -static inline void ExpandAESKey256_sub1(__m128i *tmp1, __m128i *tmp2) -{ - __m128i tmp4; - *tmp2 = _mm_shuffle_epi32(*tmp2, 0xFF); - tmp4 = _mm_slli_si128(*tmp1, 0x04); - *tmp1 = _mm_xor_si128(*tmp1, tmp4); - tmp4 = _mm_slli_si128(tmp4, 0x04); - *tmp1 = _mm_xor_si128(*tmp1, tmp4); - tmp4 = _mm_slli_si128(tmp4, 0x04); - *tmp1 = _mm_xor_si128(*tmp1, tmp4); - *tmp1 = _mm_xor_si128(*tmp1, *tmp2); -} - -static inline void ExpandAESKey256_sub2(__m128i *tmp1, __m128i *tmp3) -{ - __m128i tmp2, tmp4; - - tmp4 = _mm_aeskeygenassist_si128(*tmp1, 0x00); - tmp2 = _mm_shuffle_epi32(tmp4, 0xAA); - tmp4 = _mm_slli_si128(*tmp3, 0x04); - *tmp3 = _mm_xor_si128(*tmp3, tmp4); - tmp4 = _mm_slli_si128(tmp4, 0x04); - *tmp3 = _mm_xor_si128(*tmp3, tmp4); - tmp4 = _mm_slli_si128(tmp4, 0x04); - *tmp3 = _mm_xor_si128(*tmp3, tmp4); - *tmp3 = _mm_xor_si128(*tmp3, tmp2); -} - -// Special thanks to Intel for helping me -// with ExpandAESKey256() and its subroutines -static inline void ExpandAESKey256(char *keybuf) -{ - __m128i tmp1, tmp2, tmp3, *keys; - - keys = (__m128i *)keybuf; - - tmp1 = _mm_load_si128((__m128i *)keybuf); - tmp3 = _mm_load_si128((__m128i *)(keybuf+0x10)); - - tmp2 = _mm_aeskeygenassist_si128(tmp3, 0x01); - ExpandAESKey256_sub1(&tmp1, &tmp2); - keys[2] = tmp1; - ExpandAESKey256_sub2(&tmp1, &tmp3); - keys[3] = tmp3; - - tmp2 = _mm_aeskeygenassist_si128(tmp3, 0x02); - ExpandAESKey256_sub1(&tmp1, &tmp2); - keys[4] = tmp1; - ExpandAESKey256_sub2(&tmp1, &tmp3); - keys[5] = tmp3; - - tmp2 = _mm_aeskeygenassist_si128(tmp3, 0x04); - ExpandAESKey256_sub1(&tmp1, &tmp2); - keys[6] = tmp1; - ExpandAESKey256_sub2(&tmp1, &tmp3); - keys[7] = tmp3; - - tmp2 = _mm_aeskeygenassist_si128(tmp3, 0x08); - ExpandAESKey256_sub1(&tmp1, &tmp2); - keys[8] = tmp1; - ExpandAESKey256_sub2(&tmp1, &tmp3); - keys[9] = tmp3; - - tmp2 = _mm_aeskeygenassist_si128(tmp3, 0x10); - ExpandAESKey256_sub1(&tmp1, &tmp2); - keys[10] = tmp1; - ExpandAESKey256_sub2(&tmp1, &tmp3); - keys[11] = tmp3; - - tmp2 = _mm_aeskeygenassist_si128(tmp3, 0x20); - ExpandAESKey256_sub1(&tmp1, &tmp2); - keys[12] = tmp1; - ExpandAESKey256_sub2(&tmp1, &tmp3); - keys[13] = tmp3; - - tmp2 = _mm_aeskeygenassist_si128(tmp3, 0x40); - ExpandAESKey256_sub1(&tmp1, &tmp2); - keys[14] = tmp1; -} - -void cryptonight_av1_aesni32(void *restrict output, const void *restrict input, const char *restrict memory, struct cryptonight_ctx *restrict ctx) -{ - keccak((const uint8_t *)input, 76, (uint8_t *) &ctx->state.hs, 200); - uint8_t ExpandedKey[256]; - size_t i, j; - - memcpy(ctx->text, ctx->state.init, INIT_SIZE_BYTE); - memcpy(ExpandedKey, ctx->state.hs.b, AES_KEY_SIZE); - ExpandAESKey256(ExpandedKey); - - __m128i *longoutput, *expkey, *xmminput; - longoutput = (__m128i *) memory; - expkey = (__m128i *)ExpandedKey; - xmminput = (__m128i *)ctx->text; - - for (i = 0; __builtin_expect(i < MEMORY, 1); i += INIT_SIZE_BYTE) - { - for(j = 0; j < 10; j++) - { - xmminput[0] = _mm_aesenc_si128(xmminput[0], expkey[j]); - xmminput[1] = _mm_aesenc_si128(xmminput[1], expkey[j]); - xmminput[2] = _mm_aesenc_si128(xmminput[2], expkey[j]); - xmminput[3] = _mm_aesenc_si128(xmminput[3], expkey[j]); - xmminput[4] = _mm_aesenc_si128(xmminput[4], expkey[j]); - xmminput[5] = _mm_aesenc_si128(xmminput[5], expkey[j]); - xmminput[6] = _mm_aesenc_si128(xmminput[6], expkey[j]); - xmminput[7] = _mm_aesenc_si128(xmminput[7], expkey[j]); - } - _mm_store_si128(&(longoutput[(i >> 4)]), xmminput[0]); - _mm_store_si128(&(longoutput[(i >> 4) + 1]), xmminput[1]); - _mm_store_si128(&(longoutput[(i >> 4) + 2]), xmminput[2]); - _mm_store_si128(&(longoutput[(i >> 4) + 3]), xmminput[3]); - _mm_store_si128(&(longoutput[(i >> 4) + 4]), xmminput[4]); - _mm_store_si128(&(longoutput[(i >> 4) + 5]), xmminput[5]); - _mm_store_si128(&(longoutput[(i >> 4) + 6]), xmminput[6]); - _mm_store_si128(&(longoutput[(i >> 4) + 7]), xmminput[7]); - } - - for (i = 0; i < 2; i++) - { - ctx->a[i] = ((uint64_t *)ctx->state.k)[i] ^ ((uint64_t *)ctx->state.k)[i+4]; - ctx->b[i] = ((uint64_t *)ctx->state.k)[i+2] ^ ((uint64_t *)ctx->state.k)[i+6]; - } - - __m128i a_x = _mm_load_si128((__m128i *) &memory[ctx->a[0] & 0x1FFFF0]); - __m128i b_x = _mm_load_si128((__m128i *) ctx->b); - - uint64_t c[2] __attribute((aligned(16))); - uint64_t d[2] __attribute((aligned(16))); - uint64_t hi; - - for (i = 0; __builtin_expect(i < 0x80000, 1); i++) { - __m128i c_x = _mm_aesenc_si128(a_x, _mm_load_si128((__m128i *) ctx->a)); - _mm_store_si128((__m128i *) c, c_x); - - uint64_t *restrict d_ptr = (uint64_t *) &memory[c[0] & 0x1FFFF0]; - _mm_store_si128((__m128i *) &memory[ctx->a[0] & 0x1FFFF0], _mm_xor_si128(b_x, c_x)); - b_x = c_x; - - d[0] = d_ptr[0]; - d[1] = d_ptr[1]; - - d_ptr[1] = ctx->a[1] += mul128(c[0], d[0], &hi); - d_ptr[0] = ctx->a[0] += hi; - - ctx->a[0] ^= d[0]; - ctx->a[1] ^= d[1]; - - a_x = _mm_load_si128((__m128i *) &memory[ctx->a[0] & 0x1FFFF0]); - } - - memcpy(ctx->text, ctx->state.init, INIT_SIZE_BYTE); - memcpy(ExpandedKey, &ctx->state.hs.b[32], AES_KEY_SIZE); - ExpandAESKey256(ExpandedKey); - - for (i = 0; __builtin_expect(i < MEMORY, 1); i += INIT_SIZE_BYTE) { - xmminput[0] = _mm_xor_si128(longoutput[(i >> 4)], xmminput[0]); - xmminput[1] = _mm_xor_si128(longoutput[(i >> 4) + 1], xmminput[1]); - xmminput[2] = _mm_xor_si128(longoutput[(i >> 4) + 2], xmminput[2]); - xmminput[3] = _mm_xor_si128(longoutput[(i >> 4) + 3], xmminput[3]); - xmminput[4] = _mm_xor_si128(longoutput[(i >> 4) + 4], xmminput[4]); - xmminput[5] = _mm_xor_si128(longoutput[(i >> 4) + 5], xmminput[5]); - xmminput[6] = _mm_xor_si128(longoutput[(i >> 4) + 6], xmminput[6]); - xmminput[7] = _mm_xor_si128(longoutput[(i >> 4) + 7], xmminput[7]); - - for(j = 0; j < 10; j++) - { - xmminput[0] = _mm_aesenc_si128(xmminput[0], expkey[j]); - xmminput[1] = _mm_aesenc_si128(xmminput[1], expkey[j]); - xmminput[2] = _mm_aesenc_si128(xmminput[2], expkey[j]); - xmminput[3] = _mm_aesenc_si128(xmminput[3], expkey[j]); - xmminput[4] = _mm_aesenc_si128(xmminput[4], expkey[j]); - xmminput[5] = _mm_aesenc_si128(xmminput[5], expkey[j]); - xmminput[6] = _mm_aesenc_si128(xmminput[6], expkey[j]); - xmminput[7] = _mm_aesenc_si128(xmminput[7], expkey[j]); - } - - } - - memcpy(ctx->state.init, ctx->text, INIT_SIZE_BYTE); - keccakf((uint64_t *) &ctx->state.hs, 24); - extra_hashes[ctx->state.hs.b[0] & 3](&ctx->state, 200, output); -} diff --git a/algo/cryptonight/cryptonight_av2_aesni_bmi2.c b/algo/cryptonight/cryptonight_av2_aesni_bmi2.c deleted file mode 100644 index 15cf12c17..000000000 --- a/algo/cryptonight/cryptonight_av2_aesni_bmi2.c +++ /dev/null @@ -1,211 +0,0 @@ -/* XMRig - * Copyright 2010 Jeff Garzik - * Copyright 2012-2014 pooler - * Copyright 2014 Lucas Jones - * Copyright 2014-2016 Wolf9466 - * Copyright 2016 Jay D Dee - * Copyright 2016-2017 XMRig - * - * - * This program is free software: you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program. If not, see . - */ - -#include -#include - -#include "cryptonight.h" -#include "crypto/c_keccak.h" - - -static inline void ExpandAESKey256_sub1(__m128i *tmp1, __m128i *tmp2) -{ - __m128i tmp4; - *tmp2 = _mm_shuffle_epi32(*tmp2, 0xFF); - tmp4 = _mm_slli_si128(*tmp1, 0x04); - *tmp1 = _mm_xor_si128(*tmp1, tmp4); - tmp4 = _mm_slli_si128(tmp4, 0x04); - *tmp1 = _mm_xor_si128(*tmp1, tmp4); - tmp4 = _mm_slli_si128(tmp4, 0x04); - *tmp1 = _mm_xor_si128(*tmp1, tmp4); - *tmp1 = _mm_xor_si128(*tmp1, *tmp2); -} - -static inline void ExpandAESKey256_sub2(__m128i *tmp1, __m128i *tmp3) -{ - __m128i tmp2, tmp4; - - tmp4 = _mm_aeskeygenassist_si128(*tmp1, 0x00); - tmp2 = _mm_shuffle_epi32(tmp4, 0xAA); - tmp4 = _mm_slli_si128(*tmp3, 0x04); - *tmp3 = _mm_xor_si128(*tmp3, tmp4); - tmp4 = _mm_slli_si128(tmp4, 0x04); - *tmp3 = _mm_xor_si128(*tmp3, tmp4); - tmp4 = _mm_slli_si128(tmp4, 0x04); - *tmp3 = _mm_xor_si128(*tmp3, tmp4); - *tmp3 = _mm_xor_si128(*tmp3, tmp2); -} - -// Special thanks to Intel for helping me -// with ExpandAESKey256() and its subroutines -static inline void ExpandAESKey256(char *keybuf) -{ - __m128i tmp1, tmp2, tmp3, *keys; - - keys = (__m128i *)keybuf; - - tmp1 = _mm_load_si128((__m128i *)keybuf); - tmp3 = _mm_load_si128((__m128i *)(keybuf+0x10)); - - tmp2 = _mm_aeskeygenassist_si128(tmp3, 0x01); - ExpandAESKey256_sub1(&tmp1, &tmp2); - keys[2] = tmp1; - ExpandAESKey256_sub2(&tmp1, &tmp3); - keys[3] = tmp3; - - tmp2 = _mm_aeskeygenassist_si128(tmp3, 0x02); - ExpandAESKey256_sub1(&tmp1, &tmp2); - keys[4] = tmp1; - ExpandAESKey256_sub2(&tmp1, &tmp3); - keys[5] = tmp3; - - tmp2 = _mm_aeskeygenassist_si128(tmp3, 0x04); - ExpandAESKey256_sub1(&tmp1, &tmp2); - keys[6] = tmp1; - ExpandAESKey256_sub2(&tmp1, &tmp3); - keys[7] = tmp3; - - tmp2 = _mm_aeskeygenassist_si128(tmp3, 0x08); - ExpandAESKey256_sub1(&tmp1, &tmp2); - keys[8] = tmp1; - ExpandAESKey256_sub2(&tmp1, &tmp3); - keys[9] = tmp3; - - tmp2 = _mm_aeskeygenassist_si128(tmp3, 0x10); - ExpandAESKey256_sub1(&tmp1, &tmp2); - keys[10] = tmp1; - ExpandAESKey256_sub2(&tmp1, &tmp3); - keys[11] = tmp3; - - tmp2 = _mm_aeskeygenassist_si128(tmp3, 0x20); - ExpandAESKey256_sub1(&tmp1, &tmp2); - keys[12] = tmp1; - ExpandAESKey256_sub2(&tmp1, &tmp3); - keys[13] = tmp3; - - tmp2 = _mm_aeskeygenassist_si128(tmp3, 0x40); - ExpandAESKey256_sub1(&tmp1, &tmp2); - keys[14] = tmp1; -} - - -void cryptonight_av2_aesni_bmi2(void *restrict output, const void *restrict input, const char *restrict memory, struct cryptonight_ctx *restrict ctx) -{ - uint64_t* state = ctx->state.hs.w; - - keccak((const uint8_t *)input, 76, (uint8_t *) state, 200); - uint8_t ExpandedKey[256]; - size_t i, j; - - memcpy(ctx->text, ctx->state.init, INIT_SIZE_BYTE); - memcpy(ExpandedKey, ctx->state.hs.b, AES_KEY_SIZE); - ExpandAESKey256(ExpandedKey); - - __m128i *longoutput, *expkey, *xmminput; - longoutput = (__m128i *) memory; - expkey = (__m128i *)ExpandedKey; - xmminput = (__m128i *)ctx->text; - - for (i = 0; __builtin_expect(i < MEMORY, 1); i += INIT_SIZE_BYTE) - { - for(j = 0; j < 10; j++) - { - xmminput[0] = _mm_aesenc_si128(xmminput[0], expkey[j]); - xmminput[1] = _mm_aesenc_si128(xmminput[1], expkey[j]); - xmminput[2] = _mm_aesenc_si128(xmminput[2], expkey[j]); - xmminput[3] = _mm_aesenc_si128(xmminput[3], expkey[j]); - xmminput[4] = _mm_aesenc_si128(xmminput[4], expkey[j]); - xmminput[5] = _mm_aesenc_si128(xmminput[5], expkey[j]); - xmminput[6] = _mm_aesenc_si128(xmminput[6], expkey[j]); - xmminput[7] = _mm_aesenc_si128(xmminput[7], expkey[j]); - } - _mm_store_si128(&(longoutput[(i >> 4)]), xmminput[0]); - _mm_store_si128(&(longoutput[(i >> 4) + 1]), xmminput[1]); - _mm_store_si128(&(longoutput[(i >> 4) + 2]), xmminput[2]); - _mm_store_si128(&(longoutput[(i >> 4) + 3]), xmminput[3]); - _mm_store_si128(&(longoutput[(i >> 4) + 4]), xmminput[4]); - _mm_store_si128(&(longoutput[(i >> 4) + 5]), xmminput[5]); - _mm_store_si128(&(longoutput[(i >> 4) + 6]), xmminput[6]); - _mm_store_si128(&(longoutput[(i >> 4) + 7]), xmminput[7]); - } - - uint64_t a[2] __attribute((aligned(16))) = { state[0] ^ state[4], state[1] ^ state[5] }; - uint64_t c __attribute((aligned(16))); - uint64_t d[2] __attribute((aligned(16))); - uint64_t hi; - - __m128i a_x = _mm_load_si128((__m128i *) &memory[a[0] & 0x1FFFF0]); - __m128i b_x = _mm_set_epi64x(state[3] ^ state[7], state[2] ^ state[6]); - - for (i = 0; __builtin_expect(i < 0x80000, 1); i++) { - __m128i c_x = _mm_aesenc_si128(a_x, _mm_load_si128((__m128i *) a)); - c = _mm_cvtsi128_si64(c_x); - - uint64_t *restrict d_ptr = (uint64_t *) &memory[c & 0x1FFFF0]; - _mm_store_si128((__m128i *) &memory[a[0] & 0x1FFFF0], _mm_xor_si128(b_x, c_x)); - b_x = c_x; - - d[0] = d_ptr[0]; - d[1] = d_ptr[1]; - - d_ptr[1] = a[1] += _mulx_u64(c, d[0], &hi); - d_ptr[0] = a[0] += hi; - - a[0] ^= d[0]; - a[1] ^= d[1]; - - a_x = _mm_load_si128((__m128i *) &memory[a[0] & 0x1FFFF0]); - } - - memcpy(ctx->text, ctx->state.init, INIT_SIZE_BYTE); - memcpy(ExpandedKey, &ctx->state.hs.b[32], AES_KEY_SIZE); - ExpandAESKey256(ExpandedKey); - - for (i = 0; __builtin_expect(i < MEMORY, 1); i += INIT_SIZE_BYTE) { - xmminput[0] = _mm_xor_si128(longoutput[(i >> 4)], xmminput[0]); - xmminput[1] = _mm_xor_si128(longoutput[(i >> 4) + 1], xmminput[1]); - xmminput[2] = _mm_xor_si128(longoutput[(i >> 4) + 2], xmminput[2]); - xmminput[3] = _mm_xor_si128(longoutput[(i >> 4) + 3], xmminput[3]); - xmminput[4] = _mm_xor_si128(longoutput[(i >> 4) + 4], xmminput[4]); - xmminput[5] = _mm_xor_si128(longoutput[(i >> 4) + 5], xmminput[5]); - xmminput[6] = _mm_xor_si128(longoutput[(i >> 4) + 6], xmminput[6]); - xmminput[7] = _mm_xor_si128(longoutput[(i >> 4) + 7], xmminput[7]); - - for(j = 0; j < 10; j++) - { - xmminput[0] = _mm_aesenc_si128(xmminput[0], expkey[j]); - xmminput[1] = _mm_aesenc_si128(xmminput[1], expkey[j]); - xmminput[2] = _mm_aesenc_si128(xmminput[2], expkey[j]); - xmminput[3] = _mm_aesenc_si128(xmminput[3], expkey[j]); - xmminput[4] = _mm_aesenc_si128(xmminput[4], expkey[j]); - xmminput[5] = _mm_aesenc_si128(xmminput[5], expkey[j]); - xmminput[6] = _mm_aesenc_si128(xmminput[6], expkey[j]); - xmminput[7] = _mm_aesenc_si128(xmminput[7], expkey[j]); - } - - } - - memcpy(ctx->state.init, ctx->text, INIT_SIZE_BYTE); - keccakf((uint64_t *) state, 24); - extra_hashes[ctx->state.hs.b[0] & 3](&ctx->state, 200, output); -} diff --git a/algo/cryptonight/cryptonight_av5_aesni_stak.c b/algo/cryptonight/cryptonight_av2_aesni_stak.c similarity index 99% rename from algo/cryptonight/cryptonight_av5_aesni_stak.c rename to algo/cryptonight/cryptonight_av2_aesni_stak.c index 1b78abe71..67298a5b8 100644 --- a/algo/cryptonight/cryptonight_av5_aesni_stak.c +++ b/algo/cryptonight/cryptonight_av2_aesni_stak.c @@ -222,7 +222,7 @@ static inline void cn_implode_scratchpad(const __m128i* input, __m128i* output) } -void cryptonight_av5_aesni_stak(void *restrict output, const void *restrict input, char *restrict memory, struct cryptonight_ctx *restrict ctx) +void cryptonight_av2_aesni_stak(void *restrict output, const void *restrict input, char *restrict memory, struct cryptonight_ctx *restrict ctx) { keccak((const uint8_t *) input, 76, (uint8_t *) &ctx->state.hs, 200); diff --git a/algo/cryptonight/cryptonight_av3_aesni_alt.c b/algo/cryptonight/cryptonight_av3_aesni_alt.c deleted file mode 100644 index d4d33ff4e..000000000 --- a/algo/cryptonight/cryptonight_av3_aesni_alt.c +++ /dev/null @@ -1,216 +0,0 @@ -/* XMRig - * Copyright 2010 Jeff Garzik - * Copyright 2012-2014 pooler - * Copyright 2014 Lucas Jones - * Copyright 2014-2016 Wolf9466 - * Copyright 2016 Jay D Dee - * Copyright 2016-2017 XMRig - * - * - * This program is free software: you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program. If not, see . - */ - -#include -#include - -#include "cryptonight.h" -#include "crypto/c_keccak.h" - - -static inline void ExpandAESKey256_sub1(__m128i *tmp1, __m128i *tmp2) -{ - __m128i tmp4; - *tmp2 = _mm_shuffle_epi32(*tmp2, 0xFF); - tmp4 = _mm_slli_si128(*tmp1, 0x04); - *tmp1 = _mm_xor_si128(*tmp1, tmp4); - tmp4 = _mm_slli_si128(tmp4, 0x04); - *tmp1 = _mm_xor_si128(*tmp1, tmp4); - tmp4 = _mm_slli_si128(tmp4, 0x04); - *tmp1 = _mm_xor_si128(*tmp1, tmp4); - *tmp1 = _mm_xor_si128(*tmp1, *tmp2); -} - -static inline void ExpandAESKey256_sub2(__m128i *tmp1, __m128i *tmp3) -{ - __m128i tmp2, tmp4; - - tmp4 = _mm_aeskeygenassist_si128(*tmp1, 0x00); - tmp2 = _mm_shuffle_epi32(tmp4, 0xAA); - tmp4 = _mm_slli_si128(*tmp3, 0x04); - *tmp3 = _mm_xor_si128(*tmp3, tmp4); - tmp4 = _mm_slli_si128(tmp4, 0x04); - *tmp3 = _mm_xor_si128(*tmp3, tmp4); - tmp4 = _mm_slli_si128(tmp4, 0x04); - *tmp3 = _mm_xor_si128(*tmp3, tmp4); - *tmp3 = _mm_xor_si128(*tmp3, tmp2); -} - -// Special thanks to Intel for helping me -// with ExpandAESKey256() and its subroutines -static inline void ExpandAESKey256(char *keybuf) -{ - __m128i tmp1, tmp2, tmp3, *keys; - - keys = (__m128i *)keybuf; - - tmp1 = _mm_load_si128((__m128i *)keybuf); - tmp3 = _mm_load_si128((__m128i *)(keybuf+0x10)); - - tmp2 = _mm_aeskeygenassist_si128(tmp3, 0x01); - ExpandAESKey256_sub1(&tmp1, &tmp2); - keys[2] = tmp1; - ExpandAESKey256_sub2(&tmp1, &tmp3); - keys[3] = tmp3; - - tmp2 = _mm_aeskeygenassist_si128(tmp3, 0x02); - ExpandAESKey256_sub1(&tmp1, &tmp2); - keys[4] = tmp1; - ExpandAESKey256_sub2(&tmp1, &tmp3); - keys[5] = tmp3; - - tmp2 = _mm_aeskeygenassist_si128(tmp3, 0x04); - ExpandAESKey256_sub1(&tmp1, &tmp2); - keys[6] = tmp1; - ExpandAESKey256_sub2(&tmp1, &tmp3); - keys[7] = tmp3; - - tmp2 = _mm_aeskeygenassist_si128(tmp3, 0x08); - ExpandAESKey256_sub1(&tmp1, &tmp2); - keys[8] = tmp1; - ExpandAESKey256_sub2(&tmp1, &tmp3); - keys[9] = tmp3; - - tmp2 = _mm_aeskeygenassist_si128(tmp3, 0x10); - ExpandAESKey256_sub1(&tmp1, &tmp2); - keys[10] = tmp1; - ExpandAESKey256_sub2(&tmp1, &tmp3); - keys[11] = tmp3; - - tmp2 = _mm_aeskeygenassist_si128(tmp3, 0x20); - ExpandAESKey256_sub1(&tmp1, &tmp2); - keys[12] = tmp1; - ExpandAESKey256_sub2(&tmp1, &tmp3); - keys[13] = tmp3; - - tmp2 = _mm_aeskeygenassist_si128(tmp3, 0x40); - ExpandAESKey256_sub1(&tmp1, &tmp2); - keys[14] = tmp1; -} - -void cryptonight_av3_aesni_alt(void *restrict output, const void *restrict input, const char *restrict memory, struct cryptonight_ctx *restrict ctx) -{ - keccak((const uint8_t *)input, 76, (uint8_t *) &ctx->state.hs, 200); - uint8_t ExpandedKey[256]; - size_t i, j; - - memcpy(ctx->text, ctx->state.init, INIT_SIZE_BYTE); - memcpy(ExpandedKey, ctx->state.hs.b, AES_KEY_SIZE); - ExpandAESKey256(ExpandedKey); - - __m128i *longoutput, *expkey, *xmminput; - longoutput = (__m128i *) memory; - expkey = (__m128i *)ExpandedKey; - xmminput = (__m128i *)ctx->text; - - for (i = 0; __builtin_expect(i < MEMORY, 1); i += INIT_SIZE_BYTE) - { - for(j = 0; j < 10; j++) - { - xmminput[0] = _mm_aesenc_si128(xmminput[0], expkey[j]); - xmminput[1] = _mm_aesenc_si128(xmminput[1], expkey[j]); - xmminput[2] = _mm_aesenc_si128(xmminput[2], expkey[j]); - xmminput[3] = _mm_aesenc_si128(xmminput[3], expkey[j]); - xmminput[4] = _mm_aesenc_si128(xmminput[4], expkey[j]); - xmminput[5] = _mm_aesenc_si128(xmminput[5], expkey[j]); - xmminput[6] = _mm_aesenc_si128(xmminput[6], expkey[j]); - xmminput[7] = _mm_aesenc_si128(xmminput[7], expkey[j]); - } - _mm_store_si128(&(longoutput[(i >> 4)]), xmminput[0]); - _mm_store_si128(&(longoutput[(i >> 4) + 1]), xmminput[1]); - _mm_store_si128(&(longoutput[(i >> 4) + 2]), xmminput[2]); - _mm_store_si128(&(longoutput[(i >> 4) + 3]), xmminput[3]); - _mm_store_si128(&(longoutput[(i >> 4) + 4]), xmminput[4]); - _mm_store_si128(&(longoutput[(i >> 4) + 5]), xmminput[5]); - _mm_store_si128(&(longoutput[(i >> 4) + 6]), xmminput[6]); - _mm_store_si128(&(longoutput[(i >> 4) + 7]), xmminput[7]); - } - - for (i = 0; i < 2; i++) - { - ctx->a[i] = ((uint64_t *)ctx->state.k)[i] ^ ((uint64_t *)ctx->state.k)[i+4]; - ctx->b[i] = ((uint64_t *)ctx->state.k)[i+2] ^ ((uint64_t *)ctx->state.k)[i+6]; - } - - __m128i a_x = _mm_load_si128((__m128i *) &memory[ctx->a[0] & 0x1FFFF0]); - __m128i b_x = _mm_load_si128((__m128i *) ctx->b); - - uint64_t c[2] __attribute((aligned(16))); - uint64_t d[2] __attribute((aligned(16))); - - for (i = 0; __builtin_expect(i < 0x80000, 1); i++) { - __m128i c_x = _mm_aesenc_si128(a_x, _mm_load_si128((__m128i *) ctx->a)); - _mm_store_si128((__m128i *) c, c_x); - - uint64_t *restrict d_ptr = (uint64_t *) &memory[c[0] & 0x1FFFF0]; - _mm_store_si128((__m128i *) &memory[ctx->a[0] & 0x1FFFF0], _mm_xor_si128(b_x, c_x)); - b_x = c_x; - - d[0] = d_ptr[0]; - d[1] = d_ptr[1]; - - { - unsigned __int128 res = (unsigned __int128) c[0] * d[0]; - - d_ptr[0] = ctx->a[0] += res >> 64; - d_ptr[1] = ctx->a[1] += (uint64_t) res; - } - - ctx->a[0] ^= d[0]; - ctx->a[1] ^= d[1]; - - a_x = _mm_load_si128((__m128i *) &memory[ctx->a[0] & 0x1FFFF0]); - } - - memcpy(ctx->text, ctx->state.init, INIT_SIZE_BYTE); - memcpy(ExpandedKey, &ctx->state.hs.b[32], AES_KEY_SIZE); - ExpandAESKey256(ExpandedKey); - - for (i = 0; __builtin_expect(i < MEMORY, 1); i += INIT_SIZE_BYTE) { - xmminput[0] = _mm_xor_si128(longoutput[(i >> 4)], xmminput[0]); - xmminput[1] = _mm_xor_si128(longoutput[(i >> 4) + 1], xmminput[1]); - xmminput[2] = _mm_xor_si128(longoutput[(i >> 4) + 2], xmminput[2]); - xmminput[3] = _mm_xor_si128(longoutput[(i >> 4) + 3], xmminput[3]); - xmminput[4] = _mm_xor_si128(longoutput[(i >> 4) + 4], xmminput[4]); - xmminput[5] = _mm_xor_si128(longoutput[(i >> 4) + 5], xmminput[5]); - xmminput[6] = _mm_xor_si128(longoutput[(i >> 4) + 6], xmminput[6]); - xmminput[7] = _mm_xor_si128(longoutput[(i >> 4) + 7], xmminput[7]); - - for(j = 0; j < 10; j++) - { - xmminput[0] = _mm_aesenc_si128(xmminput[0], expkey[j]); - xmminput[1] = _mm_aesenc_si128(xmminput[1], expkey[j]); - xmminput[2] = _mm_aesenc_si128(xmminput[2], expkey[j]); - xmminput[3] = _mm_aesenc_si128(xmminput[3], expkey[j]); - xmminput[4] = _mm_aesenc_si128(xmminput[4], expkey[j]); - xmminput[5] = _mm_aesenc_si128(xmminput[5], expkey[j]); - xmminput[6] = _mm_aesenc_si128(xmminput[6], expkey[j]); - xmminput[7] = _mm_aesenc_si128(xmminput[7], expkey[j]); - } - - } - - memcpy(ctx->state.init, ctx->text, INIT_SIZE_BYTE); - keccakf((uint64_t *) &ctx->state.hs, 24); - extra_hashes[ctx->state.hs.b[0] & 3](&ctx->state, 200, output); -} diff --git a/algo/cryptonight/cryptonight_av6_aesni_stak_no_prefetch.c b/algo/cryptonight/cryptonight_av3_aesni_bmi2.c similarity index 97% rename from algo/cryptonight/cryptonight_av6_aesni_stak_no_prefetch.c rename to algo/cryptonight/cryptonight_av3_aesni_bmi2.c index f58031e06..a2a04bf0f 100644 --- a/algo/cryptonight/cryptonight_av6_aesni_stak_no_prefetch.c +++ b/algo/cryptonight/cryptonight_av3_aesni_bmi2.c @@ -222,14 +222,14 @@ static inline void cn_implode_scratchpad(const __m128i* input, __m128i* output) } -void cryptonight_av6_aesni_stak_no_prefetch(void *restrict output, const void *restrict input, char *restrict memory, struct cryptonight_ctx *restrict ctx) +void cryptonight_av3_aesni_bmi2(void *restrict output, const void *restrict input, char *restrict memory, struct cryptonight_ctx *restrict ctx) { keccak((const uint8_t *) input, 76, (uint8_t *) &ctx->state.hs, 200); - cn_explode_scratchpad((__m128i*) &ctx->state.hs, (__m128i*) memory); + cn_explode_scratchpad((__m128i*) &ctx->state, (__m128i*) memory); const uint8_t* l0 = memory; - uint64_t* h0 = (uint64_t*) &ctx->state.hs; + uint64_t* h0 = (uint64_t*) &ctx->state; uint64_t al0 = h0[0] ^ h0[4]; uint64_t ah0 = h0[1] ^ h0[5]; diff --git a/algo/cryptonight/cryptonight_av7_aesni_experimental.c b/algo/cryptonight/cryptonight_av5_aesni_experimental.c similarity index 99% rename from algo/cryptonight/cryptonight_av7_aesni_experimental.c rename to algo/cryptonight/cryptonight_av5_aesni_experimental.c index 99eb3df05..e474a8a31 100644 --- a/algo/cryptonight/cryptonight_av7_aesni_experimental.c +++ b/algo/cryptonight/cryptonight_av5_aesni_experimental.c @@ -213,7 +213,7 @@ static inline void cn_implode_scratchpad(const __m128i* input, __m128i* output) } -void cryptonight_av7_aesni_experimental(void *restrict output, const void *restrict input, char *restrict memory, struct cryptonight_ctx *restrict ctx) +void cryptonight_av5_aesni_experimental(void *restrict output, const void *restrict input, char *restrict memory, struct cryptonight_ctx *restrict ctx) { uint64_t* state = ctx->state.hs.w; diff --git a/algo/cryptonight/cryptonight_common.c b/algo/cryptonight/cryptonight_common.c index babe66d91..78228d505 100644 --- a/algo/cryptonight/cryptonight_common.c +++ b/algo/cryptonight/cryptonight_common.c @@ -38,11 +38,10 @@ #if defined(__x86_64__) void cryptonight_av1_aesni(void* output, const void* input, const char *memory, struct cryptonight_ctx* ctx); - void cryptonight_av2_aesni_bmi2(void* output, const void* input, const char *memory, struct cryptonight_ctx* ctx); - void cryptonight_av3_aesni_alt(void* output, const void* input, const char *memory, struct cryptonight_ctx* ctx); - void cryptonight_av5_aesni_stak(void* output, const void* input, const char *memory, struct cryptonight_ctx* ctx); - void cryptonight_av6_aesni_stak_no_prefetch(void* output, const void* input, const char *memory, struct cryptonight_ctx* ctx); - void cryptonight_av7_aesni_experimental(void* output, const void* input, const char *memory, struct cryptonight_ctx* ctx); + void cryptonight_av2_aesni_stak(void* output, const void* input, const char *memory, struct cryptonight_ctx* ctx); + void cryptonight_av3_aesni_bmi2(void* output, const void* input, const char *memory, struct cryptonight_ctx* ctx); + void cryptonight_av4_softaes(void* output, const void* input, const char *memory, struct cryptonight_ctx* ctx); + void cryptonight_av5_aesni_experimental(void* output, const void* input, const char *memory, struct cryptonight_ctx* ctx); #elif defined(__i386__) void cryptonight_av1_aesni32(void* output, const void* input, const char *memory, struct cryptonight_ctx* ctx); #endif @@ -60,24 +59,16 @@ void cryptonight_init(int variant) cryptonight_hash_ctx = cryptonight_av1_aesni; break; - case XMR_AV2_AESNI_BMI2: - cryptonight_hash_ctx = cryptonight_av2_aesni_bmi2; + case XMR_AV2_STAK: + cryptonight_hash_ctx = cryptonight_av2_aesni_stak; break; - case XMR_AV3_AESNI_ALT: - cryptonight_hash_ctx = cryptonight_av3_aesni_alt; + case XMR_AV3_AESNI_BMI2: + cryptonight_hash_ctx = cryptonight_av3_aesni_bmi2; break; - case XMR_AV5_STAK: - cryptonight_hash_ctx = cryptonight_av5_aesni_stak; - break; - - case XMR_AV6_STAK_NO_PREFETCH: - cryptonight_hash_ctx = cryptonight_av6_aesni_stak_no_prefetch; - break; - - case XMR_AV7_EXPERIMENTAL: - cryptonight_hash_ctx = cryptonight_av7_aesni_experimental; + case XMR_AV5_EXPERIMENTAL: + cryptonight_hash_ctx = cryptonight_av5_aesni_experimental; break; #elif defined(__i386__) diff --git a/options.h b/options.h index fe27cc2d7..22d6d5959 100644 --- a/options.h +++ b/options.h @@ -35,12 +35,10 @@ enum xmr_algo_variant { XMR_AV0_AUTO, XMR_AV1_AESNI, - XMR_AV2_AESNI_BMI2, - XMR_AV3_AESNI_ALT, + XMR_AV2_STAK, + XMR_AV3_AESNI_BMI2, XMR_AV4_SOFT_AES, - XMR_AV5_STAK, - XMR_AV6_STAK_NO_PREFETCH, - XMR_AV7_EXPERIMENTAL, + XMR_AV5_EXPERIMENTAL, XMR_AV_MAX }; diff --git a/test/cryptonight/CMakeLists.txt b/test/cryptonight/CMakeLists.txt index 7cd314015..f15ca5fdb 100644 --- a/test/cryptonight/CMakeLists.txt +++ b/test/cryptonight/CMakeLists.txt @@ -16,13 +16,11 @@ if (CMAKE_SIZEOF_VOID_P EQUAL 8) add_executable(cryptonight_app ${SOURCES} cryptonight.c ../../algo/cryptonight/cryptonight_av1_aesni.c - ../../algo/cryptonight/cryptonight_av3_aesni_alt.c - ../../algo/cryptonight/cryptonight_av5_aesni_stak.c - ../../algo/cryptonight/cryptonight_av6_aesni_stak_no_prefetch.c - ../../algo/cryptonight/cryptonight_av7_aesni_experimental.c + ../../algo/cryptonight/cryptonight_av2_aesni_stak.c + ../../algo/cryptonight/cryptonight_av5_aesni_experimental.c ) - target_link_libraries(cryptonight_app unity cryptonight_av2_aesni_bmi2) + target_link_libraries(cryptonight_app unity cryptonight_av3_aesni_bmi2) else() add_executable(cryptonight_app ${SOURCES} cryptonight32.c diff --git a/test/cryptonight/bmi2/CMakeLists.txt b/test/cryptonight/bmi2/CMakeLists.txt index bfabb5564..785709a9f 100644 --- a/test/cryptonight/bmi2/CMakeLists.txt +++ b/test/cryptonight/bmi2/CMakeLists.txt @@ -1,3 +1,3 @@ set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -maes -mbmi2") include_directories(../../..) -add_library(cryptonight_av2_aesni_bmi2 STATIC ../../../algo/cryptonight/cryptonight_av2_aesni_bmi2.c) +add_library(cryptonight_av3_aesni_bmi2 STATIC ../../../algo/cryptonight/cryptonight_av3_aesni_bmi2.c) diff --git a/test/cryptonight/cryptonight.c b/test/cryptonight/cryptonight.c index eca192668..c059f798c 100644 --- a/test/cryptonight/cryptonight.c +++ b/test/cryptonight/cryptonight.c @@ -5,12 +5,10 @@ void cryptonight_av1_aesni(void* output, const void* input, const char *memory, struct cryptonight_ctx* ctx); -void cryptonight_av2_aesni_bmi2(void* output, const void* input, const char *memory, struct cryptonight_ctx* ctx); -void cryptonight_av3_aesni_alt(void* output, const void* input, const char *memory, struct cryptonight_ctx* ctx); +void cryptonight_av2_aesni_stak(void* output, const void* input, const char *memory, struct cryptonight_ctx* ctx); +void cryptonight_av3_aesni_bmi2(void* output, const void* input, const char *memory, struct cryptonight_ctx* ctx); void cryptonight_av4_softaes(void* output, const void* input, const char *memory, struct cryptonight_ctx* ctx); -void cryptonight_av5_aesni_stak(void* output, const void* input, const char *memory, struct cryptonight_ctx* ctx); -void cryptonight_av6_aesni_stak_no_prefetch(void* output, const void* input, const char *memory, struct cryptonight_ctx* ctx); -void cryptonight_av7_aesni_experimental(void* output, const void* input, const char *memory, struct cryptonight_ctx* ctx); +void cryptonight_av5_aesni_experimental(void* output, const void* input, const char *memory, struct cryptonight_ctx* ctx); char hash[32]; @@ -77,7 +75,7 @@ void test_cryptonight_av2_should_CalcHash(void) uint8_t *memory = (uint8_t *) malloc(MEMORY); struct cryptonight_ctx *ctx = (struct cryptonight_ctx*)malloc(sizeof(struct cryptonight_ctx)); - cryptonight_av2_aesni_bmi2(&hash, data, memory, ctx); + cryptonight_av2_aesni_stak(&hash, data, memory, ctx); free(memory); free(ctx); @@ -91,7 +89,7 @@ void test_cryptonight_av3_should_CalcHash(void) uint8_t *memory = (uint8_t *) malloc(MEMORY); struct cryptonight_ctx *ctx = (struct cryptonight_ctx*) malloc(sizeof(struct cryptonight_ctx)); - cryptonight_av3_aesni_alt(&hash, data, memory, ctx); + cryptonight_av3_aesni_bmi2(&hash, data, memory, ctx); free(memory); free(ctx); @@ -119,35 +117,7 @@ void test_cryptonight_av5_should_CalcHash(void) uint8_t *memory = (uint8_t *) malloc(MEMORY); struct cryptonight_ctx *ctx = (struct cryptonight_ctx*)malloc(sizeof(struct cryptonight_ctx)); - cryptonight_av5_aesni_stak(&hash, data, memory, ctx); - - free(memory); - free(ctx); - - TEST_ASSERT_EQUAL_STRING(RESULT, bin2hex(hash, 32)); -} - - -void test_cryptonight_av6_should_CalcHash(void) -{ - uint8_t *memory = (uint8_t *) malloc(MEMORY); - struct cryptonight_ctx *ctx = (struct cryptonight_ctx*)malloc(sizeof(struct cryptonight_ctx)); - - cryptonight_av6_aesni_stak_no_prefetch(&hash, data, memory, ctx); - - free(memory); - free(ctx); - - TEST_ASSERT_EQUAL_STRING(RESULT, bin2hex(hash, 32)); -} - - -void test_cryptonight_av7_should_CalcHash(void) -{ - uint8_t *memory = (uint8_t *) malloc(MEMORY); - struct cryptonight_ctx *ctx = (struct cryptonight_ctx*)malloc(sizeof(struct cryptonight_ctx)); - - cryptonight_av7_aesni_experimental(&hash, data, memory, ctx); + cryptonight_av5_aesni_experimental(&hash, data, memory, ctx); free(memory); free(ctx); @@ -167,8 +137,6 @@ int main(void) RUN_TEST(test_cryptonight_av3_should_CalcHash); RUN_TEST(test_cryptonight_av4_should_CalcHash); RUN_TEST(test_cryptonight_av5_should_CalcHash); - RUN_TEST(test_cryptonight_av6_should_CalcHash); - RUN_TEST(test_cryptonight_av7_should_CalcHash); return UNITY_END(); }