]> Git Repo - cpuminer-multi.git/blame - algo/heavy.c
cryptonight: handle rpc 2.0 pools and clean the crypto-rpc-code
[cpuminer-multi.git] / algo / heavy.c
CommitLineData
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 */
12static 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 31extern 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
81int 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}
This page took 0.037511 seconds and 4 git commands to generate.