|
|
@ -16,8 +16,12 @@ |
|
|
|
|
|
|
|
|
|
|
|
#include "sha256_generic.c" |
|
|
|
#include "sha256_generic.c" |
|
|
|
|
|
|
|
|
|
|
|
static const bool opt_verbose = true; |
|
|
|
enum { |
|
|
|
static const bool opt_debug = true; |
|
|
|
POW_SLEEP_INTERVAL = 5, |
|
|
|
|
|
|
|
}; |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
static const bool opt_verbose = false; |
|
|
|
|
|
|
|
static const bool opt_debug = false; |
|
|
|
|
|
|
|
|
|
|
|
struct data_buffer { |
|
|
|
struct data_buffer { |
|
|
|
void *buf; |
|
|
|
void *buf; |
|
|
@ -32,7 +36,7 @@ struct upload_buffer { |
|
|
|
struct work { |
|
|
|
struct work { |
|
|
|
unsigned char midstate[32]; |
|
|
|
unsigned char midstate[32]; |
|
|
|
unsigned char data[128]; |
|
|
|
unsigned char data[128]; |
|
|
|
unsigned char hash[64]; |
|
|
|
unsigned char hash[32]; |
|
|
|
unsigned char hash1[64]; |
|
|
|
unsigned char hash1[64]; |
|
|
|
BIGNUM *target; |
|
|
|
BIGNUM *target; |
|
|
|
}; |
|
|
|
}; |
|
|
@ -169,6 +173,19 @@ err_out: |
|
|
|
return NULL; |
|
|
|
return NULL; |
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
static char *bin2hex(unsigned char *p, size_t len) |
|
|
|
|
|
|
|
{ |
|
|
|
|
|
|
|
int i; |
|
|
|
|
|
|
|
char *s = malloc((len * 2) + 1); |
|
|
|
|
|
|
|
if (!s) |
|
|
|
|
|
|
|
return NULL; |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
for (i = 0; i < len; i++) |
|
|
|
|
|
|
|
sprintf(s + (i * 2), "%02x", p[i]); |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
return s; |
|
|
|
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
static bool hex2bin(unsigned char *p, const char *hexstr, size_t len) |
|
|
|
static bool hex2bin(unsigned char *p, const char *hexstr, size_t len) |
|
|
|
{ |
|
|
|
{ |
|
|
|
while (*hexstr && len) { |
|
|
|
while (*hexstr && len) { |
|
|
@ -270,6 +287,17 @@ err_out: |
|
|
|
return NULL; |
|
|
|
return NULL; |
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
#define ___constant_swab32(x) ((u32)( \ |
|
|
|
|
|
|
|
(((u32)(x) & (u32)0x000000ffUL) << 24) | \ |
|
|
|
|
|
|
|
(((u32)(x) & (u32)0x0000ff00UL) << 8) | \ |
|
|
|
|
|
|
|
(((u32)(x) & (u32)0x00ff0000UL) >> 8) | \ |
|
|
|
|
|
|
|
(((u32)(x) & (u32)0xff000000UL) >> 24))) |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
static inline uint32_t swab32(uint32_t v) |
|
|
|
|
|
|
|
{ |
|
|
|
|
|
|
|
return ___constant_swab32(v); |
|
|
|
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
static void runhash(void *state, void *input, const void *init) |
|
|
|
static void runhash(void *state, void *input, const void *init) |
|
|
|
{ |
|
|
|
{ |
|
|
|
memcpy(state, init, 32); |
|
|
|
memcpy(state, init, 32); |
|
|
@ -285,6 +313,7 @@ static const uint32_t init_state[8] = { |
|
|
|
static uint32_t scanhash(unsigned char *midstate, unsigned char *data, |
|
|
|
static uint32_t scanhash(unsigned char *midstate, unsigned char *data, |
|
|
|
unsigned char *hash1, unsigned char *hash) |
|
|
|
unsigned char *hash1, unsigned char *hash) |
|
|
|
{ |
|
|
|
{ |
|
|
|
|
|
|
|
uint32_t *hash32 = (uint32_t *) hash; |
|
|
|
uint32_t *nonce = (uint32_t *)(data + 12); |
|
|
|
uint32_t *nonce = (uint32_t *)(data + 12); |
|
|
|
uint32_t n; |
|
|
|
uint32_t n; |
|
|
|
|
|
|
|
|
|
|
@ -296,14 +325,21 @@ static uint32_t scanhash(unsigned char *midstate, unsigned char *data, |
|
|
|
runhash(hash1, data, midstate); |
|
|
|
runhash(hash1, data, midstate); |
|
|
|
runhash(hash, hash1, init_state); |
|
|
|
runhash(hash, hash1, init_state); |
|
|
|
|
|
|
|
|
|
|
|
if (((uint16_t *)hash)[14] == 0) { |
|
|
|
if (hash32[7] == 0) { |
|
|
|
if (opt_debug) |
|
|
|
if (1) { |
|
|
|
fprintf(stderr, "DBG: found zeroes in hash\n"); |
|
|
|
char *hexstr; |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
hexstr = bin2hex(hash, 32); |
|
|
|
|
|
|
|
fprintf(stderr, |
|
|
|
|
|
|
|
"DBG: found zeroes in hash:\n%s\n", |
|
|
|
|
|
|
|
hexstr); |
|
|
|
|
|
|
|
free(hexstr); |
|
|
|
|
|
|
|
} |
|
|
|
return n; |
|
|
|
return n; |
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
if ((n & 0xffffff) == 0) { |
|
|
|
if ((n & 0xffffff) == 0) { |
|
|
|
if (opt_debug) |
|
|
|
if (1) |
|
|
|
fprintf(stderr, "DBG: end of nonce range\n"); |
|
|
|
fprintf(stderr, "DBG: end of nonce range\n"); |
|
|
|
return 0; |
|
|
|
return 0; |
|
|
|
} |
|
|
|
} |
|
|
@ -315,22 +351,63 @@ static const char *userpass = "pretzel:smooth"; |
|
|
|
|
|
|
|
|
|
|
|
static void submit_work(struct work *work) |
|
|
|
static void submit_work(struct work *work) |
|
|
|
{ |
|
|
|
{ |
|
|
|
char hexstr[256 + 1], *s; |
|
|
|
char *hexstr = NULL, *s = NULL; |
|
|
|
|
|
|
|
json_t *val, *res; |
|
|
|
int i; |
|
|
|
int i; |
|
|
|
json_t *val; |
|
|
|
unsigned char hash_rev[32]; |
|
|
|
|
|
|
|
BIGNUM *hashnum; |
|
|
|
|
|
|
|
char *s_hash, *s_target; |
|
|
|
|
|
|
|
|
|
|
|
printf("PROOF OF WORK FOUND\n"); |
|
|
|
printf("PROOF OF WORK FOUND? submitting...\n"); |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
for (i = 0; i < 32/4; i++) |
|
|
|
|
|
|
|
((uint32_t *)hash_rev)[i] = |
|
|
|
|
|
|
|
swab32(((uint32_t *)work->hash)[i]); |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
hashnum = BN_bin2bn(hash_rev, sizeof(hash_rev), NULL); |
|
|
|
|
|
|
|
if (!hashnum) { |
|
|
|
|
|
|
|
fprintf(stderr, "BN_bin2bn failed\n"); |
|
|
|
|
|
|
|
return; |
|
|
|
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
s_hash = BN_bn2hex(hashnum); |
|
|
|
|
|
|
|
s_target = BN_bn2hex(work->target); |
|
|
|
|
|
|
|
fprintf(stderr, " hash:%s\n hashTarget:%s\n", |
|
|
|
|
|
|
|
s_hash, s_target); |
|
|
|
|
|
|
|
free(s_hash); |
|
|
|
|
|
|
|
free(s_target); |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
#if 0 |
|
|
|
|
|
|
|
i = BN_cmp(hashnum, work->target); |
|
|
|
|
|
|
|
#endif |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
BN_free(hashnum); |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
#if 0 |
|
|
|
|
|
|
|
if (i >= 0) { |
|
|
|
|
|
|
|
fprintf(stderr, "---INVALID--- proof of work found.\n"); |
|
|
|
|
|
|
|
return; |
|
|
|
|
|
|
|
} |
|
|
|
|
|
|
|
#endif |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
#if 0 |
|
|
|
|
|
|
|
/* byte reverse data */ |
|
|
|
|
|
|
|
for (i = 0; i < 128/4; i ++) |
|
|
|
|
|
|
|
((uint32_t *)work->data)[i] = |
|
|
|
|
|
|
|
swab32(((uint32_t *)work->data)[i]); |
|
|
|
|
|
|
|
#endif |
|
|
|
|
|
|
|
|
|
|
|
/* build hex string */ |
|
|
|
/* build hex string */ |
|
|
|
for (i = 0; i < sizeof(work->data); i++) |
|
|
|
hexstr = bin2hex(work->data, sizeof(work->data)); |
|
|
|
sprintf(hexstr + (i * 2), "%02x", work->data[i]); |
|
|
|
if (!hexstr) |
|
|
|
|
|
|
|
goto out; |
|
|
|
|
|
|
|
|
|
|
|
/* build JSON-RPC request */ |
|
|
|
/* build JSON-RPC request */ |
|
|
|
if (asprintf(&s, |
|
|
|
if (asprintf(&s, |
|
|
|
"{\"method\": \"getwork\", \"params\": [ \"%s\" ], \"id\":1}\r\n", |
|
|
|
"{\"method\": \"getwork\", \"params\": [ \"%s\" ], \"id\":1}\r\n", |
|
|
|
hexstr) < 0) { |
|
|
|
hexstr) < 0) { |
|
|
|
fprintf(stderr, "asprintf failed\n"); |
|
|
|
fprintf(stderr, "asprintf failed\n"); |
|
|
|
return; |
|
|
|
goto out; |
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
if (opt_debug) |
|
|
|
if (opt_debug) |
|
|
@ -340,11 +417,19 @@ static void submit_work(struct work *work) |
|
|
|
val = json_rpc_call(url, userpass, s); |
|
|
|
val = json_rpc_call(url, userpass, s); |
|
|
|
if (!val) { |
|
|
|
if (!val) { |
|
|
|
fprintf(stderr, "submit_work json_rpc_call failed\n"); |
|
|
|
fprintf(stderr, "submit_work json_rpc_call failed\n"); |
|
|
|
return; |
|
|
|
goto out; |
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
free(s); |
|
|
|
res = json_object_get(val, "result"); |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
printf("PROOF OF WORK RESULT: %s\n", |
|
|
|
|
|
|
|
json_is_true(res) ? "true (yay!!!)" : "false (booooo)"); |
|
|
|
|
|
|
|
|
|
|
|
json_decref(val); |
|
|
|
json_decref(val); |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
out: |
|
|
|
|
|
|
|
free(s); |
|
|
|
|
|
|
|
free(hexstr); |
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
static int main_loop(void) |
|
|
|
static int main_loop(void) |
|
|
@ -388,7 +473,7 @@ static int main_loop(void) |
|
|
|
submit_work(work); |
|
|
|
submit_work(work); |
|
|
|
|
|
|
|
|
|
|
|
fprintf(stderr, "sleeping, after proof-of-work...\n"); |
|
|
|
fprintf(stderr, "sleeping, after proof-of-work...\n"); |
|
|
|
sleep(20); |
|
|
|
sleep(POW_SLEEP_INTERVAL); |
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
work_free(work); |
|
|
|
work_free(work); |
|
|
|