2 * x16s algo implementation
4 * Implementation by tpruvot@github Jan 2018
12 #include <sha3/sph_blake.h>
13 #include <sha3/sph_bmw.h>
14 #include <sha3/sph_groestl.h>
15 #include <sha3/sph_jh.h>
16 #include <sha3/sph_keccak.h>
17 #include <sha3/sph_skein.h>
18 #include <sha3/sph_luffa.h>
19 #include <sha3/sph_cubehash.h>
20 #include <sha3/sph_shavite.h>
21 #include <sha3/sph_simd.h>
22 #include <sha3/sph_echo.h>
23 #include <sha3/sph_hamsi.h>
24 #include <sha3/sph_fugue.h>
25 #include <sha3/sph_shabal.h>
26 #include <sha3/sph_whirlpool.h>
27 #include <sha3/sph_sha2.h>
49 static __thread uint32_t s_ntime = UINT32_MAX;
50 static __thread char hashOrder[HASH_FUNC_COUNT + 1] = { 0 };
53 static void getAlgoString(const uint8_t* prevblock, char *output)
55 uint8_t* data = (uint8_t*)prevblock;
57 strcpy(output, "0123456789ABCDEF");
59 for(int i = 0; i < 16; i++){
60 uint8_t b = (15 - i) >> 1; // 16 ascii hex chars, reversed
61 uint8_t algoDigit = (i & 1) ? data[b] & 0xF : data[b] >> 4;
62 int offset = algoDigit;
63 // insert the nth character at the front
64 char oldVal = output[offset];
65 for(int j=offset; j-->0;){
66 output[j+1] = output[j];
72 void x16s_hash(void* output, const void* input)
74 uint32_t _ALIGN(128) hash[64/4];
76 sph_blake512_context ctx_blake;
77 sph_bmw512_context ctx_bmw;
78 sph_groestl512_context ctx_groestl;
79 sph_skein512_context ctx_skein;
80 sph_jh512_context ctx_jh;
81 sph_keccak512_context ctx_keccak;
82 sph_luffa512_context ctx_luffa1;
83 sph_cubehash512_context ctx_cubehash1;
84 sph_shavite512_context ctx_shavite1;
85 sph_simd512_context ctx_simd1;
86 sph_echo512_context ctx_echo1;
87 sph_hamsi512_context ctx_hamsi1;
88 sph_fugue512_context ctx_fugue1;
89 sph_shabal512_context ctx_shabal1;
90 sph_whirlpool_context ctx_whirlpool1;
91 sph_sha512_context ctx_sha512;
93 void *in = (void*) input;
96 if (s_ntime == UINT32_MAX) {
97 const uint8_t* in8 = (uint8_t*) input;
98 getAlgoString(&in8[4], hashOrder);
101 for (int i = 0; i < 16; i++)
103 const char elem = hashOrder[i];
104 const uint8_t algo = elem >= 'A' ? elem - 'A' + 10 : elem - '0';
108 sph_blake512_init(&ctx_blake);
109 sph_blake512(&ctx_blake, in, size);
110 sph_blake512_close(&ctx_blake, hash);
113 sph_bmw512_init(&ctx_bmw);
114 sph_bmw512(&ctx_bmw, in, size);
115 sph_bmw512_close(&ctx_bmw, hash);
118 sph_groestl512_init(&ctx_groestl);
119 sph_groestl512(&ctx_groestl, in, size);
120 sph_groestl512_close(&ctx_groestl, hash);
123 sph_skein512_init(&ctx_skein);
124 sph_skein512(&ctx_skein, in, size);
125 sph_skein512_close(&ctx_skein, hash);
128 sph_jh512_init(&ctx_jh);
129 sph_jh512(&ctx_jh, in, size);
130 sph_jh512_close(&ctx_jh, hash);
133 sph_keccak512_init(&ctx_keccak);
134 sph_keccak512(&ctx_keccak, in, size);
135 sph_keccak512_close(&ctx_keccak, hash);
138 sph_luffa512_init(&ctx_luffa1);
139 sph_luffa512(&ctx_luffa1, in, size);
140 sph_luffa512_close(&ctx_luffa1, hash);
143 sph_cubehash512_init(&ctx_cubehash1);
144 sph_cubehash512(&ctx_cubehash1, in, size);
145 sph_cubehash512_close(&ctx_cubehash1, hash);
148 sph_shavite512_init(&ctx_shavite1);
149 sph_shavite512(&ctx_shavite1, in, size);
150 sph_shavite512_close(&ctx_shavite1, hash);
153 sph_simd512_init(&ctx_simd1);
154 sph_simd512(&ctx_simd1, in, size);
155 sph_simd512_close(&ctx_simd1, hash);
158 sph_echo512_init(&ctx_echo1);
159 sph_echo512(&ctx_echo1, in, size);
160 sph_echo512_close(&ctx_echo1, hash);
163 sph_hamsi512_init(&ctx_hamsi1);
164 sph_hamsi512(&ctx_hamsi1, in, size);
165 sph_hamsi512_close(&ctx_hamsi1, hash);
168 sph_fugue512_init(&ctx_fugue1);
169 sph_fugue512(&ctx_fugue1, in, size);
170 sph_fugue512_close(&ctx_fugue1, hash);
173 sph_shabal512_init(&ctx_shabal1);
174 sph_shabal512(&ctx_shabal1, in, size);
175 sph_shabal512_close(&ctx_shabal1, hash);
178 sph_whirlpool_init(&ctx_whirlpool1);
179 sph_whirlpool(&ctx_whirlpool1, in, size);
180 sph_whirlpool_close(&ctx_whirlpool1, hash);
183 sph_sha512_init(&ctx_sha512);
184 sph_sha512(&ctx_sha512,(const void*) in, size);
185 sph_sha512_close(&ctx_sha512,(void*) hash);
191 memcpy(output, hash, 32);
194 int scanhash_x16s(int thr_id, struct work *work, uint32_t max_nonce, uint64_t *hashes_done)
196 uint32_t _ALIGN(128) hash32[8];
197 uint32_t _ALIGN(128) endiandata[20];
198 uint32_t *pdata = work->data;
199 uint32_t *ptarget = work->target;
200 const uint32_t Htarg = ptarget[7];
201 const uint32_t first_nonce = pdata[19];
202 uint32_t nonce = first_nonce;
203 volatile uint8_t *restart = &(work_restart[thr_id].restart);
205 for (int k=0; k < 19; k++)
206 be32enc(&endiandata[k], pdata[k]);
208 if (s_ntime != pdata[17]) {
209 uint32_t ntime = swab32(pdata[17]);
210 getAlgoString((const uint8_t*) (&endiandata[1]), hashOrder);
212 if (opt_debug && !thr_id) applog(LOG_DEBUG, "hash order %s (%08x)", hashOrder, ntime);
219 be32enc(&endiandata[19], nonce);
220 x16s_hash(hash32, endiandata);
222 if (hash32[7] <= Htarg && fulltest(hash32, ptarget)) {
223 work_set_target_ratio(work, hash32);
225 *hashes_done = pdata[19] - first_nonce;
230 } while (nonce < max_nonce && !(*restart));
233 *hashes_done = pdata[19] - first_nonce + 1;