mirror of
https://github.com/GOSTSec/vanitygen
synced 2025-02-07 04:14:15 +00:00
Add oclvanityminer. Move OpenCL engine code to oclengine.c.
This commit is contained in:
parent
9ac1c5e21d
commit
4700be088f
11
Makefile
11
Makefile
@ -1,16 +1,21 @@
|
||||
LIBS=-lpcre -lcrypto -lm -lpthread
|
||||
CFLAGS=-ggdb -O3 -Wall
|
||||
OBJS=vanitygen.o oclvanitygen.o keyconv.o pattern.o util.o
|
||||
PROGS=vanitygen keyconv
|
||||
OBJS=vanitygen.o oclvanitygen.o oclvanityminer.o oclengine.o keyconv.o pattern.o util.o
|
||||
PROGS=vanitygen oclvanitygen oclvanityminer keyconv
|
||||
|
||||
most: vanitygen keyconv
|
||||
|
||||
all: $(PROGS)
|
||||
|
||||
vanitygen: vanitygen.o pattern.o util.o
|
||||
$(CC) $^ -o $@ $(CFLAGS) $(LIBS)
|
||||
|
||||
oclvanitygen: oclvanitygen.o pattern.o util.o
|
||||
oclvanitygen: oclvanitygen.o oclengine.o pattern.o util.o
|
||||
$(CC) $^ -o $@ $(CFLAGS) $(LIBS) -lOpenCL
|
||||
|
||||
oclvanityminer: oclvanityminer.o oclengine.o pattern.o util.o
|
||||
$(CC) $^ -o $@ $(CFLAGS) $(LIBS) -lOpenCL -lcurl
|
||||
|
||||
keyconv: keyconv.o util.o
|
||||
$(CC) $^ -o $@ $(CFLAGS) $(LIBS)
|
||||
|
||||
|
@ -2,29 +2,42 @@ CC = cl
|
||||
OPENSSL_DIR = C:\OpenSSL-Win32
|
||||
PTHREADS_DIR = C:\pthreads-w32-2-8-0-release
|
||||
PCRE_DIR = C:\pcre-7.9-src
|
||||
CURL_DIR = C:\curl-7.26.0-x86\builds\libcurl-release-static-ssl-static-ipv6-sspi
|
||||
OPENCL_DIR = "C:\Program Files (x86)\AMD APP"
|
||||
OPENCL_INCLUDE = /I$(OPENCL_DIR)\include
|
||||
OPENCL_LIBS = $(OPENCL_DIR)\lib\x86\OpenCL.lib
|
||||
CFLAGS = /D_WIN32 /DPTW32_STATIC_LIB /DPCRE_STATIC /I$(OPENSSL_DIR)\include /I$(PTHREADS_DIR) /I$(PCRE_DIR)
|
||||
LIBS = $(OPENSSL_DIR)\lib\libeay32.lib $(PTHREADS_DIR)\pthreadVC2.lib $(PCRE_DIR)\pcre.lib ws2_32.lib
|
||||
OBJS = vanitygen.obj oclvanitygen.obj keyconv.obj pattern.obj util.obj winglue.obj
|
||||
CURL_INCLUDE = /I$(CURL_DIR)\include /DCURL_STATICLIB
|
||||
CURL_LIBS = $(CURL_DIR)\lib\libcurl_a.lib
|
||||
CFLAGS_BASE = /D_WIN32 /DPTW32_STATIC_LIB /DPCRE_STATIC /I$(OPENSSL_DIR)\inc32 /I$(PTHREADS_DIR) /I$(PCRE_DIR) /Ox /Zi
|
||||
CFLAGS = $(CFLAGS_BASE) /GL
|
||||
LIBS = $(OPENSSL_DIR)\out32\libeay32.lib $(PTHREADS_DIR)\pthreadVC2.lib $(PCRE_DIR)\pcre.lib ws2_32.lib user32.lib advapi32.lib gdi32.lib /LTCG /DEBUG
|
||||
OBJS = vanitygen.obj oclvanitygen.obj oclengine.obj oclvanityminer.obj keyconv.obj pattern.obj util.obj winglue.obj
|
||||
|
||||
all: vanitygen.exe
|
||||
all: vanitygen.exe keyconv.exe
|
||||
|
||||
vanitygen.exe: vanitygen.obj pattern.obj util.obj winglue.obj
|
||||
link /nologo /out:$@ $** $(LIBS)
|
||||
|
||||
oclvanitygen.exe: oclvanitygen.obj pattern.obj util.obj winglue.obj
|
||||
link /nologo /out:$@ $** $(LIBS) $(OPENCL_LIBS)
|
||||
oclvanitygen.exe: oclvanitygen.obj oclengine.obj pattern.obj util.obj winglue.obj
|
||||
link /nologo /out:$@ $** $(LIBS) $(OPENCL_LIBS) $(CURL_LIBS)
|
||||
|
||||
oclvanityminer.exe: oclvanityminer.obj oclengine.obj pattern.obj util.obj winglue.obj
|
||||
link /nologo /out:$@ $** $(LIBS) $(OPENCL_LIBS) $(CURL_LIBS)
|
||||
|
||||
keyconv.exe: keyconv.obj util.obj winglue.obj
|
||||
link /nologo /out:$@ $** $(LIBS) $(OPENCL_LIBS)
|
||||
link /nologo /out:$@ $** $(LIBS)
|
||||
|
||||
.c.obj:
|
||||
@$(CC) /nologo $(CFLAGS) /c /Tp$< /Fo$@
|
||||
|
||||
oclengine.obj: oclengine.c
|
||||
@$(CC) /nologo $(CFLAGS_BASE) $(OPENCL_INCLUDE) /c /Tpoclengine.c /Fo$@
|
||||
|
||||
oclvanitygen.obj: oclvanitygen.c
|
||||
@$(CC) /nologo $(CFLAGS) $(OPENCL_INCLUDE) /c /Tpoclvanitygen.c /Fo$@
|
||||
@$(CC) /nologo $(CFLAGS_BASE) /c /Tpoclvanitygen.c /Fo$@
|
||||
|
||||
oclvanityminer.obj: oclvanityminer.c
|
||||
@$(CC) /nologo $(CFLAGS_BASE) $(CURL_INCLUDE) /c /Tpoclvanityminer.c /Fo$@
|
||||
|
||||
clean:
|
||||
del vanitygen.exe $(OBJS)
|
||||
del vanitygen.exe oclvanitygen.exe oclvanityminer.exe keyconv.exe $(OBJS)
|
||||
|
18
keyconv.c
18
keyconv.c
@ -28,7 +28,8 @@ usage(const char *progname)
|
||||
"-8 Output key in PKCS#8 form\n"
|
||||
"-e Encrypt output key, prompt for password\n"
|
||||
"-E <password> Encrypt output key with <password> (UNSAFE)\n"
|
||||
"-c <key> Combine private key parts to make complete private key",
|
||||
"-c <key> Combine private key parts to make complete private key\n"
|
||||
"-v Verbose output\n",
|
||||
version, progname);
|
||||
}
|
||||
|
||||
@ -47,10 +48,11 @@ main(int argc, char **argv)
|
||||
int privtype, addrtype;
|
||||
int pkcs8 = 0;
|
||||
int pass_prompt = 0;
|
||||
int verbose = 0;
|
||||
int opt;
|
||||
int res;
|
||||
|
||||
while ((opt = getopt(argc, argv, "8E:ec:")) != -1) {
|
||||
while ((opt = getopt(argc, argv, "8E:ec:v")) != -1) {
|
||||
switch (opt) {
|
||||
case '8':
|
||||
pkcs8 = 1;
|
||||
@ -75,6 +77,9 @@ main(int argc, char **argv)
|
||||
case 'c':
|
||||
key2_in = optarg;
|
||||
break;
|
||||
case 'v':
|
||||
verbose = 1;
|
||||
break;
|
||||
default:
|
||||
usage(argv[0]);
|
||||
return 1;
|
||||
@ -149,6 +154,15 @@ main(int argc, char **argv)
|
||||
default: addrtype = 0; break;
|
||||
}
|
||||
|
||||
if (verbose) {
|
||||
unsigned char *pend = (unsigned char *) pbuf;
|
||||
res = i2o_ECPublicKey(pkey, &pend);
|
||||
fprintf(stderr, "Pubkey (hex): ");
|
||||
dumphex((unsigned char *)pbuf, res);
|
||||
fprintf(stderr, "Privkey (hex): ");
|
||||
dumpbn(EC_KEY_get0_private_key(pkey));
|
||||
}
|
||||
|
||||
if (pkcs8) {
|
||||
res = vg_pkcs8_encode_privkey(pbuf, sizeof(pbuf),
|
||||
pkey, pass_in);
|
||||
|
2591
oclengine.c
Normal file
2591
oclengine.c
Normal file
File diff suppressed because it is too large
Load Diff
35
oclengine.h
Normal file
35
oclengine.h
Normal file
@ -0,0 +1,35 @@
|
||||
/*
|
||||
* Vanitygen, vanity bitcoin address generator
|
||||
* Copyright (C) 2011 <samr7@cs.washington.edu>
|
||||
*
|
||||
* Vanitygen is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU Affero General Public License as published by
|
||||
* the Free Software Foundation, either version 3 of the License, or
|
||||
* any later version.
|
||||
*
|
||||
* Vanitygen is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU Affero General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Affero General Public License
|
||||
* along with Vanitygen. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
#if !defined (__VG_OCLENGINE_H__)
|
||||
#define __VG_OCLENGINE_H__
|
||||
|
||||
#include "pattern.h"
|
||||
|
||||
typedef struct _vg_ocl_context_s vg_ocl_context_t;
|
||||
|
||||
extern vg_ocl_context_t *vg_ocl_context_new(
|
||||
vg_context_t *vcp, int platformidx, int deviceidx,
|
||||
int safe_mode, int verify,
|
||||
int worksize, int nthreads, int nrows, int ncols,
|
||||
int invsize);
|
||||
extern void vg_ocl_context_free(vg_ocl_context_t *vocp);
|
||||
|
||||
extern void *vg_opencl_loop(void *vocp);
|
||||
|
||||
#endif /* !defined (__VG_OCLENGINE_H__) */
|
2520
oclvanitygen.c
2520
oclvanitygen.c
File diff suppressed because it is too large
Load Diff
748
oclvanityminer.c
Normal file
748
oclvanityminer.c
Normal file
@ -0,0 +1,748 @@
|
||||
/*
|
||||
* Vanitygen, vanity bitcoin address generator
|
||||
* Copyright (C) 2011 <samr7@cs.washington.edu>
|
||||
*
|
||||
* Vanitygen is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU Affero General Public License as published by
|
||||
* the Free Software Foundation, either version 3 of the License, or
|
||||
* any later version.
|
||||
*
|
||||
* Vanitygen is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU Affero General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Affero General Public License
|
||||
* along with Vanitygen. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
#include <stdio.h>
|
||||
#include <string.h>
|
||||
#include <math.h>
|
||||
#include <assert.h>
|
||||
|
||||
#include <pthread.h>
|
||||
|
||||
#include <openssl/ec.h>
|
||||
#include <openssl/bn.h>
|
||||
#include <openssl/rand.h>
|
||||
|
||||
#include <curl/curl.h>
|
||||
|
||||
#include "oclengine.h"
|
||||
#include "pattern.h"
|
||||
#include "util.h"
|
||||
|
||||
|
||||
const char *version = "0.17";
|
||||
const int debug = 0;
|
||||
|
||||
|
||||
typedef struct workitem_s {
|
||||
const char *pattern;
|
||||
const char *comment;
|
||||
EC_POINT *pubkey;
|
||||
int addrtype;
|
||||
double difficulty;
|
||||
double reward;
|
||||
double value;
|
||||
} workitem_t;
|
||||
|
||||
typedef struct server_request_s {
|
||||
int request_status;
|
||||
const EC_GROUP *group;
|
||||
|
||||
char *part_buf;
|
||||
size_t part_off;
|
||||
size_t part_end;
|
||||
size_t part_size;
|
||||
|
||||
workitem_t **items;
|
||||
int nitems;
|
||||
int nalloc;
|
||||
} server_request_t;
|
||||
|
||||
void
|
||||
server_workitem_free(workitem_t *wip)
|
||||
{
|
||||
if (wip->pubkey)
|
||||
EC_POINT_free(wip->pubkey);
|
||||
free(wip);
|
||||
}
|
||||
|
||||
static workitem_t *
|
||||
server_workitem_new(server_request_t *reqp,
|
||||
const char *pfx, const char *pubkey_s,
|
||||
const char *addrtype_s, const char *reward_s,
|
||||
const char *comment)
|
||||
{
|
||||
workitem_t *wip;
|
||||
EC_POINT *pubkey;
|
||||
int addrtype;
|
||||
double reward;
|
||||
double difficulty;
|
||||
|
||||
addrtype = atoi(addrtype_s);
|
||||
if ((addrtype < 0) || (addrtype > 255))
|
||||
return NULL;
|
||||
|
||||
reward = strtod(reward_s, NULL);
|
||||
if (reward < 0.0)
|
||||
return NULL;
|
||||
|
||||
difficulty = vg_prefix_get_difficulty(addrtype, pfx);
|
||||
if (difficulty == 0.0)
|
||||
return NULL;
|
||||
|
||||
pubkey = EC_POINT_hex2point(reqp->group, pubkey_s, NULL, NULL);
|
||||
if (pubkey == NULL)
|
||||
return NULL;
|
||||
|
||||
|
||||
wip = (workitem_t *) malloc(sizeof(*wip) +
|
||||
strlen(pfx) +
|
||||
strlen(comment) + 2);
|
||||
memset(wip, 0, sizeof(*wip));
|
||||
wip->pattern = (char *) (wip + 1);
|
||||
strcpy((char *)wip->pattern, pfx);
|
||||
wip->comment = wip->pattern + (strlen(wip->pattern) + 1);
|
||||
strcpy((char *) wip->comment, comment);
|
||||
wip->pubkey = pubkey;
|
||||
wip->addrtype = addrtype;
|
||||
wip->difficulty = difficulty;
|
||||
wip->reward = reward;
|
||||
wip->value = (reward * 1000000.0 * 3600.0) / difficulty;
|
||||
|
||||
return wip;
|
||||
}
|
||||
|
||||
static int
|
||||
server_workitem_ptr_comp(const void *pa, const void *pb)
|
||||
{
|
||||
workitem_t *a = *(workitem_t **) pa, *b = *(workitem_t **) pb;
|
||||
return (a->value > b->value) ? -1 : ((a->value < b->value) ? 1 : 0);
|
||||
}
|
||||
|
||||
|
||||
typedef struct server_context_s {
|
||||
EC_KEY *dummy_key;
|
||||
const char *url;
|
||||
const char *credit_addr;
|
||||
char *getwork;
|
||||
char *submit;
|
||||
int verbose;
|
||||
} server_context_t;
|
||||
|
||||
static int
|
||||
server_workitem_equal(server_context_t *ctxp, workitem_t *a, workitem_t *b)
|
||||
{
|
||||
if (strcmp(a->pattern, b->pattern))
|
||||
return 0;
|
||||
if (EC_POINT_cmp(EC_KEY_get0_group(ctxp->dummy_key),
|
||||
a->pubkey, b->pubkey, NULL))
|
||||
return 0;
|
||||
return 1;
|
||||
}
|
||||
|
||||
|
||||
void
|
||||
server_context_free(server_context_t *ctxp)
|
||||
{
|
||||
if (ctxp->dummy_key)
|
||||
EC_KEY_free(ctxp->dummy_key);
|
||||
if (ctxp->getwork)
|
||||
free(ctxp->getwork);
|
||||
if (ctxp->submit)
|
||||
free(ctxp->submit);
|
||||
free(ctxp);
|
||||
}
|
||||
|
||||
server_context_t *
|
||||
server_context_new(const char *url, const char *credit_addr)
|
||||
{
|
||||
server_context_t *ctxp;
|
||||
int urllen = strlen(url);
|
||||
int addrlen = strlen(credit_addr);
|
||||
ctxp = (server_context_t *)
|
||||
malloc(sizeof(*ctxp) + urllen + addrlen + 2);
|
||||
memset(ctxp, 0, sizeof(*ctxp));
|
||||
ctxp->url = (const char *) (ctxp + 1);
|
||||
ctxp->credit_addr = (const char *) (ctxp->url + urllen + 1);
|
||||
strcpy((char *) ctxp->url, url);
|
||||
strcpy((char *) ctxp->credit_addr, credit_addr);
|
||||
|
||||
ctxp->dummy_key = vg_exec_context_new_key();
|
||||
ctxp->getwork = (char *) malloc(urllen + 9);
|
||||
ctxp->submit = (char *) malloc(urllen + 7);
|
||||
if (url[urllen - 1] == '/') {
|
||||
snprintf(ctxp->getwork, urllen + 9, "%sgetWork", url);
|
||||
snprintf(ctxp->submit, urllen + 7, "%ssolve", url);
|
||||
} else {
|
||||
snprintf(ctxp->getwork, urllen + 9, "%s/getWork", url);
|
||||
snprintf(ctxp->submit, urllen + 7, "%s/solve", url);
|
||||
}
|
||||
|
||||
return ctxp;
|
||||
}
|
||||
|
||||
|
||||
int
|
||||
server_workitem_add(server_request_t *reqp, workitem_t *wip)
|
||||
{
|
||||
int nalloc;
|
||||
|
||||
if ((reqp->nitems + 1) >= reqp->nalloc) {
|
||||
nalloc = reqp->nalloc * 2;
|
||||
if (nalloc == 0)
|
||||
nalloc = 16;
|
||||
if (nalloc > 65536)
|
||||
return -1;
|
||||
reqp->items = (workitem_t **)
|
||||
realloc(reqp->items, nalloc * sizeof(*reqp->items));
|
||||
if (reqp->items == NULL)
|
||||
return -1;
|
||||
reqp->nalloc = nalloc;
|
||||
}
|
||||
reqp->items[reqp->nitems++] = wip;
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
static int
|
||||
server_body_reader(const char *buf, size_t elemsize, size_t len, void *param)
|
||||
{
|
||||
server_request_t *reqp = (server_request_t *) param;
|
||||
char *line, *sep, *pfx, *pubkey_s, *addrtype_s, *reward_s, *comment;
|
||||
workitem_t *wip;
|
||||
|
||||
if (!len)
|
||||
return 0;
|
||||
|
||||
if ((reqp->part_size < (reqp->part_end + len)) &&
|
||||
(reqp->part_off > 0)) {
|
||||
memmove(reqp->part_buf,
|
||||
reqp->part_buf + reqp->part_off,
|
||||
reqp->part_end - reqp->part_off);
|
||||
reqp->part_end -= reqp->part_off;
|
||||
reqp->part_off = 0;
|
||||
}
|
||||
|
||||
if (reqp->part_size < (reqp->part_end + len)) {
|
||||
if (reqp->part_size == 0)
|
||||
reqp->part_size = 4096;
|
||||
while (reqp->part_size < (reqp->part_end + len)) {
|
||||
reqp->part_size *= 2;
|
||||
if (reqp->part_size > (1024*1024)) {
|
||||
fprintf(stderr, "Line too long from server");
|
||||
reqp->request_status = 0;
|
||||
return -1;
|
||||
}
|
||||
}
|
||||
reqp->part_buf = (char *) realloc(reqp->part_buf,
|
||||
reqp->part_size);
|
||||
if (!reqp->part_buf) {
|
||||
fprintf(stderr, "Out of memory");
|
||||
return -1;
|
||||
}
|
||||
}
|
||||
|
||||
memcpy(reqp->part_buf + reqp->part_end, buf, len);
|
||||
reqp->part_end += len;
|
||||
|
||||
line = reqp->part_buf;
|
||||
while (1) {
|
||||
sep = strchr(line, '\n');
|
||||
if (!sep)
|
||||
break;
|
||||
pfx = line;
|
||||
*sep = '\0';
|
||||
line = sep + 1;
|
||||
sep = strchr(pfx, ':');
|
||||
if (!sep)
|
||||
goto bad_line;
|
||||
*sep = '\0'; sep += 1;
|
||||
pubkey_s = sep;
|
||||
sep = strchr(sep, ':');
|
||||
if (!sep)
|
||||
goto bad_line;
|
||||
*sep = '\0'; sep += 1;
|
||||
addrtype_s = sep;
|
||||
sep = strchr(sep, ':');
|
||||
if (!sep)
|
||||
goto bad_line;
|
||||
*sep = '\0'; sep += 1;
|
||||
reward_s = sep;
|
||||
sep = strchr(sep, ';');
|
||||
if (!sep)
|
||||
goto bad_line;
|
||||
*sep = '\0'; sep += 1;
|
||||
comment = sep;
|
||||
|
||||
wip = server_workitem_new(reqp, pfx, pubkey_s, addrtype_s,
|
||||
reward_s, comment);
|
||||
if (!wip)
|
||||
goto bad_line;
|
||||
if (server_workitem_add(reqp, wip)) {
|
||||
server_workitem_free(wip);
|
||||
goto bad_line;
|
||||
}
|
||||
continue;
|
||||
|
||||
bad_line:
|
||||
;
|
||||
}
|
||||
|
||||
reqp->part_off = line - reqp->part_buf;
|
||||
if (reqp->part_off == reqp->part_end) {
|
||||
reqp->part_off = 0;
|
||||
reqp->part_end = 0;
|
||||
}
|
||||
|
||||
return len;
|
||||
}
|
||||
|
||||
void
|
||||
dump_work(workitem_t **workarray)
|
||||
{
|
||||
workitem_t *wip;
|
||||
int i;
|
||||
printf("Available bounties:\n");
|
||||
for (i = 0; workarray[i] != NULL; i++) {
|
||||
wip = workarray[i];
|
||||
printf("Pattern: \"%s\" Reward: %f Value: %f BTC/MkeyHr\n",
|
||||
wip->pattern,
|
||||
wip->reward,
|
||||
wip->value);
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
free_work_array(workitem_t **workarray, workitem_t *except)
|
||||
{
|
||||
int i;
|
||||
if (workarray) {
|
||||
for (i = 0; workarray[i] != NULL; i++) {
|
||||
if (workarray[i] != except)
|
||||
server_workitem_free(workarray[i]);
|
||||
}
|
||||
free(workarray);
|
||||
}
|
||||
}
|
||||
|
||||
workitem_t **
|
||||
server_context_getwork(server_context_t *ctxp)
|
||||
{
|
||||
CURLcode res;
|
||||
server_request_t *reqp;
|
||||
CURL *creq;
|
||||
|
||||
reqp = (server_request_t *) malloc(sizeof(*reqp));
|
||||
memset(reqp, 0, sizeof(*reqp));
|
||||
|
||||
reqp->group = EC_KEY_get0_group(ctxp->dummy_key);
|
||||
|
||||
creq = curl_easy_init();
|
||||
if (curl_easy_setopt(creq, CURLOPT_URL, ctxp->getwork) ||
|
||||
curl_easy_setopt(creq, CURLOPT_VERBOSE, ctxp->verbose > 1) ||
|
||||
curl_easy_setopt(creq, CURLOPT_WRITEFUNCTION,
|
||||
server_body_reader) ||
|
||||
curl_easy_setopt(creq, CURLOPT_WRITEDATA, reqp)) {
|
||||
fprintf(stderr, "Failed to set up libcurl\n");
|
||||
exit(1);
|
||||
}
|
||||
|
||||
res = curl_easy_perform(creq);
|
||||
if (res != CURLE_OK) {
|
||||
fprintf(stderr, "Get work request failed: %s\n",
|
||||
curl_easy_strerror(res));
|
||||
curl_easy_cleanup(creq);
|
||||
free_work_array(reqp->items, NULL);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
if (reqp->items) {
|
||||
qsort(reqp->items, reqp->nitems, sizeof(*(reqp->items)),
|
||||
server_workitem_ptr_comp);
|
||||
reqp->items[reqp->nitems] = NULL;
|
||||
}
|
||||
|
||||
curl_easy_cleanup(creq);
|
||||
return reqp->items;
|
||||
}
|
||||
|
||||
|
||||
int
|
||||
server_context_submit_solution(server_context_t *ctxp,
|
||||
workitem_t *work,
|
||||
const char *privkey)
|
||||
{
|
||||
char urlbuf[8192];
|
||||
char *pubhex;
|
||||
CURL *creq;
|
||||
CURLcode res;
|
||||
|
||||
pubhex = EC_POINT_point2hex(EC_KEY_get0_group(ctxp->dummy_key),
|
||||
work->pubkey,
|
||||
POINT_CONVERSION_UNCOMPRESSED,
|
||||
NULL);
|
||||
snprintf(urlbuf, sizeof(urlbuf),
|
||||
"%s?key=%s%%3A%s&privateKey=%s&bitcoinAddress=%s",
|
||||
ctxp->submit,
|
||||
work->pattern,
|
||||
pubhex,
|
||||
privkey,
|
||||
ctxp->credit_addr);
|
||||
OPENSSL_free(pubhex);
|
||||
creq = curl_easy_init();
|
||||
if (curl_easy_setopt(creq, CURLOPT_URL, urlbuf) ||
|
||||
curl_easy_setopt(creq, CURLOPT_VERBOSE, ctxp->verbose > 1) ||
|
||||
curl_easy_setopt(creq, CURLOPT_POST, 1)) {
|
||||
fprintf(stderr, "Failed to set up libcurl\n");
|
||||
exit(1);
|
||||
}
|
||||
|
||||
res = curl_easy_perform(creq);
|
||||
if (res != CURLE_OK) {
|
||||
fprintf(stderr, "Submission failed: %s\n",
|
||||
curl_easy_strerror(res));
|
||||
curl_easy_cleanup(creq);
|
||||
return -1;
|
||||
}
|
||||
|
||||
curl_easy_cleanup(creq);
|
||||
return 0;
|
||||
}
|
||||
|
||||
static pthread_mutex_t soln_lock;
|
||||
static pthread_cond_t soln_cond;
|
||||
static char *soln_pattern = NULL;
|
||||
static char *soln_private_key = NULL;
|
||||
|
||||
void
|
||||
free_soln()
|
||||
{
|
||||
if (soln_pattern) {
|
||||
free(soln_pattern);
|
||||
soln_pattern = NULL;
|
||||
}
|
||||
if (soln_private_key) {
|
||||
OPENSSL_free(soln_private_key);
|
||||
soln_private_key = NULL;
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
output_match_work_complete(vg_context_t *vcp, EC_KEY *pkey, const char *pattern)
|
||||
{
|
||||
vg_output_match_console(vcp, pkey, pattern);
|
||||
pthread_mutex_lock(&soln_lock);
|
||||
free_soln();
|
||||
soln_pattern = strdup(pattern);
|
||||
soln_private_key = BN_bn2hex(EC_KEY_get0_private_key(pkey));
|
||||
|
||||
/* Signal the generator to stop */
|
||||
vcp->vc_halt = 1;
|
||||
|
||||
/* Wake up the main thread, if it's sleeping */
|
||||
pthread_cond_broadcast(&soln_cond);
|
||||
pthread_mutex_unlock(&soln_lock);
|
||||
}
|
||||
|
||||
int
|
||||
check_solution(server_context_t *scp, workitem_t *wip)
|
||||
{
|
||||
int res = 0;
|
||||
pthread_mutex_lock(&soln_lock);
|
||||
if (soln_private_key != NULL) {
|
||||
assert(!strcmp(soln_pattern, wip->pattern));
|
||||
server_context_submit_solution(scp, wip, soln_private_key);
|
||||
free_soln();
|
||||
res = 1;
|
||||
}
|
||||
pthread_mutex_unlock(&soln_lock);
|
||||
return res;
|
||||
}
|
||||
|
||||
void
|
||||
usage(const char *name)
|
||||
{
|
||||
fprintf(stderr,
|
||||
"oclVanityMiner %s (" OPENSSL_VERSION_TEXT ")\n"
|
||||
"Usage: %s -u <URL> -a <credit address>\n"
|
||||
"Organized vanity address mining client using OpenCL. Contacts the specified\n"
|
||||
"bounty pool server, downloads a list of active bounties, and attempts to\n"
|
||||
"generate the address with the best difficulty to reward ratio. Maintains\n"
|
||||
"contact with the bounty pool server and periodically refreshes the bounty\n"
|
||||
"list.\n"
|
||||
"\n"
|
||||
"Options:\n"
|
||||
"-u <URL> Bounty pool URL\n"
|
||||
"-a <address> Credit address for completed work\n"
|
||||
"-i <interval> Set server polling interval in seconds (default 90)\n"
|
||||
"-v Verbose output\n"
|
||||
"-q Quiet output\n"
|
||||
"-p <platform> Select OpenCL platform\n"
|
||||
"-d <device> Select OpenCL device\n"
|
||||
"-S Safe mode, disable OpenCL loop unrolling optimizations\n"
|
||||
"-w <worksize> Set work items per thread in a work unit\n"
|
||||
"-t <threads> Set target thread count per multiprocessor\n"
|
||||
"-g <x>x<y> Set grid size\n"
|
||||
"-b <invsize> Set modular inverse ops per thread\n"
|
||||
"-V Enable kernel/OpenCL/hardware verification (SLOW)\n",
|
||||
version, name);
|
||||
}
|
||||
|
||||
|
||||
int
|
||||
main(int argc, char **argv)
|
||||
{
|
||||
const char *url = NULL;
|
||||
const char *credit_addr = NULL;
|
||||
int opt;
|
||||
int platformidx = -1, deviceidx = -1;
|
||||
char *pend;
|
||||
int verbose = 1;
|
||||
int interval = 90;
|
||||
int nthreads = 0;
|
||||
int worksize = 0;
|
||||
int nrows = 0, ncols = 0;
|
||||
int invsize = 0;
|
||||
int verify_mode = 0;
|
||||
int safe_mode = 0;
|
||||
vg_context_t *vcp = NULL;
|
||||
vg_ocl_context_t *vocp = NULL;
|
||||
|
||||
int res;
|
||||
int thread_started = 0;
|
||||
pthread_t thread;
|
||||
workitem_t *active_wip = NULL;
|
||||
|
||||
server_context_t *scp = NULL;
|
||||
workitem_t *wip = NULL, **wipa;
|
||||
int wip_index;
|
||||
int was_sleeping = 0;
|
||||
|
||||
struct timeval tv;
|
||||
struct timespec sleepy;
|
||||
|
||||
pthread_mutex_init(&soln_lock, NULL);
|
||||
pthread_cond_init(&soln_cond, NULL);
|
||||
|
||||
if (argc == 1) {
|
||||
usage(argv[0]);
|
||||
return 1;
|
||||
}
|
||||
|
||||
while ((opt = getopt(argc, argv,
|
||||
"u:a:vqp:d:w:t:g:b:VSh?i:")) != -1) {
|
||||
switch (opt) {
|
||||
case 'u':
|
||||
url = optarg;
|
||||
break;
|
||||
case 'a':
|
||||
credit_addr = optarg;
|
||||
break;
|
||||
case 'v':
|
||||
verbose = 2;
|
||||
break;
|
||||
case 'q':
|
||||
verbose = 0;
|
||||
break;
|
||||
case 'i':
|
||||
interval = atoi(optarg);
|
||||
if (interval < 60) {
|
||||
fprintf(stderr,
|
||||
"Invalid interval '%s'\n", optarg);
|
||||
return 1;
|
||||
}
|
||||
case 'p':
|
||||
platformidx = atoi(optarg);
|
||||
break;
|
||||
case 'd':
|
||||
deviceidx = atoi(optarg);
|
||||
break;
|
||||
case 'w':
|
||||
worksize = atoi(optarg);
|
||||
if (worksize == 0) {
|
||||
fprintf(stderr,
|
||||
"Invalid work size '%s'\n", optarg);
|
||||
return 1;
|
||||
}
|
||||
break;
|
||||
case 't':
|
||||
nthreads = atoi(optarg);
|
||||
if (nthreads == 0) {
|
||||
fprintf(stderr,
|
||||
"Invalid thread count '%s'\n", optarg);
|
||||
return 1;
|
||||
}
|
||||
break;
|
||||
case 'g':
|
||||
nrows = 0;
|
||||
ncols = strtol(optarg, &pend, 0);
|
||||
if (pend && *pend == 'x') {
|
||||
nrows = strtol(pend+1, NULL, 0);
|
||||
}
|
||||
if (!nrows || !ncols) {
|
||||
fprintf(stderr,
|
||||
"Invalid grid size '%s'\n", optarg);
|
||||
return 1;
|
||||
}
|
||||
break;
|
||||
case 'b':
|
||||
invsize = atoi(optarg);
|
||||
if (!invsize) {
|
||||
fprintf(stderr,
|
||||
"Invalid modular inverse size '%s'\n",
|
||||
optarg);
|
||||
return 1;
|
||||
}
|
||||
if (invsize & (invsize - 1)) {
|
||||
fprintf(stderr,
|
||||
"Modular inverse size must be "
|
||||
"a power of 2\n");
|
||||
return 1;
|
||||
}
|
||||
break;
|
||||
case 'V':
|
||||
verify_mode = 1;
|
||||
break;
|
||||
case 'S':
|
||||
safe_mode = 1;
|
||||
break;
|
||||
default:
|
||||
usage(argv[0]);
|
||||
return 1;
|
||||
}
|
||||
}
|
||||
|
||||
#if OPENSSL_VERSION_NUMBER < 0x10000000L
|
||||
/* Complain about older versions of OpenSSL */
|
||||
if (verbose > 0) {
|
||||
fprintf(stderr,
|
||||
"WARNING: Built with " OPENSSL_VERSION_TEXT "\n"
|
||||
"WARNING: Use OpenSSL 1.0.0d+ for best performance\n");
|
||||
}
|
||||
#endif
|
||||
curl_easy_init();
|
||||
|
||||
vcp = vg_prefix_context_new(0, 128, 0);
|
||||
|
||||
vcp->vc_verbose = verbose;
|
||||
|
||||
vcp->vc_output_match = output_match_work_complete;
|
||||
vcp->vc_output_timing = vg_output_timing_console;
|
||||
|
||||
|
||||
if (!url) {
|
||||
fprintf(stderr, "ERROR: No server URL specified\n");
|
||||
return 1;
|
||||
}
|
||||
if (!credit_addr) {
|
||||
fprintf(stderr, "ERROR: No reward address specified\n");
|
||||
return 1;
|
||||
}
|
||||
if (!vg_b58_decode_check(credit_addr, NULL, 0)) {
|
||||
fprintf(stderr, "ERROR: Invalid reward address specified\n");
|
||||
return 1;
|
||||
}
|
||||
|
||||
scp = server_context_new(url, credit_addr);
|
||||
scp->verbose = verbose;
|
||||
wipa = NULL;
|
||||
|
||||
while (1) {
|
||||
if (!wipa) {
|
||||
wipa = server_context_getwork(scp);
|
||||
wip_index = 0;
|
||||
}
|
||||
|
||||
if (wipa) {
|
||||
wip = wipa[wip_index];
|
||||
if (wip)
|
||||
wip_index += 1;
|
||||
} else
|
||||
wip = NULL;
|
||||
|
||||
/* If the work item is the same as the one we're executing,
|
||||
keep it */
|
||||
if (wip && active_wip &&
|
||||
server_workitem_equal(scp, active_wip, wip))
|
||||
wip = active_wip;
|
||||
|
||||
if (thread_started && (!active_wip || (wip != active_wip))) {
|
||||
/* If a thread is running, stop it */
|
||||
vcp->vc_halt = 1;
|
||||
pthread_join(thread, NULL);
|
||||
thread_started = 0;
|
||||
vcp->vc_halt = 0;
|
||||
if (active_wip) {
|
||||
check_solution(scp, active_wip);
|
||||
active_wip = NULL;
|
||||
}
|
||||
vg_context_clear_all_patterns(vcp);
|
||||
}
|
||||
|
||||
if (!wip) {
|
||||
if (!was_sleeping) {
|
||||
fprintf(stderr,
|
||||
"No work available, sleeping\n");
|
||||
was_sleeping = 1;
|
||||
}
|
||||
|
||||
} else if (!active_wip) {
|
||||
was_sleeping = 0;
|
||||
fprintf(stderr,
|
||||
"Searching for pattern: \"%s\" "
|
||||
"Reward: %f Value: %f BTC/MkeyHr\n",
|
||||
wip->pattern,
|
||||
wip->reward,
|
||||
wip->value);
|
||||
vcp->vc_addrtype = wip->addrtype;
|
||||
vcp->vc_pubkey_base = wip->pubkey;
|
||||
if (!vg_context_add_patterns(vcp, &wip->pattern, 1))
|
||||
return 1;
|
||||
assert(vcp->vc_npatterns);
|
||||
|
||||
if (!vocp) {
|
||||
vocp = vg_ocl_context_new(vcp,
|
||||
platformidx, deviceidx,
|
||||
safe_mode, verify_mode,
|
||||
worksize, nthreads, nrows,
|
||||
ncols, invsize);
|
||||
if (!vocp)
|
||||
return 1;
|
||||
}
|
||||
|
||||
res = pthread_create(&thread, NULL,
|
||||
vg_opencl_loop, vocp);
|
||||
thread_started = 1;
|
||||
active_wip = wip;
|
||||
}
|
||||
|
||||
/* Wait for something to happen */
|
||||
gettimeofday(&tv, NULL);
|
||||
sleepy.tv_sec = tv.tv_sec;
|
||||
sleepy.tv_nsec = tv.tv_usec * 1000;
|
||||
sleepy.tv_sec += interval;
|
||||
|
||||
pthread_mutex_lock(&soln_lock);
|
||||
if (!soln_private_key)
|
||||
res = pthread_cond_timedwait(&soln_cond,
|
||||
&soln_lock, &sleepy);
|
||||
pthread_mutex_unlock(&soln_lock);
|
||||
|
||||
if (res == 0) {
|
||||
if (check_solution(scp, active_wip))
|
||||
active_wip = NULL;
|
||||
}
|
||||
else if (res == ETIMEDOUT) {
|
||||
if (wipa) {
|
||||
free_work_array(wipa, active_wip);
|
||||
wipa = NULL;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
169
pattern.c
169
pattern.c
@ -141,20 +141,13 @@ typedef struct _timing_info_s {
|
||||
int
|
||||
vg_output_timing(vg_context_t *vcp, int cycle, struct timeval *last)
|
||||
{
|
||||
static unsigned long long total = 0, prevfound = 0, sincelast = 0;
|
||||
static pthread_mutex_t mutex = PTHREAD_MUTEX_INITIALIZER;
|
||||
static timing_info_t *timing_head = NULL;
|
||||
|
||||
pthread_t me;
|
||||
struct timeval tvnow, tv;
|
||||
timing_info_t *tip, *mytip;
|
||||
unsigned long long rate, myrate = 0, mytime;
|
||||
double count, prob, time, targ;
|
||||
char linebuf[80];
|
||||
char *unit;
|
||||
int rem, p, i;
|
||||
|
||||
const double targs[] = { 0.5, 0.75, 0.8, 0.9, 0.95, 1.0 };
|
||||
unsigned long long rate, myrate = 0, mytime, total, sincelast;
|
||||
int p, i;
|
||||
|
||||
/* Compute the rate */
|
||||
gettimeofday(&tvnow, NULL);
|
||||
@ -167,7 +160,8 @@ vg_output_timing(vg_context_t *vcp, int cycle, struct timeval *last)
|
||||
|
||||
pthread_mutex_lock(&mutex);
|
||||
me = pthread_self();
|
||||
for (tip = timing_head, mytip = NULL; tip != NULL; tip = tip->ti_next) {
|
||||
for (tip = vcp->vc_timing_head, mytip = NULL;
|
||||
tip != NULL; tip = tip->ti_next) {
|
||||
if (pthread_equal(tip->ti_thread, me)) {
|
||||
mytip = tip;
|
||||
p = ((tip->ti_hist_last + 1) % timing_hist_size);
|
||||
@ -190,9 +184,9 @@ vg_output_timing(vg_context_t *vcp, int cycle, struct timeval *last)
|
||||
}
|
||||
if (!mytip) {
|
||||
mytip = (timing_info_t *) malloc(sizeof(*tip));
|
||||
mytip->ti_next = timing_head;
|
||||
mytip->ti_next = vcp->vc_timing_head;
|
||||
mytip->ti_thread = me;
|
||||
timing_head = mytip;
|
||||
vcp->vc_timing_head = mytip;
|
||||
mytip->ti_hist_last = 0;
|
||||
mytip->ti_hist_time[0] = mytime;
|
||||
mytip->ti_hist_work[0] = cycle;
|
||||
@ -205,20 +199,47 @@ vg_output_timing(vg_context_t *vcp, int cycle, struct timeval *last)
|
||||
rate += myrate;
|
||||
}
|
||||
|
||||
total += cycle;
|
||||
if (prevfound != vcp->vc_found) {
|
||||
prevfound = vcp->vc_found;
|
||||
sincelast = 0;
|
||||
vcp->vc_timing_total += cycle;
|
||||
if (vcp->vc_timing_prevfound != vcp->vc_found) {
|
||||
vcp->vc_timing_prevfound = vcp->vc_found;
|
||||
vcp->vc_timing_sincelast = 0;
|
||||
}
|
||||
sincelast += cycle;
|
||||
count = sincelast;
|
||||
vcp->vc_timing_sincelast += cycle;
|
||||
|
||||
if (mytip != timing_head) {
|
||||
if (mytip != vcp->vc_timing_head) {
|
||||
pthread_mutex_unlock(&mutex);
|
||||
return myrate;
|
||||
}
|
||||
total = vcp->vc_timing_total;
|
||||
sincelast = vcp->vc_timing_sincelast;
|
||||
pthread_mutex_unlock(&mutex);
|
||||
|
||||
vcp->vc_output_timing(vcp, sincelast, rate, total);
|
||||
return myrate;
|
||||
}
|
||||
|
||||
static void
|
||||
vg_timing_info_free(vg_context_t *vcp)
|
||||
{
|
||||
timing_info_t *tp;
|
||||
while (vcp->vc_timing_head != NULL) {
|
||||
tp = vcp->vc_timing_head;
|
||||
vcp->vc_timing_head = tp->ti_next;
|
||||
free(tp);
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
vg_output_timing_console(vg_context_t *vcp, double count,
|
||||
unsigned long long rate, unsigned long long total)
|
||||
{
|
||||
double prob, time, targ;
|
||||
char *unit;
|
||||
char linebuf[80];
|
||||
int rem, p, i;
|
||||
|
||||
const double targs[] = { 0.5, 0.75, 0.8, 0.9, 0.95, 1.0 };
|
||||
|
||||
targ = rate;
|
||||
unit = "key/s";
|
||||
if (targ > 1000) {
|
||||
@ -314,11 +335,10 @@ vg_output_timing(vg_context_t *vcp, int cycle, struct timeval *last)
|
||||
}
|
||||
printf("\r%s", linebuf);
|
||||
fflush(stdout);
|
||||
return myrate;
|
||||
}
|
||||
|
||||
void
|
||||
vg_output_match(vg_context_t *vcp, EC_KEY *pkey, const char *pattern)
|
||||
vg_output_match_console(vg_context_t *vcp, EC_KEY *pkey, const char *pattern)
|
||||
{
|
||||
unsigned char key_buf[512], *pend;
|
||||
char addr_buf[64], addr2_buf[64];
|
||||
@ -386,6 +406,7 @@ vg_output_match(vg_context_t *vcp, EC_KEY *pkey, const char *pattern)
|
||||
printf("Privkey (ASN1): ");
|
||||
dumphex(key_buf, len);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
if (!vcp->vc_result_file || (vcp->vc_verbose > 0)) {
|
||||
@ -420,20 +441,26 @@ vg_output_match(vg_context_t *vcp, EC_KEY *pkey, const char *pattern)
|
||||
}
|
||||
|
||||
|
||||
|
||||
void
|
||||
vg_context_free(vg_context_t *vcp)
|
||||
{
|
||||
vg_timing_info_free(vcp);
|
||||
vcp->vc_free(vcp);
|
||||
}
|
||||
|
||||
int
|
||||
vg_context_add_patterns(vg_context_t *vcp,
|
||||
char ** const patterns, int npatterns)
|
||||
const char ** const patterns, int npatterns)
|
||||
{
|
||||
return vcp->vc_add_patterns(vcp, patterns, npatterns);
|
||||
}
|
||||
|
||||
void
|
||||
vg_context_clear_all_patterns(vg_context_t *vcp)
|
||||
{
|
||||
vcp->vc_clear_all_patterns(vcp);
|
||||
}
|
||||
|
||||
int
|
||||
vg_context_hash160_sort(vg_context_t *vcp, void *buf)
|
||||
{
|
||||
@ -699,6 +726,21 @@ out:
|
||||
return ret;
|
||||
}
|
||||
|
||||
static void
|
||||
free_ranges(BIGNUM **ranges)
|
||||
{
|
||||
BN_free(ranges[0]);
|
||||
BN_free(ranges[1]);
|
||||
ranges[0] = NULL;
|
||||
ranges[1] = NULL;
|
||||
if (ranges[2]) {
|
||||
BN_free(ranges[2]);
|
||||
BN_free(ranges[3]);
|
||||
ranges[2] = NULL;
|
||||
ranges[3] = NULL;
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
* AVL tree implementation
|
||||
*/
|
||||
@ -1364,7 +1406,7 @@ typedef struct _vg_prefix_context_s {
|
||||
} vg_prefix_context_t;
|
||||
|
||||
static void
|
||||
vg_prefix_context_free(vg_context_t *vcp)
|
||||
vg_prefix_context_clear_all_patterns(vg_context_t *vcp)
|
||||
{
|
||||
vg_prefix_context_t *vcpp = (vg_prefix_context_t *) vcp;
|
||||
vg_prefix_t *vp;
|
||||
@ -1378,6 +1420,17 @@ vg_prefix_context_free(vg_context_t *vcp)
|
||||
}
|
||||
|
||||
assert(npfx_left == vcpp->base.vc_npatterns);
|
||||
vcpp->base.vc_npatterns = 0;
|
||||
vcpp->base.vc_npatterns_start = 0;
|
||||
vcpp->base.vc_found = 0;
|
||||
BN_clear(&vcpp->vcp_difficulty);
|
||||
}
|
||||
|
||||
static void
|
||||
vg_prefix_context_free(vg_context_t *vcp)
|
||||
{
|
||||
vg_prefix_context_t *vcpp = (vg_prefix_context_t *) vcp;
|
||||
vg_prefix_context_clear_all_patterns(vcp);
|
||||
BN_clear_free(&vcpp->vcp_difficulty);
|
||||
free(vcpp);
|
||||
}
|
||||
@ -1407,7 +1460,7 @@ vg_prefix_context_next_difficulty(vg_prefix_context_t *vcpp,
|
||||
|
||||
static int
|
||||
vg_prefix_context_add_patterns(vg_context_t *vcp,
|
||||
char ** const patterns, int npatterns)
|
||||
const char ** const patterns, int npatterns)
|
||||
{
|
||||
vg_prefix_context_t *vcpp = (vg_prefix_context_t *) vcp;
|
||||
prefix_case_iter_t caseiter;
|
||||
@ -1556,6 +1609,47 @@ vg_prefix_context_add_patterns(vg_context_t *vcp,
|
||||
return ret;
|
||||
}
|
||||
|
||||
double
|
||||
vg_prefix_get_difficulty(int addrtype, const char *pattern)
|
||||
{
|
||||
BN_CTX *bnctx;
|
||||
BIGNUM result, bntmp;
|
||||
BIGNUM *ranges[4];
|
||||
char *dbuf;
|
||||
int ret;
|
||||
double diffret = 0.0;
|
||||
|
||||
bnctx = BN_CTX_new();
|
||||
BN_init(&result);
|
||||
BN_init(&bntmp);
|
||||
|
||||
ret = get_prefix_ranges(addrtype,
|
||||
pattern, ranges, bnctx);
|
||||
|
||||
if (ret == 0) {
|
||||
BN_sub(&bntmp, ranges[1], ranges[0]);
|
||||
BN_add(&result, &result, &bntmp);
|
||||
if (ranges[2]) {
|
||||
BN_sub(&bntmp, ranges[3], ranges[2]);
|
||||
BN_add(&result, &result, &bntmp);
|
||||
}
|
||||
free_ranges(ranges);
|
||||
|
||||
BN_clear(&bntmp);
|
||||
BN_set_bit(&bntmp, 192);
|
||||
BN_div(&result, NULL, &bntmp, &result, bnctx);
|
||||
|
||||
dbuf = BN_bn2dec(&result);
|
||||
diffret = strtod(dbuf, NULL);
|
||||
OPENSSL_free(dbuf);
|
||||
}
|
||||
|
||||
BN_clear_free(&result);
|
||||
BN_clear_free(&bntmp);
|
||||
BN_CTX_free(bnctx);
|
||||
return diffret;
|
||||
}
|
||||
|
||||
|
||||
static int
|
||||
vg_prefix_test(vg_exec_context_t *vxcp)
|
||||
@ -1579,7 +1673,8 @@ research:
|
||||
goto research;
|
||||
|
||||
vg_exec_context_consolidate_key(vxcp);
|
||||
vg_output_match(&vcpp->base, vxcp->vxc_key, vp->vp_pattern);
|
||||
vcpp->base.vc_output_match(&vcpp->base, vxcp->vxc_key,
|
||||
vp->vp_pattern);
|
||||
|
||||
vcpp->base.vc_found++;
|
||||
|
||||
@ -1673,6 +1768,8 @@ vg_prefix_context_new(int addrtype, int privtype, int caseinsensitive)
|
||||
vcpp->base.vc_chance = 0.0;
|
||||
vcpp->base.vc_free = vg_prefix_context_free;
|
||||
vcpp->base.vc_add_patterns = vg_prefix_context_add_patterns;
|
||||
vcpp->base.vc_clear_all_patterns =
|
||||
vg_prefix_context_clear_all_patterns;
|
||||
vcpp->base.vc_test = vg_prefix_test;
|
||||
vcpp->base.vc_hash160_sort = vg_prefix_hash160_sort;
|
||||
avl_root_init(&vcpp->vcp_avlroot);
|
||||
@ -1695,7 +1792,7 @@ typedef struct _vg_regex_context_s {
|
||||
|
||||
static int
|
||||
vg_regex_context_add_patterns(vg_context_t *vcp,
|
||||
char ** const patterns, int npatterns)
|
||||
const char ** const patterns, int npatterns)
|
||||
{
|
||||
vg_regex_context_t *vcrp = (vg_regex_context_t *) vcp;
|
||||
const char *pcre_errptr;
|
||||
@ -1770,7 +1867,7 @@ vg_regex_context_add_patterns(vg_context_t *vcp,
|
||||
}
|
||||
|
||||
static void
|
||||
vg_regex_context_free(vg_context_t *vcp)
|
||||
vg_regex_context_clear_all_patterns(vg_context_t *vcp)
|
||||
{
|
||||
vg_regex_context_t *vcrp = (vg_regex_context_t *) vcp;
|
||||
int i;
|
||||
@ -1779,6 +1876,16 @@ vg_regex_context_free(vg_context_t *vcp)
|
||||
pcre_free(vcrp->vcr_regex_extra[i]);
|
||||
pcre_free(vcrp->vcr_regex[i]);
|
||||
}
|
||||
vcrp->base.vc_npatterns = 0;
|
||||
vcrp->base.vc_npatterns_start = 0;
|
||||
vcrp->base.vc_found = 0;
|
||||
}
|
||||
|
||||
static void
|
||||
vg_regex_context_free(vg_context_t *vcp)
|
||||
{
|
||||
vg_regex_context_t *vcrp = (vg_regex_context_t *) vcp;
|
||||
vg_regex_context_clear_all_patterns(vcp);
|
||||
if (vcrp->vcr_nalloc)
|
||||
free(vcrp->vcr_regex);
|
||||
free(vcrp);
|
||||
@ -1860,8 +1967,8 @@ restart_loop:
|
||||
goto restart_loop;
|
||||
|
||||
vg_exec_context_consolidate_key(vxcp);
|
||||
vg_output_match(&vcrp->base, vxcp->vxc_key,
|
||||
vcrp->vcr_regex_pat[i]);
|
||||
vcrp->base.vc_output_match(&vcrp->base, vxcp->vxc_key,
|
||||
vcrp->vcr_regex_pat[i]);
|
||||
vcrp->base.vc_found++;
|
||||
|
||||
if (vcrp->base.vc_remove_on_match) {
|
||||
@ -1902,6 +2009,8 @@ vg_regex_context_new(int addrtype, int privtype)
|
||||
vcrp->base.vc_chance = 0.0;
|
||||
vcrp->base.vc_free = vg_regex_context_free;
|
||||
vcrp->base.vc_add_patterns = vg_regex_context_add_patterns;
|
||||
vcrp->base.vc_clear_all_patterns =
|
||||
vg_regex_context_clear_all_patterns;
|
||||
vcrp->base.vc_test = vg_regex_test;
|
||||
vcrp->base.vc_hash160_sort = NULL;
|
||||
vcrp->vcr_regex = NULL;
|
||||
|
48
pattern.h
48
pattern.h
@ -56,16 +56,24 @@ extern void vg_exec_context_consolidate_key(vg_exec_context_t *vxcp);
|
||||
extern void vg_exec_context_calc_address(vg_exec_context_t *vxcp);
|
||||
extern EC_KEY *vg_exec_context_new_key(void);
|
||||
|
||||
|
||||
/* Implementation-specific lock/unlock/consolidate */
|
||||
extern void vg_exec_downgrade_lock(vg_exec_context_t *vxcp);
|
||||
extern int vg_exec_upgrade_lock(vg_exec_context_t *vxcp);
|
||||
|
||||
|
||||
typedef void (*vg_free_func_t)(vg_context_t *);
|
||||
typedef int (*vg_add_pattern_func_t)(vg_context_t *,
|
||||
char ** const patterns, int npatterns);
|
||||
const char ** const patterns,
|
||||
int npatterns);
|
||||
typedef void (*vg_clear_all_patterns_func_t)(vg_context_t *);
|
||||
typedef int (*vg_test_func_t)(vg_exec_context_t *);
|
||||
typedef int (*vg_hash160_sort_func_t)(vg_context_t *vcp, void *buf);
|
||||
typedef void (*vg_output_error_func_t)(vg_context_t *vcp, const char *info);
|
||||
typedef void (*vg_output_match_func_t)(vg_context_t *vcp, EC_KEY *pkey,
|
||||
const char *pattern);
|
||||
typedef void (*vg_output_timing_func_t)(vg_context_t *vcp, double count,
|
||||
unsigned long long rate,
|
||||
unsigned long long total);
|
||||
|
||||
enum vg_format {
|
||||
VCF_PUBKEY,
|
||||
@ -84,28 +92,50 @@ struct _vg_context_s {
|
||||
const char *vc_key_protect_pass;
|
||||
int vc_remove_on_match;
|
||||
int vc_verbose;
|
||||
vg_free_func_t vc_free;
|
||||
vg_add_pattern_func_t vc_add_patterns;
|
||||
vg_test_func_t vc_test;
|
||||
vg_hash160_sort_func_t vc_hash160_sort;
|
||||
enum vg_format vc_format;
|
||||
int vc_pubkeytype;
|
||||
EC_POINT *vc_pubkey_base;
|
||||
int vc_halt;
|
||||
|
||||
/* Internal methods */
|
||||
vg_free_func_t vc_free;
|
||||
vg_add_pattern_func_t vc_add_patterns;
|
||||
vg_clear_all_patterns_func_t vc_clear_all_patterns;
|
||||
vg_test_func_t vc_test;
|
||||
vg_hash160_sort_func_t vc_hash160_sort;
|
||||
|
||||
/* Performance related members */
|
||||
unsigned long long vc_timing_total;
|
||||
unsigned long long vc_timing_prevfound;
|
||||
unsigned long long vc_timing_sincelast;
|
||||
struct _timing_info_s *vc_timing_head;
|
||||
|
||||
/* External methods */
|
||||
vg_output_error_func_t vc_output_error;
|
||||
vg_output_match_func_t vc_output_match;
|
||||
vg_output_timing_func_t vc_output_timing;
|
||||
};
|
||||
|
||||
|
||||
extern void vg_context_free(vg_context_t *vcp);
|
||||
extern int vg_context_add_patterns(vg_context_t *vcp,
|
||||
char ** const patterns, int npatterns);
|
||||
const char ** const patterns, int npatterns);
|
||||
extern void vg_context_clear_all_patterns(vg_context_t *vcp);
|
||||
extern int vg_context_hash160_sort(vg_context_t *vcp, void *buf);
|
||||
|
||||
|
||||
extern vg_context_t *vg_prefix_context_new(int addrtype, int privtype,
|
||||
int caseinsensitive);
|
||||
extern double vg_prefix_get_difficulty(int addrtype, const char *pattern);
|
||||
|
||||
extern vg_context_t *vg_regex_context_new(int addrtype, int privtype);
|
||||
|
||||
extern int vg_output_timing(vg_context_t *vcp, int cycle, struct timeval *last);
|
||||
extern void vg_output_match(vg_context_t *vcp, EC_KEY *pkey,
|
||||
const char *pattern);
|
||||
|
||||
extern void vg_output_match_console(vg_context_t *vcp, EC_KEY *pkey,
|
||||
const char *pattern);
|
||||
extern void vg_output_timing_console(vg_context_t *vcp, double count,
|
||||
unsigned long long rate,
|
||||
unsigned long long total);
|
||||
|
||||
#endif /* !defined (__VG_PATTERN_H__) */
|
||||
|
@ -280,7 +280,7 @@ vg_thread_loop(void *arg)
|
||||
hash_len = 65;
|
||||
}
|
||||
|
||||
while (1) {
|
||||
while (!vcp->vc_halt) {
|
||||
if (++npoints >= rekey_at) {
|
||||
pthread_mutex_lock(&vg_thread_lock);
|
||||
/* Generate a new random private key */
|
||||
@ -704,7 +704,11 @@ main(int argc, char **argv)
|
||||
vcp->vc_pubkeytype = pubkeytype;
|
||||
vcp->vc_pubkey_base = pubkey_base;
|
||||
|
||||
if (!vg_context_add_patterns(vcp, patterns, npatterns))
|
||||
vcp->vc_output_match = vg_output_match_console;
|
||||
vcp->vc_output_timing = vg_output_timing_console;
|
||||
|
||||
if (!vg_context_add_patterns(vcp, (const char ** const) patterns,
|
||||
npatterns))
|
||||
return 1;
|
||||
|
||||
if (!vcp->vc_npatterns) {
|
||||
|
23
winglue.c
23
winglue.c
@ -73,11 +73,9 @@ count_processors(void)
|
||||
* struct timeval compatibility for Win32
|
||||
*/
|
||||
|
||||
#if defined(_MSC_VER) || defined(_MSC_EXTENSIONS)
|
||||
#define DELTA_EPOCH_IN_MICROSECS 11644473600000000Ui64
|
||||
#else
|
||||
#define DELTA_EPOCH_IN_MICROSECS 11644473600000000ULL
|
||||
#endif
|
||||
#define TIMESPEC_TO_FILETIME_OFFSET \
|
||||
( ((unsigned __int64) 27111902 << 32) + \
|
||||
(unsigned __int64) 3577643008 )
|
||||
|
||||
int
|
||||
gettimeofday(struct timeval *tv, struct timezone *tz)
|
||||
@ -88,14 +86,13 @@ gettimeofday(struct timeval *tv, struct timezone *tz)
|
||||
if (NULL != tv) {
|
||||
GetSystemTimeAsFileTime(&ft);
|
||||
|
||||
tmpres |= ft.dwHighDateTime;
|
||||
tmpres <<= 32;
|
||||
tmpres |= ft.dwLowDateTime;
|
||||
|
||||
tmpres -= DELTA_EPOCH_IN_MICROSECS;
|
||||
tmpres /= 10;
|
||||
tv->tv_sec = (long)(tmpres / 1000000UL);
|
||||
tv->tv_usec = (long)(tmpres % 1000000UL);
|
||||
tv->tv_sec = (int) ((*(unsigned __int64 *) &ft -
|
||||
TIMESPEC_TO_FILETIME_OFFSET) /
|
||||
10000000);
|
||||
tv->tv_usec = (int) ((*(unsigned __int64 *) &ft -
|
||||
TIMESPEC_TO_FILETIME_OFFSET -
|
||||
((unsigned __int64) tv->tv_sec *
|
||||
(unsigned __int64) 10000000)) / 10);
|
||||
}
|
||||
|
||||
return 0;
|
||||
|
Loading…
x
Reference in New Issue
Block a user