#include #include #include #include #include "crypto/cn/CnHash.h" #include "backend/cpu/Cpu.h" extern "C" { #include "../randomx/panthera/sysendian.h" #include "../ghostrider/sph_blake.h" #include "../ghostrider/sph_bmw.h" #include "../ghostrider/sph_groestl.h" #include "../ghostrider/sph_jh.h" #include "../ghostrider/sph_keccak.h" #include "../ghostrider/sph_skein.h" #include "../ghostrider/sph_luffa.h" #include "../ghostrider/sph_cubehash.h" #include "../ghostrider/sph_shavite.h" #include "../ghostrider/sph_simd.h" #include "../ghostrider/sph_echo.h" #include "../ghostrider/sph_hamsi.h" #include "../ghostrider/sph_fugue.h" #include "../ghostrider/sph_shabal.h" #include "../ghostrider/sph_whirlpool.h" #include "../ghostrider/sph_sha2.h" } #include using namespace xmrig; enum Algo { BLAKE = 0, BMW, GROESTL, KECCAK, SKEIN, LUFFA, CUBEHASH, SHAVITE, SIMD, ECHO, HAMSI, FUGUE, SHABAL, WHIRLPOOL, HASH_FUNC_COUNT }; enum CNAlgo { CNDark = 0, CNDarklite, CNFast, CNLite, CNTurtle, CNTurtlelite, CN_HASH_FUNC_COUNT }; static void selectAlgo(unsigned char nibble, bool* selectedAlgos, uint8_t* selectedIndex, int algoCount, int* currentCount) { uint8_t algoDigit = (nibble & 0x0F) % algoCount; if(!selectedAlgos[algoDigit]) { selectedAlgos[algoDigit] = true; selectedIndex[currentCount[0]] = algoDigit; currentCount[0] = currentCount[0] + 1; } algoDigit = (nibble >> 4) % algoCount; if(!selectedAlgos[algoDigit]) { selectedAlgos[algoDigit] = true; selectedIndex[currentCount[0]] = algoDigit; currentCount[0] = currentCount[0] + 1; } } static void getAlgoString(void *mem, unsigned int size, uint8_t* selectedAlgoOutput, int algoCount) { unsigned char *p = (unsigned char *)mem; unsigned int len = size/2; bool* selectedAlgo = new bool[algoCount]; for(int z=0; z < algoCount; z++) { selectedAlgo[z] = false; } int selectedCount = 0; for (unsigned int i=0;ilo; lo++, hi--) { char tmp=p[lo]; p[lo] = p[hi]; p[hi] = tmp; } } void flex_hash(const char* input, char* output, cryptonight_ctx** ctx) { uint32_t hash[64/4]; sph_blake512_context ctx_blake; sph_bmw512_context ctx_bmw; sph_groestl512_context ctx_groestl; sph_keccak512_context ctx_keccak; sph_skein512_context ctx_skein; sph_luffa512_context ctx_luffa; sph_cubehash512_context ctx_cubehash; sph_shavite512_context ctx_shavite; sph_simd512_context ctx_simd; sph_echo512_context ctx_echo; sph_hamsi512_context ctx_hamsi; sph_fugue512_context ctx_fugue; sph_shabal512_context ctx_shabal; sph_whirlpool_context ctx_whirlpool; void *in = (void*) input; int size = 80; sph_keccak512_init(&ctx_keccak); sph_keccak512(&ctx_keccak, in, size); sph_keccak512_close(&ctx_keccak, hash); uint8_t selectedAlgoOutput[15] = {0}; uint8_t selectedCNAlgoOutput[14] = {0}; getAlgoString(&hash, 64, selectedAlgoOutput, 14); getAlgoString(&hash, 64, selectedCNAlgoOutput, 6); //printf("previous hash="); //print_hex_memory(&input[4], 64); const CnHash::AlgoVariant av = Cpu::info()->hasAES() ? CnHash::AV_SINGLE : CnHash::AV_SINGLE_SOFT; int i; for (i = 0; i < 18; i++) { uint8_t algo; uint8_t cnAlgo; int coreSelection; int cnSelection = -1; if(i < 5) { coreSelection = i; } else if(i < 11) { coreSelection = i-1; } else { coreSelection = i-2; } if(i==5) { coreSelection = -1; cnSelection = 0; } if(i==11) { coreSelection = -1; cnSelection = 1; } if(i==17) { coreSelection = -1; cnSelection = 2; } if(coreSelection >= 0) { algo = selectedAlgoOutput[(uint8_t)coreSelection]; } else { algo = 16; // skip core hashing for this loop iteration } if(cnSelection >=0) { cnAlgo = selectedCNAlgoOutput[(uint8_t)cnSelection]; } else { cnAlgo = 14; // skip cn hashing for this loop iteration } //selection cnAlgo. if a CN algo is selected then core algo will not be selected cn_hash_fun f; switch(cnAlgo) { case CNDark: //cryptonightdark_hash((const char*)in, (char*)hash, size, 1); f = CnHash::fn(Algorithm::CN_GR_0, av, Assembly::AUTO); break; case CNDarklite: //cryptonightdarklite_hash((const char*)in, (char*)hash, size, 1); f = CnHash::fn(Algorithm::CN_GR_1, av, Assembly::AUTO); break; case CNFast: //cryptonightfast_hash((const char*)in, (char*)hash, size, 1); f = CnHash::fn(Algorithm::CN_GR_2, av, Assembly::AUTO); break; case CNLite: //cryptonightlite_hash((const char*)in, (char*)hash, size, 1); f = CnHash::fn(Algorithm::CN_GR_3, av, Assembly::AUTO); break; case CNTurtle: //cryptonightturtle_hash((const char*)in, (char*)hash, size, 1); f = CnHash::fn(Algorithm::CN_GR_4, av, Assembly::AUTO); break; case CNTurtlelite: //cryptonightturtlelite_hash((const char*)in, (char*)hash, size, 1); f = CnHash::fn(Algorithm::CN_GR_5, av, Assembly::AUTO); break; default: f = nullptr; } if (f) f((const uint8_t*)in, size, (uint8_t*)hash, ctx, 101); //selection core algo switch (algo) { case BLAKE: sph_blake512_init(&ctx_blake); sph_blake512(&ctx_blake, in, size); sph_blake512_close(&ctx_blake, hash); break; case BMW: sph_bmw512_init(&ctx_bmw); sph_bmw512(&ctx_bmw, in, size); sph_bmw512_close(&ctx_bmw, hash); break; case GROESTL: sph_groestl512_init(&ctx_groestl); sph_groestl512(&ctx_groestl, in, size); sph_groestl512_close(&ctx_groestl, hash); break; case KECCAK: sph_keccak512_init(&ctx_keccak); sph_keccak512(&ctx_keccak, in, size); sph_keccak512_close(&ctx_keccak, hash); break; case SKEIN: sph_skein512_init(&ctx_skein); sph_skein512(&ctx_skein, in, size); sph_skein512_close(&ctx_skein, hash); break; case LUFFA: sph_luffa512_init(&ctx_luffa); sph_luffa512(&ctx_luffa, in, size); sph_luffa512_close(&ctx_luffa, hash); break; case CUBEHASH: sph_cubehash512_init(&ctx_cubehash); sph_cubehash512(&ctx_cubehash, in, size); sph_cubehash512_close(&ctx_cubehash, hash); break; case SHAVITE: sph_shavite512_init(&ctx_shavite); sph_shavite512(&ctx_shavite, in, size); sph_shavite512_close(&ctx_shavite, hash); break; case SIMD: sph_simd512_init(&ctx_simd); sph_simd512(&ctx_simd, in, size); sph_simd512_close(&ctx_simd, hash); break; case ECHO: sph_echo512_init(&ctx_echo); sph_echo512(&ctx_echo, in, size); sph_echo512_close(&ctx_echo, hash); break; case HAMSI: sph_hamsi512_init(&ctx_hamsi); sph_hamsi512(&ctx_hamsi, in, size); sph_hamsi512_close(&ctx_hamsi, hash); break; case FUGUE: sph_fugue512_init(&ctx_fugue); sph_fugue512(&ctx_fugue, in, size); sph_fugue512_close(&ctx_fugue, hash); break; case SHABAL: sph_shabal512_init(&ctx_shabal); sph_shabal512(&ctx_shabal, in, size); sph_shabal512_close(&ctx_shabal, hash); break; case WHIRLPOOL: sph_whirlpool_init(&ctx_whirlpool); sph_whirlpool(&ctx_whirlpool, in, size); sph_whirlpool_close(&ctx_whirlpool, hash); break; } in = (void*) hash; size = 64; } sph_keccak256_init(&ctx_keccak); sph_keccak256(&ctx_keccak, in, size); sph_keccak256_close(&ctx_keccak, hash); memcpy(output, hash, 32); }