|
| 1 | +#include "miner.h" |
| 2 | + |
| 3 | +#include <stdio.h> |
| 4 | +#include <stdlib.h> |
| 5 | +#include <string.h> |
| 6 | + |
| 7 | +#include <sha3/sph_blake.h> |
| 8 | +#include <sha3/sph_bmw.h> |
| 9 | +#include <sha3/sph_groestl.h> |
| 10 | +#include <sha3/sph_jh.h> |
| 11 | +#include <sha3/sph_keccak.h> |
| 12 | +#include <sha3/sph_skein.h> |
| 13 | +#include <sha3/sph_luffa.h> |
| 14 | +#include <sha3/sph_cubehash.h> |
| 15 | +#include <sha3/sph_shavite.h> |
| 16 | +#include <sha3/sph_simd.h> |
| 17 | +#include <sha3/sph_echo.h> |
| 18 | +#include <sha3/sph_hamsi.h> |
| 19 | +#include <sha3/sph_fugue.h> |
| 20 | +#include <sha3/sph_shabal.h> |
| 21 | +#include <sha3/sph_whirlpool.h> |
| 22 | +#include <sha3/sph_sha2.h> |
| 23 | +#include <sha3/sph_haval.h> |
| 24 | +#include <sha3/sph_radiogatun.h> |
| 25 | +#include <sha3/sph_panama.h> |
| 26 | +#include <sha3/gost_streebog.h> |
| 27 | + |
| 28 | +enum Algo { |
| 29 | + BLAKE = 0, |
| 30 | + BMW, |
| 31 | + GROESTL, |
| 32 | + JH, |
| 33 | + KECCAK, |
| 34 | + SKEIN, |
| 35 | + LUFFA, |
| 36 | + CUBEHASH, |
| 37 | + SHAVITE, |
| 38 | + SIMD, |
| 39 | + ECHO, |
| 40 | + HAMSI, |
| 41 | + FUGUE, |
| 42 | + SHABAL, |
| 43 | + WHIRLPOOL, |
| 44 | + SHA512, |
| 45 | + HAVAL, |
| 46 | + GOST, |
| 47 | + RADIOGATUN, |
| 48 | + PANAMA, |
| 49 | + HASH_FUNC_COUNT |
| 50 | +}; |
| 51 | + |
| 52 | +static __thread uint32_t s_ntime = UINT32_MAX; |
| 53 | +static __thread char hashOrder[HASH_FUNC_COUNT + 1] = { 0 }; |
| 54 | + |
| 55 | +static void getAlgoString(const uint8_t* prevblock, char *output) |
| 56 | +{ |
| 57 | + char *sptr = output; |
| 58 | + |
| 59 | + for (int j = 0; j < HASH_FUNC_COUNT; j++) { |
| 60 | + char b = (19 - j) >> 1; // 16 ascii hex chars, reversed |
| 61 | + uint8_t algoDigit = (j & 1) ? prevblock[b] & 0xF : prevblock[b] >> 4; |
| 62 | + if (algoDigit >= 10) |
| 63 | + sprintf(sptr, "%c", 'A' + (algoDigit - 10)); |
| 64 | + else |
| 65 | + sprintf(sptr, "%u", (uint32_t) algoDigit); |
| 66 | + sptr++; |
| 67 | + } |
| 68 | + *sptr = '\0'; |
| 69 | +} |
| 70 | + |
| 71 | +void x20r_hash(void* output, const void* input) |
| 72 | +{ |
| 73 | + uint32_t _ALIGN(128) hash[64/4]; |
| 74 | + |
| 75 | + sph_blake512_context ctx_blake; |
| 76 | + sph_bmw512_context ctx_bmw; |
| 77 | + sph_groestl512_context ctx_groestl; |
| 78 | + sph_skein512_context ctx_skein; |
| 79 | + sph_jh512_context ctx_jh; |
| 80 | + sph_keccak512_context ctx_keccak; |
| 81 | + sph_luffa512_context ctx_luffa; |
| 82 | + sph_cubehash512_context ctx_cubehash; |
| 83 | + sph_shavite512_context ctx_shavite; |
| 84 | + sph_simd512_context ctx_simd; |
| 85 | + sph_echo512_context ctx_echo; |
| 86 | + sph_hamsi512_context ctx_hamsi; |
| 87 | + sph_fugue512_context ctx_fugue; |
| 88 | + sph_shabal512_context ctx_shabal; |
| 89 | + sph_whirlpool_context ctx_whirlpool; |
| 90 | + sph_sha512_context ctx_sha512; |
| 91 | + sph_haval256_5_context ctx_haval; |
| 92 | + sph_gost512_context ctx_gost; |
| 93 | + sph_radiogatun64_context ctx_radiogatun; |
| 94 | + sph_panama_context ctx_panama; |
| 95 | + |
| 96 | + void *in = (void*) input; |
| 97 | + int size = 80; |
| 98 | + |
| 99 | + if (s_ntime == UINT32_MAX) { |
| 100 | + const uint8_t* in8 = (uint8_t*) input; |
| 101 | + getAlgoString(&in8[4], hashOrder); |
| 102 | + } |
| 103 | + |
| 104 | + for (int i = 0; i < 20; i++) |
| 105 | + { |
| 106 | + const char elem = hashOrder[i]; |
| 107 | + const uint8_t algo = elem >= 'A' ? elem - 'A' + 10 : elem - '0'; |
| 108 | + |
| 109 | + switch (algo) { |
| 110 | + case BLAKE: |
| 111 | + sph_blake512_init(&ctx_blake); |
| 112 | + sph_blake512(&ctx_blake, in, size); |
| 113 | + sph_blake512_close(&ctx_blake, hash); |
| 114 | + break; |
| 115 | + case BMW: |
| 116 | + sph_bmw512_init(&ctx_bmw); |
| 117 | + sph_bmw512(&ctx_bmw, in, size); |
| 118 | + sph_bmw512_close(&ctx_bmw, hash); |
| 119 | + break; |
| 120 | + case GROESTL: |
| 121 | + sph_groestl512_init(&ctx_groestl); |
| 122 | + sph_groestl512(&ctx_groestl, in, size); |
| 123 | + sph_groestl512_close(&ctx_groestl, hash); |
| 124 | + break; |
| 125 | + case SKEIN: |
| 126 | + sph_skein512_init(&ctx_skein); |
| 127 | + sph_skein512(&ctx_skein, in, size); |
| 128 | + sph_skein512_close(&ctx_skein, hash); |
| 129 | + break; |
| 130 | + case JH: |
| 131 | + sph_jh512_init(&ctx_jh); |
| 132 | + sph_jh512(&ctx_jh, in, size); |
| 133 | + sph_jh512_close(&ctx_jh, hash); |
| 134 | + break; |
| 135 | + case KECCAK: |
| 136 | + sph_keccak512_init(&ctx_keccak); |
| 137 | + sph_keccak512(&ctx_keccak, in, size); |
| 138 | + sph_keccak512_close(&ctx_keccak, hash); |
| 139 | + break; |
| 140 | + case LUFFA: |
| 141 | + sph_luffa512_init(&ctx_luffa); |
| 142 | + sph_luffa512(&ctx_luffa, in, size); |
| 143 | + sph_luffa512_close(&ctx_luffa, hash); |
| 144 | + break; |
| 145 | + case CUBEHASH: |
| 146 | + sph_cubehash512_init(&ctx_cubehash); |
| 147 | + sph_cubehash512(&ctx_cubehash, in, size); |
| 148 | + sph_cubehash512_close(&ctx_cubehash, hash); |
| 149 | + break; |
| 150 | + case SHAVITE: |
| 151 | + sph_shavite512_init(&ctx_shavite); |
| 152 | + sph_shavite512(&ctx_shavite, in, size); |
| 153 | + sph_shavite512_close(&ctx_shavite, hash); |
| 154 | + break; |
| 155 | + case SIMD: |
| 156 | + sph_simd512_init(&ctx_simd); |
| 157 | + sph_simd512(&ctx_simd, in, size); |
| 158 | + sph_simd512_close(&ctx_simd, hash); |
| 159 | + break; |
| 160 | + case ECHO: |
| 161 | + sph_echo512_init(&ctx_echo); |
| 162 | + sph_echo512(&ctx_echo, in, size); |
| 163 | + sph_echo512_close(&ctx_echo, hash); |
| 164 | + break; |
| 165 | + case HAMSI: |
| 166 | + sph_hamsi512_init(&ctx_hamsi); |
| 167 | + sph_hamsi512(&ctx_hamsi, in, size); |
| 168 | + sph_hamsi512_close(&ctx_hamsi, hash); |
| 169 | + break; |
| 170 | + case FUGUE: |
| 171 | + sph_fugue512_init(&ctx_fugue); |
| 172 | + sph_fugue512(&ctx_fugue, in, size); |
| 173 | + sph_fugue512_close(&ctx_fugue, hash); |
| 174 | + break; |
| 175 | + case SHABAL: |
| 176 | + sph_shabal512_init(&ctx_shabal); |
| 177 | + sph_shabal512(&ctx_shabal, in, size); |
| 178 | + sph_shabal512_close(&ctx_shabal, hash); |
| 179 | + break; |
| 180 | + case WHIRLPOOL: |
| 181 | + sph_whirlpool_init(&ctx_whirlpool); |
| 182 | + sph_whirlpool(&ctx_whirlpool, in, size); |
| 183 | + sph_whirlpool_close(&ctx_whirlpool, hash); |
| 184 | + break; |
| 185 | + case SHA512: |
| 186 | + sph_sha512_init(&ctx_sha512); |
| 187 | + sph_sha512(&ctx_sha512,(const void*) in, size); |
| 188 | + sph_sha512_close(&ctx_sha512,(void*) hash); |
| 189 | + break; |
| 190 | + case HAVAL: |
| 191 | + sph_haval256_5_init(&ctx_haval); |
| 192 | + sph_haval256_5(&ctx_haval, in, size); |
| 193 | + sph_haval256_5_close(&ctx_haval, hash); |
| 194 | + break; |
| 195 | + case GOST: |
| 196 | + sph_gost512_init(&ctx_gost); |
| 197 | + sph_gost512(&ctx_gost, in, size); |
| 198 | + sph_gost512_close(&ctx_gost, hash); |
| 199 | + break; |
| 200 | + case RADIOGATUN: |
| 201 | + sph_radiogatun64_init(&ctx_radiogatun); |
| 202 | + sph_radiogatun64(&ctx_radiogatun, in, size); |
| 203 | + sph_radiogatun64_close(&ctx_radiogatun, hash); |
| 204 | + break; |
| 205 | + case PANAMA: |
| 206 | + sph_panama_init(&ctx_panama); |
| 207 | + sph_panama(&ctx_panama, in, size); |
| 208 | + sph_panama_close(&ctx_panama, hash); |
| 209 | + break; |
| 210 | + } |
| 211 | + in = (void*) hash; |
| 212 | + size = 64; |
| 213 | + } |
| 214 | + memcpy(output, hash, 32); |
| 215 | +} |
| 216 | + |
| 217 | +int scanhash_x20r(int thr_id, struct work *work, uint32_t max_nonce, uint64_t *hashes_done) |
| 218 | +{ |
| 219 | + uint32_t _ALIGN(128) hash32[8]; |
| 220 | + uint32_t _ALIGN(128) endiandata[20]; |
| 221 | + uint32_t *pdata = work->data; |
| 222 | + uint32_t *ptarget = work->target; |
| 223 | + const uint32_t Htarg = ptarget[7]; |
| 224 | + const uint32_t first_nonce = pdata[19]; |
| 225 | + uint32_t nonce = first_nonce; |
| 226 | + volatile uint8_t *restart = &(work_restart[thr_id].restart); |
| 227 | + |
| 228 | + for (int k=0; k < 19; k++) |
| 229 | + be32enc(&endiandata[k], pdata[k]); |
| 230 | + |
| 231 | + if (s_ntime != pdata[17]) { |
| 232 | + uint32_t ntime = swab32(pdata[17]); |
| 233 | + getAlgoString((const char*) (&endiandata[1]), hashOrder); |
| 234 | + s_ntime = ntime; |
| 235 | + if (opt_debug && !thr_id) applog(LOG_DEBUG, "hash order %s (%08x)", hashOrder, ntime); |
| 236 | + } |
| 237 | + |
| 238 | + if (opt_benchmark) |
| 239 | + ptarget[7] = 0x0cff; |
| 240 | + |
| 241 | + do { |
| 242 | + be32enc(&endiandata[19], nonce); |
| 243 | + x20r_hash(hash32, endiandata); |
| 244 | + |
| 245 | + if (hash32[7] <= Htarg && fulltest(hash32, ptarget)) { |
| 246 | + work_set_target_ratio(work, hash32); |
| 247 | + pdata[19] = nonce; |
| 248 | + *hashes_done = pdata[19] - first_nonce; |
| 249 | + return 1; |
| 250 | + } |
| 251 | + nonce++; |
| 252 | + |
| 253 | + } while (nonce < max_nonce && !(*restart)); |
| 254 | + |
| 255 | + pdata[19] = nonce; |
| 256 | + *hashes_done = pdata[19] - first_nonce + 1; |
| 257 | + return 0; |
| 258 | +} |
0 commit comments