Browse Source

Add oclvanityminer. Move OpenCL engine code to oclengine.c.

master
samr7 12 years ago
parent
commit
4700be088f
  1. 11
      Makefile
  2. 31
      Makefile.Win32
  3. 18
      keyconv.c
  4. 2591
      oclengine.c
  5. 35
      oclengine.h
  6. 2534
      oclvanitygen.c
  7. 748
      oclvanityminer.c
  8. 169
      pattern.c
  9. 48
      pattern.h
  10. 8
      vanitygen.c
  11. 23
      winglue.c

11
Makefile

@ -1,16 +1,21 @@
LIBS=-lpcre -lcrypto -lm -lpthread LIBS=-lpcre -lcrypto -lm -lpthread
CFLAGS=-ggdb -O3 -Wall CFLAGS=-ggdb -O3 -Wall
OBJS=vanitygen.o oclvanitygen.o keyconv.o pattern.o util.o OBJS=vanitygen.o oclvanitygen.o oclvanityminer.o oclengine.o keyconv.o pattern.o util.o
PROGS=vanitygen keyconv PROGS=vanitygen oclvanitygen oclvanityminer keyconv
most: vanitygen keyconv
all: $(PROGS) all: $(PROGS)
vanitygen: vanitygen.o pattern.o util.o vanitygen: vanitygen.o pattern.o util.o
$(CC) $^ -o $@ $(CFLAGS) $(LIBS) $(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 $(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 keyconv: keyconv.o util.o
$(CC) $^ -o $@ $(CFLAGS) $(LIBS) $(CC) $^ -o $@ $(CFLAGS) $(LIBS)

31
Makefile.Win32

@ -2,29 +2,42 @@ CC = cl
OPENSSL_DIR = C:\OpenSSL-Win32 OPENSSL_DIR = C:\OpenSSL-Win32
PTHREADS_DIR = C:\pthreads-w32-2-8-0-release PTHREADS_DIR = C:\pthreads-w32-2-8-0-release
PCRE_DIR = C:\pcre-7.9-src 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_DIR = "C:\Program Files (x86)\AMD APP"
OPENCL_INCLUDE = /I$(OPENCL_DIR)\include OPENCL_INCLUDE = /I$(OPENCL_DIR)\include
OPENCL_LIBS = $(OPENCL_DIR)\lib\x86\OpenCL.lib 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) CURL_INCLUDE = /I$(CURL_DIR)\include /DCURL_STATICLIB
LIBS = $(OPENSSL_DIR)\lib\libeay32.lib $(PTHREADS_DIR)\pthreadVC2.lib $(PCRE_DIR)\pcre.lib ws2_32.lib CURL_LIBS = $(CURL_DIR)\lib\libcurl_a.lib
OBJS = vanitygen.obj oclvanitygen.obj keyconv.obj pattern.obj util.obj winglue.obj 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 vanitygen.exe: vanitygen.obj pattern.obj util.obj winglue.obj
link /nologo /out:$@ $** $(LIBS) link /nologo /out:$@ $** $(LIBS)
oclvanitygen.exe: oclvanitygen.obj pattern.obj util.obj winglue.obj oclvanitygen.exe: oclvanitygen.obj oclengine.obj pattern.obj util.obj winglue.obj
link /nologo /out:$@ $** $(LIBS) $(OPENCL_LIBS) 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 keyconv.exe: keyconv.obj util.obj winglue.obj
link /nologo /out:$@ $** $(LIBS) $(OPENCL_LIBS) link /nologo /out:$@ $** $(LIBS)
.c.obj: .c.obj:
@$(CC) /nologo $(CFLAGS) /c /Tp$< /Fo$@ @$(CC) /nologo $(CFLAGS) /c /Tp$< /Fo$@
oclengine.obj: oclengine.c
@$(CC) /nologo $(CFLAGS_BASE) $(OPENCL_INCLUDE) /c /Tpoclengine.c /Fo$@
oclvanitygen.obj: oclvanitygen.c 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: clean:
del vanitygen.exe $(OBJS) del vanitygen.exe oclvanitygen.exe oclvanityminer.exe keyconv.exe $(OBJS)

18
keyconv.c

@ -28,7 +28,8 @@ usage(const char *progname)
"-8 Output key in PKCS#8 form\n" "-8 Output key in PKCS#8 form\n"
"-e Encrypt output key, prompt for password\n" "-e Encrypt output key, prompt for password\n"
"-E <password> Encrypt output key with <password> (UNSAFE)\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); version, progname);
} }
@ -47,10 +48,11 @@ main(int argc, char **argv)
int privtype, addrtype; int privtype, addrtype;
int pkcs8 = 0; int pkcs8 = 0;
int pass_prompt = 0; int pass_prompt = 0;
int verbose = 0;
int opt; int opt;
int res; int res;
while ((opt = getopt(argc, argv, "8E:ec:")) != -1) { while ((opt = getopt(argc, argv, "8E:ec:v")) != -1) {
switch (opt) { switch (opt) {
case '8': case '8':
pkcs8 = 1; pkcs8 = 1;
@ -75,6 +77,9 @@ main(int argc, char **argv)
case 'c': case 'c':
key2_in = optarg; key2_in = optarg;
break; break;
case 'v':
verbose = 1;
break;
default: default:
usage(argv[0]); usage(argv[0]);
return 1; return 1;
@ -149,6 +154,15 @@ main(int argc, char **argv)
default: addrtype = 0; break; 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) { if (pkcs8) {
res = vg_pkcs8_encode_privkey(pbuf, sizeof(pbuf), res = vg_pkcs8_encode_privkey(pbuf, sizeof(pbuf),
pkey, pass_in); pkey, pass_in);

2591
oclengine.c

File diff suppressed because it is too large Load Diff

35
oclengine.h

@ -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__) */

2534
oclvanitygen.c

File diff suppressed because it is too large Load Diff

748
oclvanityminer.c

@ -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

@ -141,20 +141,13 @@ typedef struct _timing_info_s {
int int
vg_output_timing(vg_context_t *vcp, int cycle, struct timeval *last) 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 pthread_mutex_t mutex = PTHREAD_MUTEX_INITIALIZER;
static timing_info_t *timing_head = NULL;
pthread_t me; pthread_t me;
struct timeval tvnow, tv; struct timeval tvnow, tv;
timing_info_t *tip, *mytip; timing_info_t *tip, *mytip;
unsigned long long rate, myrate = 0, mytime; unsigned long long rate, myrate = 0, mytime, total, sincelast;
double count, prob, time, targ; int p, i;
char linebuf[80];
char *unit;
int rem, p, i;
const double targs[] = { 0.5, 0.75, 0.8, 0.9, 0.95, 1.0 };
/* Compute the rate */ /* Compute the rate */
gettimeofday(&tvnow, NULL); gettimeofday(&tvnow, NULL);
@ -167,7 +160,8 @@ vg_output_timing(vg_context_t *vcp, int cycle, struct timeval *last)
pthread_mutex_lock(&mutex); pthread_mutex_lock(&mutex);
me = pthread_self(); 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)) { if (pthread_equal(tip->ti_thread, me)) {
mytip = tip; mytip = tip;
p = ((tip->ti_hist_last + 1) % timing_hist_size); 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) { if (!mytip) {
mytip = (timing_info_t *) malloc(sizeof(*tip)); mytip = (timing_info_t *) malloc(sizeof(*tip));
mytip->ti_next = timing_head; mytip->ti_next = vcp->vc_timing_head;
mytip->ti_thread = me; mytip->ti_thread = me;
timing_head = mytip; vcp->vc_timing_head = mytip;
mytip->ti_hist_last = 0; mytip->ti_hist_last = 0;
mytip->ti_hist_time[0] = mytime; mytip->ti_hist_time[0] = mytime;
mytip->ti_hist_work[0] = cycle; mytip->ti_hist_work[0] = cycle;
@ -205,20 +199,47 @@ vg_output_timing(vg_context_t *vcp, int cycle, struct timeval *last)
rate += myrate; rate += myrate;
} }
total += cycle; vcp->vc_timing_total += cycle;
if (prevfound != vcp->vc_found) { if (vcp->vc_timing_prevfound != vcp->vc_found) {
prevfound = vcp->vc_found; vcp->vc_timing_prevfound = vcp->vc_found;
sincelast = 0; vcp->vc_timing_sincelast = 0;
} }
sincelast += cycle; vcp->vc_timing_sincelast += cycle;
count = sincelast;
if (mytip != timing_head) { if (mytip != vcp->vc_timing_head) {
pthread_mutex_unlock(&mutex); pthread_mutex_unlock(&mutex);
return myrate; return myrate;
} }
total = vcp->vc_timing_total;
sincelast = vcp->vc_timing_sincelast;
pthread_mutex_unlock(&mutex); 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; targ = rate;
unit = "key/s"; unit = "key/s";
if (targ > 1000) { if (targ > 1000) {
@ -314,11 +335,10 @@ vg_output_timing(vg_context_t *vcp, int cycle, struct timeval *last)
} }
printf("\r%s", linebuf); printf("\r%s", linebuf);
fflush(stdout); fflush(stdout);
return myrate;
} }
void 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; unsigned char key_buf[512], *pend;
char addr_buf[64], addr2_buf[64]; 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): "); printf("Privkey (ASN1): ");
dumphex(key_buf, len); dumphex(key_buf, len);
} }
} }
if (!vcp->vc_result_file || (vcp->vc_verbose > 0)) { 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 void
vg_context_free(vg_context_t *vcp) vg_context_free(vg_context_t *vcp)
{ {
vg_timing_info_free(vcp);
vcp->vc_free(vcp); vcp->vc_free(vcp);
} }
int int
vg_context_add_patterns(vg_context_t *vcp, 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); 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 int
vg_context_hash160_sort(vg_context_t *vcp, void *buf) vg_context_hash160_sort(vg_context_t *vcp, void *buf)
{ {
@ -699,6 +726,21 @@ out:
return ret; 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 * AVL tree implementation
*/ */
@ -1364,7 +1406,7 @@ typedef struct _vg_prefix_context_s {
} vg_prefix_context_t; } vg_prefix_context_t;
static void 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_context_t *vcpp = (vg_prefix_context_t *) vcp;
vg_prefix_t *vp; vg_prefix_t *vp;
@ -1378,6 +1420,17 @@ vg_prefix_context_free(vg_context_t *vcp)
} }
assert(npfx_left == vcpp->base.vc_npatterns); 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); BN_clear_free(&vcpp->vcp_difficulty);
free(vcpp); free(vcpp);
} }
@ -1407,7 +1460,7 @@ vg_prefix_context_next_difficulty(vg_prefix_context_t *vcpp,
static int static int
vg_prefix_context_add_patterns(vg_context_t *vcp, 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; vg_prefix_context_t *vcpp = (vg_prefix_context_t *) vcp;
prefix_case_iter_t caseiter; prefix_case_iter_t caseiter;
@ -1556,6 +1609,47 @@ vg_prefix_context_add_patterns(vg_context_t *vcp,
return ret; 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 static int
vg_prefix_test(vg_exec_context_t *vxcp) vg_prefix_test(vg_exec_context_t *vxcp)
@ -1579,7 +1673,8 @@ research:
goto research; goto research;
vg_exec_context_consolidate_key(vxcp); 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++; 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_chance = 0.0;
vcpp->base.vc_free = vg_prefix_context_free; vcpp->base.vc_free = vg_prefix_context_free;
vcpp->base.vc_add_patterns = vg_prefix_context_add_patterns; 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_test = vg_prefix_test;
vcpp->base.vc_hash160_sort = vg_prefix_hash160_sort; vcpp->base.vc_hash160_sort = vg_prefix_hash160_sort;
avl_root_init(&vcpp->vcp_avlroot); avl_root_init(&vcpp->vcp_avlroot);
@ -1695,7 +1792,7 @@ typedef struct _vg_regex_context_s {
static int static int
vg_regex_context_add_patterns(vg_context_t *vcp, 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; vg_regex_context_t *vcrp = (vg_regex_context_t *) vcp;
const char *pcre_errptr; const char *pcre_errptr;
@ -1770,7 +1867,7 @@ vg_regex_context_add_patterns(vg_context_t *vcp,
} }
static void 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; vg_regex_context_t *vcrp = (vg_regex_context_t *) vcp;
int i; 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_extra[i]);
pcre_free(vcrp->vcr_regex[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) if (vcrp->vcr_nalloc)
free(vcrp->vcr_regex); free(vcrp->vcr_regex);
free(vcrp); free(vcrp);
@ -1860,8 +1967,8 @@ restart_loop:
goto restart_loop; goto restart_loop;
vg_exec_context_consolidate_key(vxcp); vg_exec_context_consolidate_key(vxcp);
vg_output_match(&vcrp->base, vxcp->vxc_key, vcrp->base.vc_output_match(&vcrp->base, vxcp->vxc_key,
vcrp->vcr_regex_pat[i]); vcrp->vcr_regex_pat[i]);
vcrp->base.vc_found++; vcrp->base.vc_found++;
if (vcrp->base.vc_remove_on_match) { 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_chance = 0.0;
vcrp->base.vc_free = vg_regex_context_free; vcrp->base.vc_free = vg_regex_context_free;
vcrp->base.vc_add_patterns = vg_regex_context_add_patterns; 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_test = vg_regex_test;
vcrp->base.vc_hash160_sort = NULL; vcrp->base.vc_hash160_sort = NULL;
vcrp->vcr_regex = NULL; vcrp->vcr_regex = NULL;

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 void vg_exec_context_calc_address(vg_exec_context_t *vxcp);
extern EC_KEY *vg_exec_context_new_key(void); extern EC_KEY *vg_exec_context_new_key(void);
/* Implementation-specific lock/unlock/consolidate */ /* Implementation-specific lock/unlock/consolidate */
extern void vg_exec_downgrade_lock(vg_exec_context_t *vxcp); extern void vg_exec_downgrade_lock(vg_exec_context_t *vxcp);
extern int vg_exec_upgrade_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 void (*vg_free_func_t)(vg_context_t *);
typedef int (*vg_add_pattern_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_test_func_t)(vg_exec_context_t *);
typedef int (*vg_hash160_sort_func_t)(vg_context_t *vcp, void *buf); 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 { enum vg_format {
VCF_PUBKEY, VCF_PUBKEY,
@ -84,28 +92,50 @@ struct _vg_context_s {
const char *vc_key_protect_pass; const char *vc_key_protect_pass;
int vc_remove_on_match; int vc_remove_on_match;
int vc_verbose; 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; enum vg_format vc_format;
int vc_pubkeytype; int vc_pubkeytype;
EC_POINT *vc_pubkey_base; 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 void vg_context_free(vg_context_t *vcp);
extern int vg_context_add_patterns(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 int vg_context_hash160_sort(vg_context_t *vcp, void *buf);
extern vg_context_t *vg_prefix_context_new(int addrtype, int privtype, extern vg_context_t *vg_prefix_context_new(int addrtype, int privtype,
int caseinsensitive); 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 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 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__) */ #endif /* !defined (__VG_PATTERN_H__) */

8
vanitygen.c

@ -280,7 +280,7 @@ vg_thread_loop(void *arg)
hash_len = 65; hash_len = 65;
} }
while (1) { while (!vcp->vc_halt) {
if (++npoints >= rekey_at) { if (++npoints >= rekey_at) {
pthread_mutex_lock(&vg_thread_lock); pthread_mutex_lock(&vg_thread_lock);
/* Generate a new random private key */ /* Generate a new random private key */
@ -704,7 +704,11 @@ main(int argc, char **argv)
vcp->vc_pubkeytype = pubkeytype; vcp->vc_pubkeytype = pubkeytype;
vcp->vc_pubkey_base = pubkey_base; 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; return 1;
if (!vcp->vc_npatterns) { if (!vcp->vc_npatterns) {

23
winglue.c

@ -73,11 +73,9 @@ count_processors(void)
* struct timeval compatibility for Win32 * struct timeval compatibility for Win32
*/ */
#if defined(_MSC_VER) || defined(_MSC_EXTENSIONS) #define TIMESPEC_TO_FILETIME_OFFSET \
#define DELTA_EPOCH_IN_MICROSECS 11644473600000000Ui64 ( ((unsigned __int64) 27111902 << 32) + \
#else (unsigned __int64) 3577643008 )
#define DELTA_EPOCH_IN_MICROSECS 11644473600000000ULL
#endif
int int
gettimeofday(struct timeval *tv, struct timezone *tz) gettimeofday(struct timeval *tv, struct timezone *tz)
@ -88,14 +86,13 @@ gettimeofday(struct timeval *tv, struct timezone *tz)
if (NULL != tv) { if (NULL != tv) {
GetSystemTimeAsFileTime(&ft); GetSystemTimeAsFileTime(&ft);
tmpres |= ft.dwHighDateTime; tv->tv_sec = (int) ((*(unsigned __int64 *) &ft -
tmpres <<= 32; TIMESPEC_TO_FILETIME_OFFSET) /
tmpres |= ft.dwLowDateTime; 10000000);
tv->tv_usec = (int) ((*(unsigned __int64 *) &ft -
tmpres -= DELTA_EPOCH_IN_MICROSECS; TIMESPEC_TO_FILETIME_OFFSET -
tmpres /= 10; ((unsigned __int64) tv->tv_sec *
tv->tv_sec = (long)(tmpres / 1000000UL); (unsigned __int64) 10000000)) / 10);
tv->tv_usec = (long)(tmpres % 1000000UL);
} }
return 0; return 0;

Loading…
Cancel
Save