Book a Demo!
CoCalc Logo Icon
StoreFeaturesDocsShareSupportNewsAboutPoliciesSign UpSign In
tpruvot
GitHub Repository: tpruvot/cpuminer-multi
Path: blob/linux/algo/bitcore.c
1201 views
1
/*
2
* Bitcore TimeTravel-10 Algo
3
*
4
* tpruvot 2017
5
*/
6
7
#include <miner.h>
8
9
#include <stdlib.h>
10
#include <stdint.h>
11
#include <string.h>
12
#include <stdio.h>
13
14
#include <sha3/sph_blake.h>
15
#include <sha3/sph_bmw.h>
16
#include <sha3/sph_groestl.h>
17
#include <sha3/sph_jh.h>
18
#include <sha3/sph_keccak.h>
19
#include <sha3/sph_skein.h>
20
#include <sha3/sph_luffa.h>
21
#include <sha3/sph_cubehash.h>
22
#include <sha3/sph_shavite.h>
23
#include <sha3/sph_simd.h>
24
25
// BitCore Genesis Timestamp
26
#define HASH_FUNC_BASE_TIMESTAMP 1492973331U
27
28
#define HASH_FUNC_COUNT 10
29
#define HASH_FUNC_COUNT_PERMUTATIONS 40320
30
31
static __thread uint32_t s_ntime = UINT32_MAX;
32
static __thread int permutation[HASH_FUNC_COUNT] = { 0 };
33
34
// helpers
35
static void swap(int *a, int *b) {
36
int c = *a;
37
*a = *b;
38
*b = c;
39
}
40
41
static void reverse(int *pbegin, int *pend) {
42
while ( (pbegin != pend) && (pbegin != --pend) )
43
swap(pbegin++, pend);
44
}
45
46
static void next_permutation(int *pbegin, int *pend) {
47
if (pbegin == pend)
48
return;
49
50
int *i = pbegin;
51
++i;
52
if (i == pend)
53
return;
54
55
i = pend;
56
--i;
57
58
while (1) {
59
int *j = i;
60
--i;
61
62
if (*i < *j) {
63
int *k = pend;
64
65
while (!(*i < *--k))
66
/* pass */;
67
68
swap(i, k);
69
reverse(j, pend);
70
return; // true
71
}
72
73
if (i == pbegin) {
74
reverse(pbegin, pend);
75
return; // false
76
}
77
}
78
}
79
80
void bitcore_hash(void *output, const void *input)
81
{
82
uint32_t _ALIGN(64) hash[16 * HASH_FUNC_COUNT];
83
uint32_t *hashA, *hashB;
84
uint32_t dataLen = 64;
85
uint32_t *work_data = (uint32_t *)input;
86
const uint32_t timestamp = work_data[17];
87
88
sph_blake512_context ctx_blake;
89
sph_bmw512_context ctx_bmw;
90
sph_groestl512_context ctx_groestl;
91
sph_skein512_context ctx_skein;
92
sph_jh512_context ctx_jh;
93
sph_keccak512_context ctx_keccak;
94
sph_luffa512_context ctx_luffa;
95
sph_cubehash512_context ctx_cubehash;
96
sph_shavite512_context ctx_shavite;
97
sph_simd512_context ctx_simd;
98
99
// We want to permute algorithms. To get started we
100
// initialize an array with a sorted sequence of unique
101
// integers where every integer represents its own algorithm.
102
if (timestamp != s_ntime) {
103
int steps = (int) (timestamp - HASH_FUNC_BASE_TIMESTAMP) % HASH_FUNC_COUNT_PERMUTATIONS;
104
for (int i = 0; i < HASH_FUNC_COUNT; i++) {
105
permutation[i] = i;
106
}
107
for (int i = 0; i < steps; i++) {
108
next_permutation(permutation, permutation + HASH_FUNC_COUNT);
109
}
110
s_ntime = timestamp;
111
}
112
113
for (int i = 0; i < HASH_FUNC_COUNT; i++) {
114
if (i == 0) {
115
dataLen = 80;
116
hashA = work_data;
117
} else {
118
dataLen = 64;
119
hashA = &hash[16 * (i - 1)];
120
}
121
hashB = &hash[16 * i];
122
123
switch(permutation[i]) {
124
case 0:
125
sph_blake512_init(&ctx_blake);
126
sph_blake512(&ctx_blake, hashA, dataLen);
127
sph_blake512_close(&ctx_blake, hashB);
128
break;
129
case 1:
130
sph_bmw512_init(&ctx_bmw);
131
sph_bmw512(&ctx_bmw, hashA, dataLen);
132
sph_bmw512_close(&ctx_bmw, hashB);
133
break;
134
case 2:
135
sph_groestl512_init(&ctx_groestl);
136
sph_groestl512(&ctx_groestl, hashA, dataLen);
137
sph_groestl512_close(&ctx_groestl, hashB);
138
break;
139
case 3:
140
sph_skein512_init(&ctx_skein);
141
sph_skein512(&ctx_skein, hashA, dataLen);
142
sph_skein512_close(&ctx_skein, hashB);
143
break;
144
case 4:
145
sph_jh512_init(&ctx_jh);
146
sph_jh512(&ctx_jh, hashA, dataLen);
147
sph_jh512_close(&ctx_jh, hashB);
148
break;
149
case 5:
150
sph_keccak512_init(&ctx_keccak);
151
sph_keccak512(&ctx_keccak, hashA, dataLen);
152
sph_keccak512_close(&ctx_keccak, hashB);
153
break;
154
case 6:
155
sph_luffa512_init(&ctx_luffa);
156
sph_luffa512(&ctx_luffa, hashA, dataLen);
157
sph_luffa512_close(&ctx_luffa, hashB);
158
break;
159
case 7:
160
sph_cubehash512_init(&ctx_cubehash);
161
sph_cubehash512(&ctx_cubehash, hashA, dataLen);
162
sph_cubehash512_close(&ctx_cubehash, hashB);
163
break;
164
case 8:
165
sph_shavite512_init(&ctx_shavite);
166
sph_shavite512(&ctx_shavite, hashA, dataLen);
167
sph_shavite512_close(&ctx_shavite, hashB);
168
break;
169
case 9:
170
sph_simd512_init(&ctx_simd);
171
sph_simd512(&ctx_simd, hashA, dataLen);
172
sph_simd512_close(&ctx_simd, hashB);
173
break;
174
default:
175
break;
176
}
177
}
178
179
memcpy(output, &hash[16 * (HASH_FUNC_COUNT - 1)], 32);
180
}
181
182
int scanhash_bitcore(int thr_id, struct work *work, uint32_t max_nonce, uint64_t *hashes_done)
183
{
184
uint32_t _ALIGN(64) hash[8];
185
uint32_t _ALIGN(64) endiandata[20];
186
uint32_t *pdata = work->data;
187
uint32_t *ptarget = work->target;
188
189
const uint32_t Htarg = ptarget[7];
190
const uint32_t first_nonce = pdata[19];
191
uint32_t nonce = first_nonce;
192
volatile uint8_t *restart = &(work_restart[thr_id].restart);
193
194
if (opt_benchmark)
195
ptarget[7] = 0x0cff;
196
197
for (int k=0; k < 19; k++)
198
be32enc(&endiandata[k], pdata[k]);
199
200
do {
201
be32enc(&endiandata[19], nonce);
202
bitcore_hash(hash, endiandata);
203
204
if (hash[7] <= Htarg && fulltest(hash, ptarget)) {
205
work_set_target_ratio(work, hash);
206
pdata[19] = nonce;
207
*hashes_done = pdata[19] - first_nonce;
208
return 1;
209
}
210
nonce++;
211
212
} while (nonce < max_nonce && !(*restart));
213
214
pdata[19] = nonce;
215
*hashes_done = pdata[19] - first_nonce + 1;
216
return 0;
217
}
218
219