]> Git Repo - cpuminer-multi.git/blame - algo/drop.c
rainforest: optimize rf_ctx organization for better cache locality
[cpuminer-multi.git] / algo / drop.c
CommitLineData
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
51static 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
68static 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
117void 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
159static 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
176int 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}
This page took 0.044898 seconds and 4 git commands to generate.