Book a Demo!
CoCalc Logo Icon
StoreFeaturesDocsShareSupportNewsAboutPoliciesSign UpSign In
tpruvot
GitHub Repository: tpruvot/cpuminer-multi
Path: blob/linux/algo/jha.c
1201 views
1
#include "miner.h"
2
3
#include <stdlib.h>
4
#include <stdint.h>
5
#include <string.h>
6
#include <stdio.h>
7
8
#include "sha3/sph_keccak.h"
9
#include "sha3/sph_groestl.h"
10
#include "sha3/sph_skein.h"
11
#include "sha3/sph_blake.h"
12
#include "sha3/sph_jh.h"
13
14
void jha_hash(void *output, const void *input)
15
{
16
uint8_t _ALIGN(128) hash[64];
17
18
sph_blake512_context ctx_blake;
19
sph_groestl512_context ctx_groestl;
20
sph_jh512_context ctx_jh;
21
sph_keccak512_context ctx_keccak;
22
sph_skein512_context ctx_skein;
23
24
// JHA v8 input is 80 bytes
25
sph_keccak512_init(&ctx_keccak);
26
sph_keccak512(&ctx_keccak, input, 80);
27
sph_keccak512_close(&ctx_keccak, (&hash));
28
29
// Heavy & Light Pair Loop
30
for (int round = 0; round < 3; round++)
31
{
32
if (hash[0] & 0x01) {
33
sph_groestl512_init(&ctx_groestl);
34
sph_groestl512(&ctx_groestl, (&hash), 64);
35
sph_groestl512_close(&ctx_groestl, (&hash));
36
} else {
37
sph_skein512_init(&ctx_skein);
38
sph_skein512(&ctx_skein, (&hash), 64);
39
sph_skein512_close(&ctx_skein, (&hash));
40
}
41
42
if (hash[0] & 0x01) {
43
sph_blake512_init(&ctx_blake);
44
sph_blake512(&ctx_blake, (&hash), 64);
45
sph_blake512_close(&ctx_blake, (&hash));
46
} else {
47
sph_jh512_init(&ctx_jh);
48
sph_jh512(&ctx_jh, (&hash), 64);
49
sph_jh512_close(&ctx_jh, (&hash));
50
}
51
}
52
53
memcpy(output, hash, 32);
54
}
55
56
int scanhash_jha(int thr_id, struct work *work, uint32_t max_nonce, uint64_t *hashes_done)
57
{
58
uint32_t _ALIGN(128) hash32[8];
59
uint32_t _ALIGN(128) endiandata[20];
60
uint32_t *pdata = work->data;
61
uint32_t *ptarget = work->target;
62
const uint32_t first_nonce = pdata[19];
63
const uint32_t Htarg = ptarget[7];
64
uint32_t n = pdata[19] - 1;
65
66
uint64_t htmax[] = {
67
0,
68
0xF,
69
0xFF,
70
0xFFF,
71
0xFFFF,
72
0x10000000
73
};
74
uint32_t masks[] = {
75
0xFFFFFFFF,
76
0xFFFFFFF0,
77
0xFFFFFF00,
78
0xFFFFF000,
79
0xFFFF0000,
80
0
81
};
82
83
// we need bigendian data...
84
for (int i=0; i < 19; i++) {
85
be32enc(&endiandata[i], pdata[i]);
86
}
87
88
#ifdef DEBUG_ALGO
89
printf("[%d] Htarg=%X\n", thr_id, Htarg);
90
#endif
91
for (int m=0; m < 6; m++) {
92
if (Htarg <= htmax[m]) {
93
uint32_t mask = masks[m];
94
do {
95
pdata[19] = ++n;
96
be32enc(&endiandata[19], n);
97
jha_hash(hash32, endiandata);
98
#ifndef DEBUG_ALGO
99
if ((!(hash32[7] & mask)) && fulltest(hash32, ptarget)) {
100
work_set_target_ratio(work, hash32);
101
*hashes_done = n - first_nonce + 1;
102
return 1;
103
}
104
#else
105
if (!(n % 0x1000) && !thr_id) printf(".");
106
if (!(hash32[7] & mask)) {
107
printf("[%d]",thr_id);
108
if (fulltest(hash32, ptarget)) {
109
work_set_target_ratio(work, hash32);
110
*hashes_done = n - first_nonce + 1;
111
return 1;
112
}
113
}
114
#endif
115
} while (n < max_nonce && !work_restart[thr_id].restart);
116
// see blake.c if else to understand the loop on htmax => mask
117
break;
118
}
119
}
120
121
*hashes_done = n - first_nonce + 1;
122
pdata[19] = n;
123
return 0;
124
}
125
126