]>
Commit | Line | Data |
---|---|---|
a4f51bd9 TP |
1 | /** |
2 | * ==========================(LICENSE BEGIN)============================ | |
3 | * | |
4 | * Copyright (c) 2015 kernels10, tpruvot | |
5 | * | |
6 | * Permission is hereby granted, free of charge, to any person obtaining | |
7 | * a copy of this software and associated documentation files (the | |
8 | * "Software"), to deal in the Software without restriction, including | |
9 | * without limitation the rights to use, copy, modify, merge, publish, | |
10 | * distribute, sublicense, and/or sell copies of the Software, and to | |
11 | * permit persons to whom the Software is furnished to do so, subject to | |
12 | * the following conditions: | |
13 | * | |
14 | * The above copyright notice and this permission notice shall be | |
15 | * included in all copies or substantial portions of the Software. | |
16 | * | |
17 | * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, | |
18 | * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF | |
19 | * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. | |
20 | * IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY | |
21 | * CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, | |
22 | * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE | |
23 | * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. | |
24 | * | |
25 | * ===========================(LICENSE END)============================= | |
26 | * | |
27 | * @file drop.c | |
28 | * @author kernels10 <[email protected]> | |
29 | * @author tpruvot <tpruvot@github> | |
30 | */ | |
31 | ||
32 | #define POK_BOOL_MASK 0x00008000 | |
33 | #define POK_DATA_MASK 0xFFFF0000 | |
34 | ||
35 | #include "miner.h" | |
36 | ||
37 | #include <string.h> | |
38 | ||
39 | #include "sha3/sph_blake.h" | |
40 | #include "sha3/sph_groestl.h" | |
41 | #include "sha3/sph_jh.h" | |
42 | #include "sha3/sph_keccak.h" | |
43 | #include "sha3/sph_skein.h" | |
44 | #include "sha3/sph_cubehash.h" | |
45 | #include "sha3/sph_echo.h" | |
46 | #include "sha3/sph_fugue.h" | |
47 | #include "sha3/sph_luffa.h" | |
48 | #include "sha3/sph_simd.h" | |
49 | #include "sha3/sph_shavite.h" | |
50 | ||
51 | static void shiftr_lp(const uint32_t *input, uint32_t *output, unsigned int shift) | |
52 | { | |
53 | if(!shift) { | |
54 | memcpy(output, input, 64); | |
55 | return; | |
56 | } | |
57 | ||
58 | memset(output, 0, 64); | |
59 | for(int i = 0; i < 15; ++i) { | |
60 | output[i + 1] |= (input[i] >> (32 - shift)); | |
61 | output[i] |= (input[i] << shift); | |
62 | } | |
63 | ||
64 | output[15] |= (input[15] << shift); | |
65 | return; | |
66 | } | |
67 | ||
68 | static void switchHash(const void *input, void *output, int id) | |
69 | { | |
70 | sph_keccak512_context ctx_keccak; | |
71 | sph_blake512_context ctx_blake; | |
72 | sph_groestl512_context ctx_groestl; | |
73 | sph_skein512_context ctx_skein; | |
74 | sph_luffa512_context ctx_luffa; | |
75 | sph_echo512_context ctx_echo; | |
76 | sph_simd512_context ctx_simd; | |
77 | sph_cubehash512_context ctx_cubehash; | |
78 | sph_fugue512_context ctx_fugue; | |
79 | sph_shavite512_context ctx_shavite; | |
80 | ||
81 | switch(id) { | |
82 | case 0: | |
83 | sph_keccak512_init(&ctx_keccak); sph_keccak512(&ctx_keccak, input, 64); sph_keccak512_close(&ctx_keccak, output); | |
84 | break; | |
85 | case 1: | |
86 | sph_blake512_init(&ctx_blake); sph_blake512(&ctx_blake, input, 64); sph_blake512_close(&ctx_blake, output); | |
87 | break; | |
88 | case 2: | |
89 | sph_groestl512_init(&ctx_groestl); sph_groestl512(&ctx_groestl, input, 64); sph_groestl512_close(&ctx_groestl, output); | |
90 | break; | |
91 | case 3: | |
92 | sph_skein512_init(&ctx_skein); sph_skein512(&ctx_skein, input, 64); sph_skein512_close(&ctx_skein, output); | |
93 | break; | |
94 | case 4: | |
95 | sph_luffa512_init(&ctx_luffa); sph_luffa512(&ctx_luffa, input, 64); sph_luffa512_close(&ctx_luffa, output); | |
96 | break; | |
97 | case 5: | |
98 | sph_echo512_init(&ctx_echo); sph_echo512(&ctx_echo, input, 64); sph_echo512_close(&ctx_echo, output); | |
99 | break; | |
100 | case 6: | |
101 | sph_shavite512_init(&ctx_shavite); sph_shavite512(&ctx_shavite, input, 64); sph_shavite512_close(&ctx_shavite, output); | |
102 | break; | |
103 | case 7: | |
104 | sph_fugue512_init(&ctx_fugue); sph_fugue512(&ctx_fugue, input, 64); sph_fugue512_close(&ctx_fugue, output); | |
105 | break; | |
106 | case 8: | |
107 | sph_simd512_init(&ctx_simd); sph_simd512(&ctx_simd, input, 64); sph_simd512_close(&ctx_simd, output); | |
108 | break; | |
109 | case 9: | |
110 | sph_cubehash512_init(&ctx_cubehash); sph_cubehash512(&ctx_cubehash, input, 64); sph_cubehash512_close(&ctx_cubehash, output); | |
111 | break; | |
112 | default: | |
113 | break; | |
114 | } | |
115 | } | |
116 | ||
117 | void droplp_hash(void *state, const void *input) | |
118 | { | |
119 | uint32_t _ALIGN(64) hash[2][16]; | |
120 | sph_jh512_context ctx_jh; | |
121 | uint32_t *hashA = hash[0]; | |
122 | uint32_t *hashB = hash[1]; | |
123 | ||
124 | sph_jh512_init(&ctx_jh); | |
125 | sph_jh512(&ctx_jh, input, 80); | |
126 | sph_jh512_close(&ctx_jh, (void*)(hashA)); | |
127 | ||
128 | unsigned int startPosition = hashA[0] % 31; | |
129 | unsigned int i = 0; | |
130 | int j = 0; | |
131 | int start = 0; | |
132 | ||
133 | for (i = startPosition; i < 31; i+=9) { | |
134 | start = i % 10; | |
135 | for (j = start; j < 10; j++) { | |
136 | shiftr_lp(hashA, hashB, (i & 3)); | |
137 | switchHash((const void*)hashB, (void*)hashA, j); | |
138 | } | |
139 | for (j = 0; j < start; j++) { | |
140 | shiftr_lp(hashA, hashB, (i & 3)); | |
141 | switchHash((const void*)hashB, (void*)hashA, j); | |
142 | } | |
143 | } | |
144 | for (i = 0; i < startPosition; i += 9) { | |
145 | start = i % 10; | |
146 | for (j = start; j < 10; j++) { | |
147 | shiftr_lp(hashA, hashB, (i & 3)); | |
148 | switchHash((const void*)hashB, (void*)hashA, j); | |
149 | } | |
150 | for (j = 0; j < start; j++) { | |
151 | shiftr_lp(hashA, hashB, (i & 3)); | |
152 | switchHash((const void*)hashB, (void*)hashA, j); | |
153 | } | |
154 | } | |
155 | ||
156 | memcpy(state, hashA, 32); | |
157 | } | |
158 | ||
159 | static void droplp_hash_pok(void *output, uint32_t *pdata, const uint32_t version) | |
160 | { | |
161 | uint32_t _ALIGN(64) hash[8]; | |
162 | uint32_t pok; | |
163 | ||
164 | pdata[0] = version; | |
165 | droplp_hash(hash, pdata); | |
166 | ||
167 | // fill PoK | |
168 | pok = version | (hash[0] & POK_DATA_MASK); | |
169 | if (pdata[0] != pok) { | |
170 | pdata[0] = pok; | |
171 | droplp_hash(hash, pdata); | |
172 | } | |
173 | memcpy(output, hash, 32); | |
174 | } | |
175 | ||
176 | int scanhash_drop(int thr_id, struct work *work, uint32_t max_nonce, uint64_t *hashes_done) | |
177 | { | |
f7c584dc | 178 | uint32_t _ALIGN(128) hash[16]; |
a4f51bd9 TP |
179 | uint32_t *pdata = work->data; |
180 | uint32_t *ptarget = work->target; | |
181 | const uint32_t version = pdata[0] & (~POK_DATA_MASK); | |
182 | const uint32_t first_nonce = pdata[19]; | |
183 | uint32_t nonce = first_nonce; | |
184 | #define tmpdata pdata | |
185 | ||
186 | if (opt_benchmark) | |
187 | ptarget[7] = 0x07ff; | |
188 | ||
189 | const uint32_t htarg = ptarget[7]; | |
190 | ||
191 | do { | |
192 | tmpdata[19] = nonce; | |
193 | droplp_hash_pok(hash, tmpdata, version); | |
194 | ||
195 | if (hash[7] <= htarg && fulltest(hash, ptarget)) { | |
f7c584dc | 196 | work_set_target_ratio(work, hash); |
a4f51bd9 TP |
197 | pdata[0] = tmpdata[0]; |
198 | pdata[19] = nonce; | |
199 | *hashes_done = pdata[19] - first_nonce + 1; | |
a4f51bd9 TP |
200 | return 1; |
201 | } | |
202 | nonce++; | |
203 | ||
204 | } while (nonce < max_nonce && !work_restart[thr_id].restart); | |
205 | ||
206 | pdata[19] = nonce; | |
207 | *hashes_done = pdata[19] - first_nonce + 1; | |
208 | return 0; | |
209 | } |