mirror of
https://github.com/GOSTSec/vanitygen
synced 2025-02-07 04:14:15 +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
|
||||
CFLAGS=-ggdb -O3 -Wall
|
||||
OBJS=vanitygen.o oclvanitygen.o pattern.o
|
||||
PROGS=vanitygen
|
||||
TESTS=
|
||||
OBJS=vanitygen.o oclvanitygen.o oclbntest.o pattern.o util.o
|
||||
PROGS=vanitygen oclvanitygen keytool
|
||||
TESTS=oclhbntest
|
||||
|
||||
all: $(PROGS)
|
||||
all: $(PROGS) $(TESTS)
|
||||
|
||||
vanitygen: vanitygen.o pattern.o
|
||||
vanitygen: vanitygen.o pattern.o util.o
|
||||
$(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
|
||||
|
||||
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:
|
||||
rm -f $(OBJS) $(PROGS) $(TESTS)
|
||||
|
@ -7,14 +7,14 @@ 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 pattern.obj winglue.obj
|
||||
OBJS = vanitygen.obj oclvanitygen.obj pattern.obj util.obj winglue.obj
|
||||
|
||||
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)
|
||||
|
||||
oclvanitygen.exe: oclvanitygen.obj pattern.obj winglue.obj
|
||||
oclvanitygen.exe: oclvanitygen.obj pattern.obj util.obj winglue.obj
|
||||
link /nologo /out:$@ $** $(LIBS) $(OPENCL_LIBS)
|
||||
|
||||
.c.obj:
|
||||
|
@ -38,6 +38,7 @@
|
||||
#endif
|
||||
|
||||
#include "pattern.h"
|
||||
#include "util.h"
|
||||
|
||||
|
||||
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.
|
||||
*/
|
||||
wsmult = 1;
|
||||
while ((!worksize || ((wsmult * 2) < worksize)) &&
|
||||
while ((!worksize || ((wsmult * 2) <= worksize)) &&
|
||||
((ncols * nrows * 2 * 128) < memsize) &&
|
||||
((ncols * nrows * 2 * 64) < allocsize)) {
|
||||
if (ncols > nrows)
|
||||
|
234
pattern.c
234
pattern.c
@ -32,127 +32,8 @@
|
||||
#include <pcre.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
|
||||
@ -176,8 +57,6 @@ vg_exec_context_init(vg_context_t *vcp, vg_exec_context_t *vxcp)
|
||||
assert(vxcp->vxc_bnctx);
|
||||
vxcp->vxc_key = EC_KEY_new_by_curve_name(NID_secp256k1);
|
||||
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);
|
||||
return 1;
|
||||
}
|
||||
@ -202,11 +81,7 @@ vg_exec_context_consolidate_key(vg_exec_context_t *vxcp)
|
||||
BN_add(&vxcp->vxc_bntmp2,
|
||||
EC_KEY_get0_private_key(vxcp->vxc_key),
|
||||
&vxcp->vxc_bntmp);
|
||||
EC_KEY_set_private_key(vxcp->vxc_key, &vxcp->vxc_bntmp2);
|
||||
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);
|
||||
vg_set_privkey(&vxcp->vxc_bntmp2, vxcp->vxc_key);
|
||||
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 > 1) {
|
||||
/* Hexadecimal OpenSSL notation */
|
||||
pend = key_buf;
|
||||
len = i2o_ECPublicKey(pkey, &pend);
|
||||
printf("Pubkey (ASN1): ");
|
||||
printf("Pubkey (hex): ");
|
||||
dumphex(key_buf, len);
|
||||
printf("Privkey (hex): ");
|
||||
dumpbn(EC_KEY_get0_private_key(pkey));
|
||||
pend = key_buf;
|
||||
len = i2d_ECPrivateKey(pkey, &pend);
|
||||
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.
|
||||
*/
|
||||
@ -551,7 +409,7 @@ get_prefix_ranges(int addrtype, const char *pfx, BIGNUM **result,
|
||||
p = strlen(pfx);
|
||||
|
||||
for (i = 0; i < p; i++) {
|
||||
c = b58_reverse_map[(int)pfx[i]];
|
||||
c = vg_b58_reverse_map[(int)pfx[i]];
|
||||
if (c == -1) {
|
||||
printf("Invalid character '%c' in prefix '%s'\n",
|
||||
pfx[i], pfx);
|
||||
@ -1674,7 +1532,7 @@ research:
|
||||
return res;
|
||||
}
|
||||
|
||||
int
|
||||
static int
|
||||
vg_prefix_hash160_sort(vg_context_t *vcp, void *buf)
|
||||
{
|
||||
vg_prefix_context_t *vcpp = (vg_prefix_context_t *) vcp;
|
||||
@ -1883,10 +1741,10 @@ vg_regex_test(vg_exec_context_t *vxcp)
|
||||
bn = bndiv;
|
||||
bndiv = bnptmp;
|
||||
d = BN_get_word(&bnrem);
|
||||
b58[--p] = b58_alphabet[d];
|
||||
b58[--p] = vg_b58_alphabet[d];
|
||||
}
|
||||
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;
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
* 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__)
|
||||
#define __VG_PATTERN_H__
|
||||
|
||||
#include <stdint.h>
|
||||
|
||||
#include <openssl/bn.h>
|
||||
#include <openssl/ec.h>
|
||||
|
||||
@ -36,10 +34,6 @@
|
||||
#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;
|
||||
|
||||
/* Context of one pattern-matching unit within the process */
|
||||
@ -47,7 +41,6 @@ typedef struct _vg_exec_context_s {
|
||||
vg_context_t *vxc_vc;
|
||||
BN_CTX *vxc_bnctx;
|
||||
EC_KEY *vxc_key;
|
||||
EC_POINT *vxc_point;
|
||||
int vxc_delta;
|
||||
unsigned char vxc_binres[28];
|
||||
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 void vg_output_match(vg_context_t *vcp, EC_KEY *pkey,
|
||||
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__) */
|
||||
|
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 "pattern.h"
|
||||
#include "util.h"
|
||||
|
||||
const char *version = "0.16";
|
||||
|
||||
@ -341,8 +342,6 @@ vg_thread_loop(void *arg)
|
||||
SHA256(eckey_buf, len, hash1);
|
||||
RIPEMD160(hash1, sizeof(hash1), &vxcp->vxc_binres[1]);
|
||||
|
||||
vxcp->vxc_point = ppnt[i];
|
||||
|
||||
switch (test_func(vxcp)) {
|
||||
case 1:
|
||||
npoints = 0;
|
||||
@ -356,9 +355,11 @@ vg_thread_loop(void *arg)
|
||||
}
|
||||
}
|
||||
|
||||
c += (i + 1);
|
||||
c += i;
|
||||
if (c >= output_interval) {
|
||||
output_interval = vg_output_timing(vcp, c, &tvstart);
|
||||
if (output_interval > 250000)
|
||||
output_interval = 250000;
|
||||
c = 0;
|
||||
}
|
||||
|
||||
|
Loading…
x
Reference in New Issue
Block a user