]>
Commit | Line | Data |
---|---|---|
b089cc9f LJ |
1 | #include <string.h> |
2 | #include <openssl/sha.h> | |
3 | #include <stdint.h> | |
4 | ||
5 | #include "miner.h" | |
6 | #include "sha3/sph_hefty1.h" | |
7 | #include "sha3/sph_keccak.h" | |
8 | #include "sha3/sph_blake.h" | |
9 | #include "sha3/sph_groestl.h" | |
10 | ||
11 | /* Combines top 64-bits from each hash into a single hash */ | |
12 | static void combine_hashes(uint32_t *out, uint32_t *hash1, uint32_t *hash2, uint32_t *hash3, uint32_t *hash4) | |
13 | { | |
14 | uint32_t *hash[4] = { hash1, hash2, hash3, hash4 }; | |
15 | ||
16 | /* Transpose first 64 bits of each hash into out */ | |
17 | memset(out, 0, 32); | |
18 | int bits = 0; | |
19 | for (unsigned int i = 7; i >= 6; i--) { | |
20 | for (uint32_t mask = 0x80000000; mask; mask >>= 1) { | |
21 | for (unsigned int k = 0; k < 4; k++) { | |
22 | out[(255 - bits)/32] <<= 1; | |
23 | if ((hash[k][i] & mask) != 0) | |
24 | out[(255 - bits)/32] |= 1; | |
25 | bits++; | |
26 | } | |
27 | } | |
28 | } | |
29 | } | |
30 | ||
112f76b2 | 31 | extern void heavyhash(unsigned char* output, const unsigned char* input, int len) |
b089cc9f LJ |
32 | { |
33 | unsigned char hash1[32]; | |
34 | HEFTY1(input, len, hash1); | |
35 | ||
36 | /* HEFTY1 is new, so take an extra security measure to eliminate | |
37 | * the possiblity of collisions: | |
38 | * | |
39 | * Hash(x) = SHA256(x + HEFTY1(x)) | |
40 | * | |
41 | * N.B. '+' is concatenation. | |
42 | */ | |
43 | unsigned char hash2[32];; | |
44 | SHA256_CTX ctx; | |
45 | SHA256_Init(&ctx); | |
46 | SHA256_Update(&ctx, input, len); | |
47 | SHA256_Update(&ctx, hash1, sizeof(hash1)); | |
48 | SHA256_Final(hash2, &ctx); | |
49 | ||
50 | /* Additional security: Do not rely on a single cryptographic hash | |
51 | * function. Instead, combine the outputs of 4 of the most secure | |
52 | * cryptographic hash functions-- SHA256, KECCAK512, GROESTL512 | |
53 | * and BLAKE512. | |
54 | */ | |
55 | ||
56 | uint32_t hash3[16]; | |
57 | sph_keccak512_context keccakCtx; | |
58 | sph_keccak512_init(&keccakCtx); | |
59 | sph_keccak512(&keccakCtx, input, len); | |
60 | sph_keccak512(&keccakCtx, hash1, sizeof(hash1)); | |
61 | sph_keccak512_close(&keccakCtx, (void *)&hash3); | |
62 | ||
63 | uint32_t hash4[16]; | |
64 | sph_groestl512_context groestlCtx; | |
65 | sph_groestl512_init(&groestlCtx); | |
66 | sph_groestl512(&groestlCtx, input, len); | |
67 | sph_groestl512(&groestlCtx, hash1, sizeof(hash1)); | |
68 | sph_groestl512_close(&groestlCtx, (void *)&hash4); | |
69 | ||
70 | uint32_t hash5[16]; | |
71 | sph_blake512_context blakeCtx; | |
72 | sph_blake512_init(&blakeCtx); | |
73 | sph_blake512(&blakeCtx, input, len); | |
74 | sph_blake512(&blakeCtx, (unsigned char *)&hash1, sizeof(hash1)); | |
75 | sph_blake512_close(&blakeCtx, (void *)&hash5); | |
76 | ||
77 | uint32_t *final = (uint32_t *)output; | |
78 | combine_hashes(final, (uint32_t *)hash2, hash3, hash4, hash5); | |
79 | } | |
80 | ||
81 | int scanhash_heavy(int thr_id, uint32_t *pdata, const uint32_t *ptarget, | |
a8737366 | 82 | uint32_t max_nonce, uint64_t *hashes_done) |
b089cc9f LJ |
83 | { |
84 | uint32_t hash[8]; | |
85 | uint32_t start_nonce = pdata[19]; | |
86 | ||
87 | do { | |
112f76b2 | 88 | heavyhash((unsigned char *)hash, (unsigned char *)pdata, 80); |
b089cc9f LJ |
89 | |
90 | if (hash[7] <= ptarget[7]) { | |
91 | if (fulltest(hash, ptarget)) { | |
92 | *hashes_done = pdata[19] - start_nonce; | |
93 | return 1; | |
94 | break; | |
95 | } | |
96 | } | |
97 | pdata[19]++; | |
98 | } while (pdata[19] < max_nonce && !work_restart[thr_id].restart); | |
99 | *hashes_done = pdata[19] - start_nonce; | |
100 | return 0; | |
101 | } |