mirror of
https://github.com/GOSTSec/vanitygen
synced 2025-02-07 12:24:20 +00:00
Split base-58 encoding primitives out of pattern.c.
This commit is contained in:
parent
570e081546
commit
46aed119a1
21
Makefile
21
Makefile
@ -1,16 +1,25 @@
|
|||||||
LIBS=-lpcre -lcrypto -lm -lpthread
|
LIBS=-lpcre -lcrypto -lm -lpthread
|
||||||
CFLAGS=-ggdb -O3 -Wall
|
CFLAGS=-ggdb -O3 -Wall
|
||||||
OBJS=vanitygen.o oclvanitygen.o pattern.o
|
OBJS=vanitygen.o oclvanitygen.o oclbntest.o pattern.o util.o
|
||||||
PROGS=vanitygen
|
PROGS=vanitygen oclvanitygen keytool
|
||||||
TESTS=
|
TESTS=oclhbntest
|
||||||
|
|
||||||
all: $(PROGS)
|
all: $(PROGS) $(TESTS)
|
||||||
|
|
||||||
vanitygen: vanitygen.o pattern.o
|
vanitygen: vanitygen.o pattern.o util.o
|
||||||
$(CC) $^ -o $@ $(CFLAGS) $(LIBS)
|
$(CC) $^ -o $@ $(CFLAGS) $(LIBS)
|
||||||
|
|
||||||
oclvanitygen: oclvanitygen.o pattern.o
|
keytool: keytool.o util.o
|
||||||
|
$(CC) $^ -o $@ $(CFLAGS) $(LIBS)
|
||||||
|
|
||||||
|
oclvanitygen: oclvanitygen.o pattern.o util.o
|
||||||
$(CC) $^ -o $@ $(CFLAGS) $(LIBS) -lOpenCL
|
$(CC) $^ -o $@ $(CFLAGS) $(LIBS) -lOpenCL
|
||||||
|
|
||||||
|
oclhbntest.o: oclhbntest.c calc_addrs.cl
|
||||||
|
$(CC) -c $< -o $@ $(CFLAGS) -m32
|
||||||
|
|
||||||
|
oclhbntest: oclhbntest.o
|
||||||
|
$(CC) $^ -o $@ $(CFLAGS) -m32 libcrypto32.a -lz -ldl -lpthread
|
||||||
|
|
||||||
clean:
|
clean:
|
||||||
rm -f $(OBJS) $(PROGS) $(TESTS)
|
rm -f $(OBJS) $(PROGS) $(TESTS)
|
||||||
|
@ -7,14 +7,14 @@ 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)
|
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
|
LIBS = $(OPENSSL_DIR)\lib\libeay32.lib $(PTHREADS_DIR)\pthreadVC2.lib $(PCRE_DIR)\pcre.lib ws2_32.lib
|
||||||
OBJS = vanitygen.obj oclvanitygen.obj pattern.obj winglue.obj
|
OBJS = vanitygen.obj oclvanitygen.obj pattern.obj util.obj winglue.obj
|
||||||
|
|
||||||
all: vanitygen.exe
|
all: vanitygen.exe
|
||||||
|
|
||||||
vanitygen.exe: vanitygen.obj pattern.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 winglue.obj
|
oclvanitygen.exe: oclvanitygen.obj pattern.obj util.obj winglue.obj
|
||||||
link /nologo /out:$@ $** $(LIBS) $(OPENCL_LIBS)
|
link /nologo /out:$@ $** $(LIBS) $(OPENCL_LIBS)
|
||||||
|
|
||||||
.c.obj:
|
.c.obj:
|
||||||
|
@ -38,6 +38,7 @@
|
|||||||
#endif
|
#endif
|
||||||
|
|
||||||
#include "pattern.h"
|
#include "pattern.h"
|
||||||
|
#include "util.h"
|
||||||
|
|
||||||
|
|
||||||
const char *version = "0.16";
|
const char *version = "0.16";
|
||||||
@ -1680,7 +1681,7 @@ vg_opencl_loop(vg_context_t *vcp, cl_device_id did, int safe_mode,
|
|||||||
* multiplier or fill available memory.
|
* multiplier or fill available memory.
|
||||||
*/
|
*/
|
||||||
wsmult = 1;
|
wsmult = 1;
|
||||||
while ((!worksize || ((wsmult * 2) < worksize)) &&
|
while ((!worksize || ((wsmult * 2) <= worksize)) &&
|
||||||
((ncols * nrows * 2 * 128) < memsize) &&
|
((ncols * nrows * 2 * 128) < memsize) &&
|
||||||
((ncols * nrows * 2 * 64) < allocsize)) {
|
((ncols * nrows * 2 * 64) < allocsize)) {
|
||||||
if (ncols > nrows)
|
if (ncols > nrows)
|
||||||
|
234
pattern.c
234
pattern.c
@ -32,127 +32,8 @@
|
|||||||
#include <pcre.h>
|
#include <pcre.h>
|
||||||
|
|
||||||
#include "pattern.h"
|
#include "pattern.h"
|
||||||
|
#include "util.h"
|
||||||
|
|
||||||
static const char *b58_alphabet = "123456789ABCDEFGHJKLMNPQRSTUVWXYZabcdefghijkmnopqrstuvwxyz";
|
|
||||||
|
|
||||||
static void
|
|
||||||
encode_b58_check(void *buf, size_t len, char *result)
|
|
||||||
{
|
|
||||||
unsigned char hash1[32];
|
|
||||||
unsigned char hash2[32];
|
|
||||||
|
|
||||||
int d, p;
|
|
||||||
|
|
||||||
BN_CTX *bnctx;
|
|
||||||
BIGNUM *bn, *bndiv, *bntmp;
|
|
||||||
BIGNUM bna, bnb, bnbase, bnrem;
|
|
||||||
unsigned char *binres;
|
|
||||||
int brlen, zpfx;
|
|
||||||
|
|
||||||
bnctx = BN_CTX_new();
|
|
||||||
BN_init(&bna);
|
|
||||||
BN_init(&bnb);
|
|
||||||
BN_init(&bnbase);
|
|
||||||
BN_init(&bnrem);
|
|
||||||
BN_set_word(&bnbase, 58);
|
|
||||||
|
|
||||||
bn = &bna;
|
|
||||||
bndiv = &bnb;
|
|
||||||
|
|
||||||
brlen = (2 * len) + 4;
|
|
||||||
binres = (unsigned char*) malloc(brlen);
|
|
||||||
memcpy(binres, buf, len);
|
|
||||||
|
|
||||||
SHA256(binres, len, hash1);
|
|
||||||
SHA256(hash1, sizeof(hash1), hash2);
|
|
||||||
memcpy(&binres[len], hash2, 4);
|
|
||||||
|
|
||||||
BN_bin2bn(binres, len + 4, bn);
|
|
||||||
|
|
||||||
for (zpfx = 0; zpfx < (len + 4) && binres[zpfx] == 0; zpfx++);
|
|
||||||
|
|
||||||
p = brlen;
|
|
||||||
while (!BN_is_zero(bn)) {
|
|
||||||
BN_div(bndiv, &bnrem, bn, &bnbase, bnctx);
|
|
||||||
bntmp = bn;
|
|
||||||
bn = bndiv;
|
|
||||||
bndiv = bntmp;
|
|
||||||
d = BN_get_word(&bnrem);
|
|
||||||
binres[--p] = b58_alphabet[d];
|
|
||||||
}
|
|
||||||
|
|
||||||
while (zpfx--) {
|
|
||||||
binres[--p] = b58_alphabet[0];
|
|
||||||
}
|
|
||||||
|
|
||||||
memcpy(result, &binres[p], brlen - p);
|
|
||||||
result[brlen - p] = '\0';
|
|
||||||
|
|
||||||
free(binres);
|
|
||||||
BN_clear_free(&bna);
|
|
||||||
BN_clear_free(&bnb);
|
|
||||||
BN_clear_free(&bnbase);
|
|
||||||
BN_clear_free(&bnrem);
|
|
||||||
BN_CTX_free(bnctx);
|
|
||||||
}
|
|
||||||
|
|
||||||
void
|
|
||||||
vg_encode_address(EC_KEY *pkey, int addrtype, char *result)
|
|
||||||
{
|
|
||||||
unsigned char eckey_buf[128], *pend;
|
|
||||||
unsigned char binres[21] = {0,};
|
|
||||||
unsigned char hash1[32];
|
|
||||||
|
|
||||||
pend = eckey_buf;
|
|
||||||
|
|
||||||
i2o_ECPublicKey(pkey, &pend);
|
|
||||||
|
|
||||||
binres[0] = addrtype;
|
|
||||||
SHA256(eckey_buf, pend - eckey_buf, hash1);
|
|
||||||
RIPEMD160(hash1, sizeof(hash1), &binres[1]);
|
|
||||||
|
|
||||||
encode_b58_check(binres, sizeof(binres), result);
|
|
||||||
}
|
|
||||||
|
|
||||||
void
|
|
||||||
vg_encode_privkey(EC_KEY *pkey, int addrtype, char *result)
|
|
||||||
{
|
|
||||||
unsigned char eckey_buf[128];
|
|
||||||
const BIGNUM *bn;
|
|
||||||
int nbytes;
|
|
||||||
|
|
||||||
bn = EC_KEY_get0_private_key(pkey);
|
|
||||||
|
|
||||||
eckey_buf[0] = addrtype;
|
|
||||||
nbytes = BN_num_bytes(bn);
|
|
||||||
assert(nbytes <= 32);
|
|
||||||
if (nbytes < 32)
|
|
||||||
memset(eckey_buf + 1, 0, 32 - nbytes);
|
|
||||||
BN_bn2bin(bn, &eckey_buf[33 - nbytes]);
|
|
||||||
|
|
||||||
encode_b58_check(eckey_buf, 33, result);
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
void
|
|
||||||
dumphex(const unsigned char *src, size_t len)
|
|
||||||
{
|
|
||||||
size_t i;
|
|
||||||
for (i = 0; i < len; i++) {
|
|
||||||
printf("%02x", src[i]);
|
|
||||||
}
|
|
||||||
printf("\n");
|
|
||||||
}
|
|
||||||
|
|
||||||
void
|
|
||||||
dumpbn(const BIGNUM *bn)
|
|
||||||
{
|
|
||||||
char *buf;
|
|
||||||
buf = BN_bn2hex(bn);
|
|
||||||
printf("%s\n", buf ? buf : "0");
|
|
||||||
if (buf)
|
|
||||||
OPENSSL_free(buf);
|
|
||||||
}
|
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Common code for execution helper
|
* Common code for execution helper
|
||||||
@ -176,8 +57,6 @@ vg_exec_context_init(vg_context_t *vcp, vg_exec_context_t *vxcp)
|
|||||||
assert(vxcp->vxc_bnctx);
|
assert(vxcp->vxc_bnctx);
|
||||||
vxcp->vxc_key = EC_KEY_new_by_curve_name(NID_secp256k1);
|
vxcp->vxc_key = EC_KEY_new_by_curve_name(NID_secp256k1);
|
||||||
assert(vxcp->vxc_key);
|
assert(vxcp->vxc_key);
|
||||||
vxcp->vxc_point = EC_POINT_new(EC_KEY_get0_group(vxcp->vxc_key));
|
|
||||||
assert(vxcp->vxc_point);
|
|
||||||
EC_KEY_precompute_mult(vxcp->vxc_key, vxcp->vxc_bnctx);
|
EC_KEY_precompute_mult(vxcp->vxc_key, vxcp->vxc_bnctx);
|
||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
@ -202,11 +81,7 @@ vg_exec_context_consolidate_key(vg_exec_context_t *vxcp)
|
|||||||
BN_add(&vxcp->vxc_bntmp2,
|
BN_add(&vxcp->vxc_bntmp2,
|
||||||
EC_KEY_get0_private_key(vxcp->vxc_key),
|
EC_KEY_get0_private_key(vxcp->vxc_key),
|
||||||
&vxcp->vxc_bntmp);
|
&vxcp->vxc_bntmp);
|
||||||
EC_KEY_set_private_key(vxcp->vxc_key, &vxcp->vxc_bntmp2);
|
vg_set_privkey(&vxcp->vxc_bntmp2, vxcp->vxc_key);
|
||||||
EC_POINT_mul(EC_KEY_get0_group(vxcp->vxc_key),
|
|
||||||
vxcp->vxc_point, &vxcp->vxc_bntmp2,
|
|
||||||
NULL, NULL, vxcp->vxc_bnctx);
|
|
||||||
EC_KEY_set_public_key(vxcp->vxc_key, vxcp->vxc_point);
|
|
||||||
vxcp->vxc_delta = 0;
|
vxcp->vxc_delta = 0;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -443,11 +318,12 @@ vg_output_match(vg_context_t *vcp, EC_KEY *pkey, const char *pattern)
|
|||||||
|
|
||||||
if (vcp->vc_verbose > 0) {
|
if (vcp->vc_verbose > 0) {
|
||||||
if (vcp->vc_verbose > 1) {
|
if (vcp->vc_verbose > 1) {
|
||||||
/* Hexadecimal OpenSSL notation */
|
|
||||||
pend = key_buf;
|
pend = key_buf;
|
||||||
len = i2o_ECPublicKey(pkey, &pend);
|
len = i2o_ECPublicKey(pkey, &pend);
|
||||||
printf("Pubkey (ASN1): ");
|
printf("Pubkey (hex): ");
|
||||||
dumphex(key_buf, len);
|
dumphex(key_buf, len);
|
||||||
|
printf("Privkey (hex): ");
|
||||||
|
dumpbn(EC_KEY_get0_private_key(pkey));
|
||||||
pend = key_buf;
|
pend = key_buf;
|
||||||
len = i2d_ECPrivateKey(pkey, &pend);
|
len = i2d_ECPrivateKey(pkey, &pend);
|
||||||
printf("Privkey (ASN1): ");
|
printf("Privkey (ASN1): ");
|
||||||
@ -502,24 +378,6 @@ vg_context_hash160_sort(vg_context_t *vcp, void *buf)
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
static const signed char b58_reverse_map[256] = {
|
|
||||||
-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
|
|
||||||
-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
|
|
||||||
-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
|
|
||||||
-1, 0, 1, 2, 3, 4, 5, 6, 7, 8, -1, -1, -1, -1, -1, -1,
|
|
||||||
-1, 9, 10, 11, 12, 13, 14, 15, 16, -1, 17, 18, 19, 20, 21, -1,
|
|
||||||
22, 23, 24, 25, 26, 27, 28, 29, 30, 31, 32, -1, -1, -1, -1, -1,
|
|
||||||
-1, 33, 34, 35, 36, 37, 38, 39, 40, 41, 42, 43, -1, 44, 45, 46,
|
|
||||||
47, 48, 49, 50, 51, 52, 53, 54, 55, 56, 57, -1, -1, -1, -1, -1,
|
|
||||||
-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
|
|
||||||
-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
|
|
||||||
-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
|
|
||||||
-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
|
|
||||||
-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
|
|
||||||
-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
|
|
||||||
-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1
|
|
||||||
};
|
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Find the bignum ranges that produce a given prefix.
|
* Find the bignum ranges that produce a given prefix.
|
||||||
*/
|
*/
|
||||||
@ -551,7 +409,7 @@ get_prefix_ranges(int addrtype, const char *pfx, BIGNUM **result,
|
|||||||
p = strlen(pfx);
|
p = strlen(pfx);
|
||||||
|
|
||||||
for (i = 0; i < p; i++) {
|
for (i = 0; i < p; i++) {
|
||||||
c = b58_reverse_map[(int)pfx[i]];
|
c = vg_b58_reverse_map[(int)pfx[i]];
|
||||||
if (c == -1) {
|
if (c == -1) {
|
||||||
printf("Invalid character '%c' in prefix '%s'\n",
|
printf("Invalid character '%c' in prefix '%s'\n",
|
||||||
pfx[i], pfx);
|
pfx[i], pfx);
|
||||||
@ -1674,7 +1532,7 @@ research:
|
|||||||
return res;
|
return res;
|
||||||
}
|
}
|
||||||
|
|
||||||
int
|
static int
|
||||||
vg_prefix_hash160_sort(vg_context_t *vcp, void *buf)
|
vg_prefix_hash160_sort(vg_context_t *vcp, void *buf)
|
||||||
{
|
{
|
||||||
vg_prefix_context_t *vcpp = (vg_prefix_context_t *) vcp;
|
vg_prefix_context_t *vcpp = (vg_prefix_context_t *) vcp;
|
||||||
@ -1883,10 +1741,10 @@ vg_regex_test(vg_exec_context_t *vxcp)
|
|||||||
bn = bndiv;
|
bn = bndiv;
|
||||||
bndiv = bnptmp;
|
bndiv = bnptmp;
|
||||||
d = BN_get_word(&bnrem);
|
d = BN_get_word(&bnrem);
|
||||||
b58[--p] = b58_alphabet[d];
|
b58[--p] = vg_b58_alphabet[d];
|
||||||
}
|
}
|
||||||
while (zpfx--) {
|
while (zpfx--) {
|
||||||
b58[--p] = b58_alphabet[0];
|
b58[--p] = vg_b58_alphabet[0];
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
@ -1972,77 +1830,3 @@ vg_regex_context_new(int addrtype, int privtype)
|
|||||||
}
|
}
|
||||||
return &vcrp->base;
|
return &vcrp->base;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
/*
|
|
||||||
* Pattern file reader
|
|
||||||
* Absolutely disgusting, unable to free the pattern list when it's done
|
|
||||||
*/
|
|
||||||
|
|
||||||
int
|
|
||||||
vg_read_file(FILE *fp, char ***result, int *rescount)
|
|
||||||
{
|
|
||||||
int ret = 1;
|
|
||||||
|
|
||||||
char **patterns;
|
|
||||||
char *buf = NULL, *obuf, *pat;
|
|
||||||
const int blksize = 16*1024;
|
|
||||||
int nalloc = 16;
|
|
||||||
int npatterns = 0;
|
|
||||||
int count, pos;
|
|
||||||
|
|
||||||
patterns = (char**) malloc(sizeof(char*) * nalloc);
|
|
||||||
count = 0;
|
|
||||||
pos = 0;
|
|
||||||
|
|
||||||
while (1) {
|
|
||||||
obuf = buf;
|
|
||||||
buf = (char *) malloc(blksize);
|
|
||||||
if (!buf) {
|
|
||||||
ret = 0;
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
if (pos < count) {
|
|
||||||
memcpy(buf, &obuf[pos], count - pos);
|
|
||||||
}
|
|
||||||
pos = count - pos;
|
|
||||||
count = fread(&buf[pos], 1, blksize - pos, fp);
|
|
||||||
if (count < 0) {
|
|
||||||
printf("Error reading file: %s\n", strerror(errno));
|
|
||||||
ret = 0;
|
|
||||||
}
|
|
||||||
if (count <= 0)
|
|
||||||
break;
|
|
||||||
count += pos;
|
|
||||||
pat = buf;
|
|
||||||
|
|
||||||
while (pos < count) {
|
|
||||||
if ((buf[pos] == '\r') || (buf[pos] == '\n')) {
|
|
||||||
buf[pos] = '\0';
|
|
||||||
if (pat) {
|
|
||||||
if (npatterns == nalloc) {
|
|
||||||
nalloc *= 2;
|
|
||||||
patterns = (char**)
|
|
||||||
realloc(patterns,
|
|
||||||
sizeof(char*) *
|
|
||||||
nalloc);
|
|
||||||
}
|
|
||||||
patterns[npatterns] = pat;
|
|
||||||
npatterns++;
|
|
||||||
pat = NULL;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
else if (!pat) {
|
|
||||||
pat = &buf[pos];
|
|
||||||
}
|
|
||||||
pos++;
|
|
||||||
}
|
|
||||||
|
|
||||||
pos = pat ? (pat - buf) : count;
|
|
||||||
}
|
|
||||||
|
|
||||||
*result = patterns;
|
|
||||||
*rescount = npatterns;
|
|
||||||
|
|
||||||
return ret;
|
|
||||||
}
|
|
||||||
|
14
pattern.h
14
pattern.h
@ -19,8 +19,6 @@
|
|||||||
#if !defined (__VG_PATTERN_H__)
|
#if !defined (__VG_PATTERN_H__)
|
||||||
#define __VG_PATTERN_H__
|
#define __VG_PATTERN_H__
|
||||||
|
|
||||||
#include <stdint.h>
|
|
||||||
|
|
||||||
#include <openssl/bn.h>
|
#include <openssl/bn.h>
|
||||||
#include <openssl/ec.h>
|
#include <openssl/ec.h>
|
||||||
|
|
||||||
@ -36,10 +34,6 @@
|
|||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
|
||||||
extern void dumphex(const unsigned char *src, size_t len);
|
|
||||||
extern void dumpbn(const BIGNUM *bn);
|
|
||||||
extern void dumpbin(const uint8_t *data, size_t nbytes);
|
|
||||||
|
|
||||||
typedef struct _vg_context_s vg_context_t;
|
typedef struct _vg_context_s vg_context_t;
|
||||||
|
|
||||||
/* Context of one pattern-matching unit within the process */
|
/* Context of one pattern-matching unit within the process */
|
||||||
@ -47,7 +41,6 @@ typedef struct _vg_exec_context_s {
|
|||||||
vg_context_t *vxc_vc;
|
vg_context_t *vxc_vc;
|
||||||
BN_CTX *vxc_bnctx;
|
BN_CTX *vxc_bnctx;
|
||||||
EC_KEY *vxc_key;
|
EC_KEY *vxc_key;
|
||||||
EC_POINT *vxc_point;
|
|
||||||
int vxc_delta;
|
int vxc_delta;
|
||||||
unsigned char vxc_binres[28];
|
unsigned char vxc_binres[28];
|
||||||
BIGNUM vxc_bntarg;
|
BIGNUM vxc_bntarg;
|
||||||
@ -104,12 +97,5 @@ 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,
|
extern void vg_output_match(vg_context_t *vcp, EC_KEY *pkey,
|
||||||
const char *pattern);
|
const char *pattern);
|
||||||
extern void vg_encode_address(EC_KEY *pkey, int addrtype, char *result);
|
|
||||||
extern void vg_encode_privkey(EC_KEY *pkey, int addrtype, char *result);
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
extern int vg_read_file(FILE *fp, char ***result, int *rescount);
|
|
||||||
|
|
||||||
|
|
||||||
#endif /* !defined (__VG_PATTERN_H__) */
|
#endif /* !defined (__VG_PATTERN_H__) */
|
||||||
|
359
util.c
Normal file
359
util.c
Normal file
@ -0,0 +1,359 @@
|
|||||||
|
/*
|
||||||
|
* 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 <stdlib.h>
|
||||||
|
#include <string.h>
|
||||||
|
#include <assert.h>
|
||||||
|
|
||||||
|
#include <openssl/bn.h>
|
||||||
|
#include <openssl/sha.h>
|
||||||
|
#include <openssl/ripemd.h>
|
||||||
|
|
||||||
|
#include "pattern.h"
|
||||||
|
#include "util.h"
|
||||||
|
|
||||||
|
const char *vg_b58_alphabet = "123456789ABCDEFGHJKLMNPQRSTUVWXYZabcdefghijkmnopqrstuvwxyz";
|
||||||
|
|
||||||
|
const signed char vg_b58_reverse_map[256] = {
|
||||||
|
-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
|
||||||
|
-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
|
||||||
|
-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
|
||||||
|
-1, 0, 1, 2, 3, 4, 5, 6, 7, 8, -1, -1, -1, -1, -1, -1,
|
||||||
|
-1, 9, 10, 11, 12, 13, 14, 15, 16, -1, 17, 18, 19, 20, 21, -1,
|
||||||
|
22, 23, 24, 25, 26, 27, 28, 29, 30, 31, 32, -1, -1, -1, -1, -1,
|
||||||
|
-1, 33, 34, 35, 36, 37, 38, 39, 40, 41, 42, 43, -1, 44, 45, 46,
|
||||||
|
47, 48, 49, 50, 51, 52, 53, 54, 55, 56, 57, -1, -1, -1, -1, -1,
|
||||||
|
-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
|
||||||
|
-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
|
||||||
|
-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
|
||||||
|
-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
|
||||||
|
-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
|
||||||
|
-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
|
||||||
|
-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1
|
||||||
|
};
|
||||||
|
|
||||||
|
void
|
||||||
|
dumphex(const unsigned char *src, size_t len)
|
||||||
|
{
|
||||||
|
size_t i;
|
||||||
|
for (i = 0; i < len; i++) {
|
||||||
|
printf("%02x", src[i]);
|
||||||
|
}
|
||||||
|
printf("\n");
|
||||||
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
dumpbn(const BIGNUM *bn)
|
||||||
|
{
|
||||||
|
char *buf;
|
||||||
|
buf = BN_bn2hex(bn);
|
||||||
|
printf("%s\n", buf ? buf : "0");
|
||||||
|
if (buf)
|
||||||
|
OPENSSL_free(buf);
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Key format encode/decode
|
||||||
|
*/
|
||||||
|
|
||||||
|
void
|
||||||
|
vg_b58_encode_check(void *buf, size_t len, char *result)
|
||||||
|
{
|
||||||
|
unsigned char hash1[32];
|
||||||
|
unsigned char hash2[32];
|
||||||
|
|
||||||
|
int d, p;
|
||||||
|
|
||||||
|
BN_CTX *bnctx;
|
||||||
|
BIGNUM *bn, *bndiv, *bntmp;
|
||||||
|
BIGNUM bna, bnb, bnbase, bnrem;
|
||||||
|
unsigned char *binres;
|
||||||
|
int brlen, zpfx;
|
||||||
|
|
||||||
|
bnctx = BN_CTX_new();
|
||||||
|
BN_init(&bna);
|
||||||
|
BN_init(&bnb);
|
||||||
|
BN_init(&bnbase);
|
||||||
|
BN_init(&bnrem);
|
||||||
|
BN_set_word(&bnbase, 58);
|
||||||
|
|
||||||
|
bn = &bna;
|
||||||
|
bndiv = &bnb;
|
||||||
|
|
||||||
|
brlen = (2 * len) + 4;
|
||||||
|
binres = (unsigned char*) malloc(brlen);
|
||||||
|
memcpy(binres, buf, len);
|
||||||
|
|
||||||
|
SHA256(binres, len, hash1);
|
||||||
|
SHA256(hash1, sizeof(hash1), hash2);
|
||||||
|
memcpy(&binres[len], hash2, 4);
|
||||||
|
|
||||||
|
BN_bin2bn(binres, len + 4, bn);
|
||||||
|
|
||||||
|
for (zpfx = 0; zpfx < (len + 4) && binres[zpfx] == 0; zpfx++);
|
||||||
|
|
||||||
|
p = brlen;
|
||||||
|
while (!BN_is_zero(bn)) {
|
||||||
|
BN_div(bndiv, &bnrem, bn, &bnbase, bnctx);
|
||||||
|
bntmp = bn;
|
||||||
|
bn = bndiv;
|
||||||
|
bndiv = bntmp;
|
||||||
|
d = BN_get_word(&bnrem);
|
||||||
|
binres[--p] = vg_b58_alphabet[d];
|
||||||
|
}
|
||||||
|
|
||||||
|
while (zpfx--) {
|
||||||
|
binres[--p] = vg_b58_alphabet[0];
|
||||||
|
}
|
||||||
|
|
||||||
|
memcpy(result, &binres[p], brlen - p);
|
||||||
|
result[brlen - p] = '\0';
|
||||||
|
|
||||||
|
free(binres);
|
||||||
|
BN_clear_free(&bna);
|
||||||
|
BN_clear_free(&bnb);
|
||||||
|
BN_clear_free(&bnbase);
|
||||||
|
BN_clear_free(&bnrem);
|
||||||
|
BN_CTX_free(bnctx);
|
||||||
|
}
|
||||||
|
|
||||||
|
int
|
||||||
|
vg_b58_decode_check(const char *input, void *buf, size_t len)
|
||||||
|
{
|
||||||
|
int i, l, c;
|
||||||
|
unsigned char *xbuf = NULL;
|
||||||
|
BIGNUM bn, bnw, bnbase;
|
||||||
|
BN_CTX *bnctx;
|
||||||
|
unsigned char hash1[32], hash2[32];
|
||||||
|
int zpfx;
|
||||||
|
int res = 0;
|
||||||
|
|
||||||
|
BN_init(&bn);
|
||||||
|
BN_init(&bnw);
|
||||||
|
BN_init(&bnbase);
|
||||||
|
BN_set_word(&bnbase, 58);
|
||||||
|
bnctx = BN_CTX_new();
|
||||||
|
|
||||||
|
/* Build a bignum from the encoded value */
|
||||||
|
l = strlen(input);
|
||||||
|
for (i = 0; i < l; i++) {
|
||||||
|
c = vg_b58_reverse_map[(int)input[i]];
|
||||||
|
if (c < 0)
|
||||||
|
goto out;
|
||||||
|
BN_clear(&bnw);
|
||||||
|
BN_set_word(&bnw, c);
|
||||||
|
BN_mul(&bn, &bn, &bnbase, bnctx);
|
||||||
|
BN_add(&bn, &bn, &bnw);
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Copy the bignum to a byte buffer */
|
||||||
|
for (zpfx = 0;
|
||||||
|
input[zpfx] && (input[zpfx] == vg_b58_alphabet[0]);
|
||||||
|
zpfx++);
|
||||||
|
c = BN_num_bytes(&bn);
|
||||||
|
l = zpfx + c;
|
||||||
|
if (l < 5)
|
||||||
|
goto out;
|
||||||
|
xbuf = (unsigned char *) malloc(l);
|
||||||
|
if (!xbuf)
|
||||||
|
goto out;
|
||||||
|
if (zpfx)
|
||||||
|
memset(xbuf, 0, zpfx);
|
||||||
|
if (c)
|
||||||
|
BN_bn2bin(&bn, xbuf + zpfx);
|
||||||
|
|
||||||
|
/* Check the hash code */
|
||||||
|
l -= 4;
|
||||||
|
SHA256(xbuf, l, hash1);
|
||||||
|
SHA256(hash1, sizeof(hash1), hash2);
|
||||||
|
if (memcmp(hash2, xbuf + l, 4))
|
||||||
|
goto out;
|
||||||
|
|
||||||
|
/* Buffer verified */
|
||||||
|
if (len) {
|
||||||
|
if (len > l)
|
||||||
|
len = l;
|
||||||
|
memcpy(buf, xbuf, len);
|
||||||
|
}
|
||||||
|
res = l;
|
||||||
|
|
||||||
|
out:
|
||||||
|
if (xbuf)
|
||||||
|
free(xbuf);
|
||||||
|
BN_clear_free(&bn);
|
||||||
|
BN_clear_free(&bnw);
|
||||||
|
BN_clear_free(&bnbase);
|
||||||
|
BN_CTX_free(bnctx);
|
||||||
|
return res;
|
||||||
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
vg_encode_address(const EC_KEY *pkey, int addrtype, char *result)
|
||||||
|
{
|
||||||
|
unsigned char eckey_buf[128], *pend;
|
||||||
|
unsigned char binres[21] = {0,};
|
||||||
|
unsigned char hash1[32];
|
||||||
|
|
||||||
|
pend = eckey_buf;
|
||||||
|
|
||||||
|
i2o_ECPublicKey((EC_KEY*)pkey, &pend);
|
||||||
|
|
||||||
|
binres[0] = addrtype;
|
||||||
|
SHA256(eckey_buf, pend - eckey_buf, hash1);
|
||||||
|
RIPEMD160(hash1, sizeof(hash1), &binres[1]);
|
||||||
|
|
||||||
|
vg_b58_encode_check(binres, sizeof(binres), result);
|
||||||
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
vg_encode_privkey(const EC_KEY *pkey, int addrtype, char *result)
|
||||||
|
{
|
||||||
|
unsigned char eckey_buf[128];
|
||||||
|
const BIGNUM *bn;
|
||||||
|
int nbytes;
|
||||||
|
|
||||||
|
bn = EC_KEY_get0_private_key(pkey);
|
||||||
|
|
||||||
|
eckey_buf[0] = addrtype;
|
||||||
|
nbytes = BN_num_bytes(bn);
|
||||||
|
assert(nbytes <= 32);
|
||||||
|
if (nbytes < 32)
|
||||||
|
memset(eckey_buf + 1, 0, 32 - nbytes);
|
||||||
|
BN_bn2bin(bn, &eckey_buf[33 - nbytes]);
|
||||||
|
|
||||||
|
vg_b58_encode_check(eckey_buf, 33, result);
|
||||||
|
}
|
||||||
|
|
||||||
|
int
|
||||||
|
vg_set_privkey(const BIGNUM *bnpriv, EC_KEY *pkey)
|
||||||
|
{
|
||||||
|
const EC_GROUP *pgroup;
|
||||||
|
EC_POINT *ppnt;
|
||||||
|
int res;
|
||||||
|
|
||||||
|
pgroup = EC_KEY_get0_group(pkey);
|
||||||
|
ppnt = EC_POINT_new(pgroup);
|
||||||
|
|
||||||
|
res = (ppnt &&
|
||||||
|
EC_KEY_set_private_key(pkey, bnpriv) &&
|
||||||
|
EC_POINT_mul(pgroup, ppnt, bnpriv, NULL, NULL, NULL) &&
|
||||||
|
EC_KEY_set_public_key(pkey, ppnt));
|
||||||
|
|
||||||
|
if (ppnt)
|
||||||
|
EC_POINT_free(ppnt);
|
||||||
|
|
||||||
|
if (!res)
|
||||||
|
return 0;
|
||||||
|
|
||||||
|
assert(EC_KEY_check_key(pkey));
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
int
|
||||||
|
vg_decode_privkey(const char *b58encoded, EC_KEY *pkey, int *addrtype)
|
||||||
|
{
|
||||||
|
BIGNUM bnpriv;
|
||||||
|
unsigned char ecpriv[48];
|
||||||
|
int res;
|
||||||
|
|
||||||
|
res = vg_b58_decode_check(b58encoded, ecpriv, sizeof(ecpriv));
|
||||||
|
|
||||||
|
BN_init(&bnpriv);
|
||||||
|
BN_bin2bn(ecpriv + 1, res - 1, &bnpriv);
|
||||||
|
res = vg_set_privkey(&bnpriv, pkey);
|
||||||
|
BN_clear_free(&bnpriv);
|
||||||
|
|
||||||
|
if (res)
|
||||||
|
*addrtype = ecpriv[0];
|
||||||
|
return res;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Pattern file reader
|
||||||
|
* Absolutely disgusting, unable to free the pattern list when it's done
|
||||||
|
*/
|
||||||
|
|
||||||
|
int
|
||||||
|
vg_read_file(FILE *fp, char ***result, int *rescount)
|
||||||
|
{
|
||||||
|
int ret = 1;
|
||||||
|
|
||||||
|
char **patterns;
|
||||||
|
char *buf = NULL, *obuf, *pat;
|
||||||
|
const int blksize = 16*1024;
|
||||||
|
int nalloc = 16;
|
||||||
|
int npatterns = 0;
|
||||||
|
int count, pos;
|
||||||
|
|
||||||
|
patterns = (char**) malloc(sizeof(char*) * nalloc);
|
||||||
|
count = 0;
|
||||||
|
pos = 0;
|
||||||
|
|
||||||
|
while (1) {
|
||||||
|
obuf = buf;
|
||||||
|
buf = (char *) malloc(blksize);
|
||||||
|
if (!buf) {
|
||||||
|
ret = 0;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
if (pos < count) {
|
||||||
|
memcpy(buf, &obuf[pos], count - pos);
|
||||||
|
}
|
||||||
|
pos = count - pos;
|
||||||
|
count = fread(&buf[pos], 1, blksize - pos, fp);
|
||||||
|
if (count < 0) {
|
||||||
|
printf("Error reading file: %s\n", strerror(errno));
|
||||||
|
ret = 0;
|
||||||
|
}
|
||||||
|
if (count <= 0)
|
||||||
|
break;
|
||||||
|
count += pos;
|
||||||
|
pat = buf;
|
||||||
|
|
||||||
|
while (pos < count) {
|
||||||
|
if ((buf[pos] == '\r') || (buf[pos] == '\n')) {
|
||||||
|
buf[pos] = '\0';
|
||||||
|
if (pat) {
|
||||||
|
if (npatterns == nalloc) {
|
||||||
|
nalloc *= 2;
|
||||||
|
patterns = (char**)
|
||||||
|
realloc(patterns,
|
||||||
|
sizeof(char*) *
|
||||||
|
nalloc);
|
||||||
|
}
|
||||||
|
patterns[npatterns] = pat;
|
||||||
|
npatterns++;
|
||||||
|
pat = NULL;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else if (!pat) {
|
||||||
|
pat = &buf[pos];
|
||||||
|
}
|
||||||
|
pos++;
|
||||||
|
}
|
||||||
|
|
||||||
|
pos = pat ? (pat - buf) : count;
|
||||||
|
}
|
||||||
|
|
||||||
|
*result = patterns;
|
||||||
|
*rescount = npatterns;
|
||||||
|
|
||||||
|
return ret;
|
||||||
|
}
|
45
util.h
Normal file
45
util.h
Normal file
@ -0,0 +1,45 @@
|
|||||||
|
/*
|
||||||
|
* 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_UTIL_H__)
|
||||||
|
#define __VG_UTIL_H__
|
||||||
|
|
||||||
|
#include <stdint.h>
|
||||||
|
|
||||||
|
#include <openssl/bn.h>
|
||||||
|
#include <openssl/ec.h>
|
||||||
|
|
||||||
|
extern const char *vg_b58_alphabet;
|
||||||
|
extern const signed char vg_b58_reverse_map[256];
|
||||||
|
|
||||||
|
extern void dumphex(const unsigned char *src, size_t len);
|
||||||
|
extern void dumpbn(const BIGNUM *bn);
|
||||||
|
|
||||||
|
extern void vg_b58_encode_check(void *buf, size_t len, char *result);
|
||||||
|
extern int vg_b58_decode_check(const char *input, void *buf, size_t len);
|
||||||
|
|
||||||
|
extern void vg_encode_address(const EC_KEY *pkey, int addrtype, char *result);
|
||||||
|
extern void vg_encode_privkey(const EC_KEY *pkey, int addrtype, char *result);
|
||||||
|
extern int vg_set_privkey(const BIGNUM *bnpriv, EC_KEY *pkey);
|
||||||
|
extern int vg_decode_privkey(const char *b58encoded,
|
||||||
|
EC_KEY *pkey, int *addrtype);
|
||||||
|
|
||||||
|
|
||||||
|
extern int vg_read_file(FILE *fp, char ***result, int *rescount);
|
||||||
|
|
||||||
|
#endif /* !defined (__VG_UTIL_H__) */
|
@ -30,6 +30,7 @@
|
|||||||
#include <openssl/rand.h>
|
#include <openssl/rand.h>
|
||||||
|
|
||||||
#include "pattern.h"
|
#include "pattern.h"
|
||||||
|
#include "util.h"
|
||||||
|
|
||||||
const char *version = "0.16";
|
const char *version = "0.16";
|
||||||
|
|
||||||
@ -341,8 +342,6 @@ vg_thread_loop(void *arg)
|
|||||||
SHA256(eckey_buf, len, hash1);
|
SHA256(eckey_buf, len, hash1);
|
||||||
RIPEMD160(hash1, sizeof(hash1), &vxcp->vxc_binres[1]);
|
RIPEMD160(hash1, sizeof(hash1), &vxcp->vxc_binres[1]);
|
||||||
|
|
||||||
vxcp->vxc_point = ppnt[i];
|
|
||||||
|
|
||||||
switch (test_func(vxcp)) {
|
switch (test_func(vxcp)) {
|
||||||
case 1:
|
case 1:
|
||||||
npoints = 0;
|
npoints = 0;
|
||||||
@ -356,9 +355,11 @@ vg_thread_loop(void *arg)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
c += (i + 1);
|
c += i;
|
||||||
if (c >= output_interval) {
|
if (c >= output_interval) {
|
||||||
output_interval = vg_output_timing(vcp, c, &tvstart);
|
output_interval = vg_output_timing(vcp, c, &tvstart);
|
||||||
|
if (output_interval > 250000)
|
||||||
|
output_interval = 250000;
|
||||||
c = 0;
|
c = 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Loading…
x
Reference in New Issue
Block a user