Browse Source

Add support for base public keys to vanitygen and oclvanitygen.

Add partial private key combining feature to keyconv.
master
samr7 13 years ago
parent
commit
9ac1c5e21d
  1. 46
      keyconv.c
  2. 30
      oclvanitygen.c
  3. 48
      pattern.c
  4. 4
      pattern.h
  5. 24
      util.c
  6. 7
      util.h
  7. 34
      vanitygen.c

46
keyconv.c

@ -24,10 +24,11 @@ usage(const char *progname)
{ {
fprintf(stderr, fprintf(stderr,
"Vanitygen keyconv %s\n" "Vanitygen keyconv %s\n"
"Usage: %s [-8] [-e|-E <password>] [<key>]\n" "Usage: %s [-8] [-e|-E <password>] [-c <key>] [<key>]\n"
"-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",
version, progname); version, progname);
} }
@ -40,6 +41,7 @@ main(int argc, char **argv)
char pbuf[1024]; char pbuf[1024];
const char *key_in; const char *key_in;
const char *pass_in = NULL; const char *pass_in = NULL;
const char *key2_in = NULL;
EC_KEY *pkey; EC_KEY *pkey;
int parameter_group = -1; int parameter_group = -1;
int privtype, addrtype; int privtype, addrtype;
@ -48,7 +50,7 @@ main(int argc, char **argv)
int opt; int opt;
int res; int res;
while ((opt = getopt(argc, argv, "8E:e")) != -1) { while ((opt = getopt(argc, argv, "8E:ec:")) != -1) {
switch (opt) { switch (opt) {
case '8': case '8':
pkcs8 = 1; pkcs8 = 1;
@ -70,6 +72,9 @@ main(int argc, char **argv)
} }
pass_prompt = 1; pass_prompt = 1;
break; break;
case 'c':
key2_in = optarg;
break;
default: default:
usage(argv[0]); usage(argv[0]);
return 1; return 1;
@ -101,6 +106,33 @@ main(int argc, char **argv)
return 1; return 1;
} }
if (key2_in) {
BIGNUM bntmp;
EC_KEY *pkey2;
pkey2 = EC_KEY_new_by_curve_name(NID_secp256k1);
res = vg_decode_privkey_any(pkey2, &privtype, key2_in, NULL);
if (res < 0) {
if (EVP_read_pw_string(pwbuf, sizeof(pwbuf),
"Enter import password:", 0) ||
!vg_decode_privkey_any(pkey2, &privtype,
key2_in, pwbuf))
return 1;
}
if (!res) {
fprintf(stderr, "ERROR: Unrecognized key format\n");
return 1;
}
BN_init(&bntmp);
BN_add(&bntmp,
EC_KEY_get0_private_key(pkey),
EC_KEY_get0_private_key(pkey2));
vg_set_privkey(&bntmp, pkey);
EC_KEY_free(pkey2);
BN_clear_free(&bntmp);
}
if (pass_prompt) { if (pass_prompt) {
res = EVP_read_pw_string(pwbuf, sizeof(pwbuf), res = EVP_read_pw_string(pwbuf, sizeof(pwbuf),
"Enter password:", 1); "Enter password:", 1);
@ -138,13 +170,17 @@ main(int argc, char **argv)
return 1; return 1;
} }
vg_encode_address(pkey, addrtype, pwbuf); vg_encode_address(EC_KEY_get0_public_key(pkey),
EC_KEY_get0_group(pkey),
addrtype, pwbuf);
printf("Address: %s\n", pwbuf); printf("Address: %s\n", pwbuf);
printf("Protkey: %s\n", ecprot); printf("Protkey: %s\n", ecprot);
} }
else { else {
vg_encode_address(pkey, addrtype, ecprot); vg_encode_address(EC_KEY_get0_public_key(pkey),
EC_KEY_get0_group(pkey),
addrtype, ecprot);
printf("Address: %s\n", ecprot); printf("Address: %s\n", ecprot);
vg_encode_privkey(pkey, privtype, ecprot); vg_encode_privkey(pkey, privtype, ecprot);
printf("Privkey: %s\n", ecprot); printf("Privkey: %s\n", ecprot);

30
oclvanitygen.c

@ -2124,6 +2124,14 @@ l_rekey:
EC_POINT_copy(ppbase[0], EC_KEY_get0_public_key(pkey)); EC_POINT_copy(ppbase[0], EC_KEY_get0_public_key(pkey));
if (vcp->vc_pubkey_base) {
EC_POINT_add(pgroup,
ppbase[0],
ppbase[0],
vcp->vc_pubkey_base,
vxcp->vxc_bnctx);
}
/* Build the base array of sequential points */ /* Build the base array of sequential points */
for (i = 1; i < ncols; i++) { for (i = 1; i < ncols; i++) {
EC_POINT_add(pgroup, EC_POINT_add(pgroup,
@ -2590,11 +2598,12 @@ main(int argc, char **argv)
int safe_mode = 0; int safe_mode = 0;
vg_context_t *vcp = NULL; vg_context_t *vcp = NULL;
cl_device_id did; cl_device_id did;
EC_POINT *pubkey_base = NULL;
const char *result_file = NULL; const char *result_file = NULL;
const char *key_password = NULL; const char *key_password = NULL;
while ((opt = getopt(argc, argv, while ((opt = getopt(argc, argv,
"vqrikNTX:eE:p:d:w:t:g:b:VSh?f:o:s:")) != -1) { "vqrikNTX:eE:p:P:d:w:t:g:b:VSh?f:o:s:")) != -1) {
switch (opt) { switch (opt) {
case 'v': case 'v':
verbose = 2; verbose = 2;
@ -2684,6 +2693,24 @@ main(int argc, char **argv)
case 'S': case 'S':
safe_mode = 1; safe_mode = 1;
break; break;
case 'P': {
if (pubkey_base != NULL) {
fprintf(stderr,
"Multiple base pubkeys specified\n");
return 1;
}
EC_KEY *pkey = vg_exec_context_new_key();
pubkey_base = EC_POINT_hex2point(
EC_KEY_get0_group(pkey),
optarg, NULL, NULL);
EC_KEY_free(pkey);
if (pubkey_base == NULL) {
fprintf(stderr,
"Invalid base pubkey\n");
return 1;
}
break;
}
case 'f': case 'f':
if (fp) { if (fp) {
fprintf(stderr, "Multiple files specified\n"); fprintf(stderr, "Multiple files specified\n");
@ -2785,6 +2812,7 @@ main(int argc, char **argv)
vcp->vc_verbose = verbose; vcp->vc_verbose = verbose;
vcp->vc_result_file = result_file; vcp->vc_result_file = result_file;
vcp->vc_remove_on_match = remove_on_match; vcp->vc_remove_on_match = remove_on_match;
vcp->vc_pubkey_base = pubkey_base;
if (!vg_context_add_patterns(vcp, patterns, npatterns)) if (!vg_context_add_patterns(vcp, patterns, npatterns))
return 1; return 1;

48
pattern.c

@ -39,6 +39,12 @@
* Common code for execution helper * Common code for execution helper
*/ */
EC_KEY *
vg_exec_context_new_key(void)
{
return EC_KEY_new_by_curve_name(NID_secp256k1);
}
int int
vg_exec_context_init(vg_context_t *vcp, vg_exec_context_t *vxcp) vg_exec_context_init(vg_context_t *vcp, vg_exec_context_t *vxcp)
{ {
@ -55,7 +61,7 @@ vg_exec_context_init(vg_context_t *vcp, vg_exec_context_t *vxcp)
vxcp->vxc_bnctx = BN_CTX_new(); vxcp->vxc_bnctx = BN_CTX_new();
assert(vxcp->vxc_bnctx); assert(vxcp->vxc_bnctx);
vxcp->vxc_key = EC_KEY_new_by_curve_name(NID_secp256k1); vxcp->vxc_key = vg_exec_context_new_key();
assert(vxcp->vxc_key); assert(vxcp->vxc_key);
EC_KEY_precompute_mult(vxcp->vxc_key, vxcp->vxc_bnctx); EC_KEY_precompute_mult(vxcp->vxc_key, vxcp->vxc_bnctx);
return 1; return 1;
@ -89,14 +95,24 @@ vg_exec_context_consolidate_key(vg_exec_context_t *vxcp)
void void
vg_exec_context_calc_address(vg_exec_context_t *vxcp) vg_exec_context_calc_address(vg_exec_context_t *vxcp)
{ {
EC_POINT *pubkey;
const EC_GROUP *pgroup; const EC_GROUP *pgroup;
unsigned char eckey_buf[96], hash1[32], hash2[20]; unsigned char eckey_buf[96], hash1[32], hash2[20];
int len; int len;
vg_exec_context_consolidate_key(vxcp); vg_exec_context_consolidate_key(vxcp);
pgroup = EC_KEY_get0_group(vxcp->vxc_key); pgroup = EC_KEY_get0_group(vxcp->vxc_key);
pubkey = EC_POINT_new(pgroup);
EC_POINT_copy(pubkey, EC_KEY_get0_public_key(vxcp->vxc_key));
if (vxcp->vxc_vc->vc_pubkey_base) {
EC_POINT_add(pgroup,
pubkey,
pubkey,
vxcp->vxc_vc->vc_pubkey_base,
vxcp->vxc_bnctx);
}
len = EC_POINT_point2oct(pgroup, len = EC_POINT_point2oct(pgroup,
EC_KEY_get0_public_key(vxcp->vxc_key), pubkey,
POINT_CONVERSION_UNCOMPRESSED, POINT_CONVERSION_UNCOMPRESSED,
eckey_buf, eckey_buf,
sizeof(eckey_buf), sizeof(eckey_buf),
@ -105,6 +121,7 @@ vg_exec_context_calc_address(vg_exec_context_t *vxcp)
RIPEMD160(hash1, sizeof(hash1), hash2); RIPEMD160(hash1, sizeof(hash1), hash2);
memcpy(&vxcp->vxc_binres[1], memcpy(&vxcp->vxc_binres[1],
hash2, 20); hash2, 20);
EC_POINT_free(pubkey);
} }
enum { enum {
@ -310,10 +327,30 @@ vg_output_match(vg_context_t *vcp, EC_KEY *pkey, const char *pattern)
int len; int len;
int isscript = (vcp->vc_format == VCF_SCRIPT); int isscript = (vcp->vc_format == VCF_SCRIPT);
EC_POINT *ppnt;
int free_ppnt = 0;
if (vcp->vc_pubkey_base) {
ppnt = EC_POINT_new(EC_KEY_get0_group(pkey));
EC_POINT_copy(ppnt, EC_KEY_get0_public_key(pkey));
EC_POINT_add(EC_KEY_get0_group(pkey),
ppnt,
ppnt,
vcp->vc_pubkey_base,
NULL);
free_ppnt = 1;
keytype = "PrivkeyPart";
} else {
ppnt = (EC_POINT *) EC_KEY_get0_public_key(pkey);
}
assert(EC_KEY_check_key(pkey)); assert(EC_KEY_check_key(pkey));
vg_encode_address(pkey, vcp->vc_pubkeytype, addr_buf); vg_encode_address(ppnt,
EC_KEY_get0_group(pkey),
vcp->vc_pubkeytype, addr_buf);
if (isscript) if (isscript)
vg_encode_script_address(pkey, vcp->vc_addrtype, addr2_buf); vg_encode_script_address(ppnt,
EC_KEY_get0_group(pkey),
vcp->vc_addrtype, addr2_buf);
if (vcp->vc_key_protect_pass) { if (vcp->vc_key_protect_pass) {
len = vg_protect_encode_privkey(privkey_buf, len = vg_protect_encode_privkey(privkey_buf,
@ -349,7 +386,6 @@ 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)) {
@ -379,6 +415,8 @@ vg_output_match(vg_context_t *vcp, EC_KEY *pkey, const char *pattern)
fclose(fp); fclose(fp);
} }
} }
if (free_ppnt)
EC_POINT_free(ppnt);
} }

4
pattern.h

@ -54,12 +54,13 @@ extern int vg_exec_context_init(vg_context_t *vcp, vg_exec_context_t *vxcp);
extern void vg_exec_context_del(vg_exec_context_t *vxcp); extern void vg_exec_context_del(vg_exec_context_t *vxcp);
extern void vg_exec_context_consolidate_key(vg_exec_context_t *vxcp); 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);
/* 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); char ** const patterns, int npatterns);
@ -89,6 +90,7 @@ struct _vg_context_s {
vg_hash160_sort_func_t vc_hash160_sort; 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;
}; };

24
util.c

@ -236,7 +236,8 @@ out:
} }
void void
vg_encode_address(const EC_KEY *pkey, int addrtype, char *result) vg_encode_address(const EC_POINT *ppoint, const EC_GROUP *pgroup,
int addrtype, char *result)
{ {
unsigned char eckey_buf[128], *pend; unsigned char eckey_buf[128], *pend;
unsigned char binres[21] = {0,}; unsigned char binres[21] = {0,};
@ -244,8 +245,13 @@ vg_encode_address(const EC_KEY *pkey, int addrtype, char *result)
pend = eckey_buf; pend = eckey_buf;
i2o_ECPublicKey((EC_KEY*)pkey, &pend); EC_POINT_point2oct(pgroup,
ppoint,
POINT_CONVERSION_UNCOMPRESSED,
eckey_buf,
sizeof(eckey_buf),
NULL);
pend = eckey_buf + 0x41;
binres[0] = addrtype; binres[0] = addrtype;
SHA256(eckey_buf, pend - eckey_buf, hash1); SHA256(eckey_buf, pend - eckey_buf, hash1);
RIPEMD160(hash1, sizeof(hash1), &binres[1]); RIPEMD160(hash1, sizeof(hash1), &binres[1]);
@ -254,7 +260,8 @@ vg_encode_address(const EC_KEY *pkey, int addrtype, char *result)
} }
void void
vg_encode_script_address(const EC_KEY *pkey, int addrtype, char *result) vg_encode_script_address(const EC_POINT *ppoint, const EC_GROUP *pgroup,
int addrtype, char *result)
{ {
unsigned char script_buf[69]; unsigned char script_buf[69];
unsigned char *eckey_buf = script_buf + 2; unsigned char *eckey_buf = script_buf + 2;
@ -267,9 +274,12 @@ vg_encode_script_address(const EC_KEY *pkey, int addrtype, char *result)
script_buf[67] = 0x51; // OP_1 script_buf[67] = 0x51; // OP_1
script_buf[68] = 0xae; // OP_CHECKMULTISIG script_buf[68] = 0xae; // OP_CHECKMULTISIG
i2o_ECPublicKey((EC_KEY*)pkey, &eckey_buf); EC_POINT_point2oct(pgroup,
assert(eckey_buf - script_buf == 67); ppoint,
POINT_CONVERSION_UNCOMPRESSED,
eckey_buf,
65,
NULL);
binres[0] = addrtype; binres[0] = addrtype;
SHA256(script_buf, 69, hash1); SHA256(script_buf, 69, hash1);
RIPEMD160(hash1, sizeof(hash1), &binres[1]); RIPEMD160(hash1, sizeof(hash1), &binres[1]);

7
util.h

@ -36,8 +36,11 @@ extern void dumpbn(const BIGNUM *bn);
extern void vg_b58_encode_check(void *buf, size_t len, char *result); 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 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_address(const EC_POINT *ppoint, const EC_GROUP *pgroup,
extern void vg_encode_script_address(const EC_KEY *pkey, int addrtype, char *result); int addrtype, char *result);
extern void vg_encode_script_address(const EC_POINT *ppoint,
const EC_GROUP *pgroup,
int addrtype, char *result);
extern void vg_encode_privkey(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_set_privkey(const BIGNUM *bnpriv, EC_KEY *pkey);
extern int vg_decode_privkey(const char *b58encoded, extern int vg_decode_privkey(const char *b58encoded,

34
vanitygen.c

@ -304,6 +304,13 @@ vg_thread_loop(void *arg)
npoints++; npoints++;
vxcp->vxc_delta = 0; vxcp->vxc_delta = 0;
if (vcp->vc_pubkey_base)
EC_POINT_add(pgroup,
ppnt[0],
ppnt[0],
vcp->vc_pubkey_base,
vxcp->vxc_bnctx);
for (nbatch = 1; for (nbatch = 1;
(nbatch < ptarraysize) && (npoints < rekey_at); (nbatch < ptarraysize) && (npoints < rekey_at);
nbatch++, npoints++) { nbatch++, npoints++) {
@ -468,6 +475,7 @@ usage(const char *name)
"-T Generate bitcoin testnet address\n" "-T Generate bitcoin testnet address\n"
"-X <version> Generate address with the given version\n" "-X <version> Generate address with the given version\n"
"-F <format> Generate address with the given format (pubkey or script)\n" "-F <format> Generate address with the given format (pubkey or script)\n"
"-P <pubkey> Specify base public key for piecewise key generation\n"
"-e Encrypt private keys, prompt for password\n" "-e Encrypt private keys, prompt for password\n"
"-E <password> Encrypt private keys with <password> (UNSAFE)\n" "-E <password> Encrypt private keys with <password> (UNSAFE)\n"
"-t <threads> Set number of worker threads (Default: number of CPUs)\n" "-t <threads> Set number of worker threads (Default: number of CPUs)\n"
@ -501,8 +509,9 @@ main(int argc, char **argv)
int npatterns = 0; int npatterns = 0;
int nthreads = 0; int nthreads = 0;
vg_context_t *vcp = NULL; vg_context_t *vcp = NULL;
EC_POINT *pubkey_base = NULL;
while ((opt = getopt(argc, argv, "vqrikeE:NTXF:t:h?f:o:s:")) != -1) { while ((opt = getopt(argc, argv, "vqrikeE:P:NTXF:t:h?f:o:s:")) != -1) {
switch (opt) { switch (opt) {
case 'v': case 'v':
verbose = 2; verbose = 2;
@ -538,13 +547,31 @@ main(int argc, char **argv)
if (!strcmp(optarg, "script")) if (!strcmp(optarg, "script"))
format = VCF_SCRIPT; format = VCF_SCRIPT;
else else
if (strcmp(optarg, "pubkey")) if (strcmp(optarg, "pubkey")) {
{
fprintf(stderr, fprintf(stderr,
"Invalid format '%s'\n", optarg); "Invalid format '%s'\n", optarg);
return 1; return 1;
} }
break; break;
case 'P': {
if (pubkey_base != NULL) {
fprintf(stderr,
"Multiple base pubkeys specified\n");
return 1;
}
EC_KEY *pkey = vg_exec_context_new_key();
pubkey_base = EC_POINT_hex2point(
EC_KEY_get0_group(pkey),
optarg, NULL, NULL);
EC_KEY_free(pkey);
if (pubkey_base == NULL) {
fprintf(stderr,
"Invalid base pubkey\n");
return 1;
}
break;
}
case 'e': case 'e':
prompt_password = 1; prompt_password = 1;
break; break;
@ -675,6 +702,7 @@ main(int argc, char **argv)
vcp->vc_remove_on_match = remove_on_match; vcp->vc_remove_on_match = remove_on_match;
vcp->vc_format = format; vcp->vc_format = format;
vcp->vc_pubkeytype = pubkeytype; vcp->vc_pubkeytype = pubkeytype;
vcp->vc_pubkey_base = pubkey_base;
if (!vg_context_add_patterns(vcp, patterns, npatterns)) if (!vg_context_add_patterns(vcp, patterns, npatterns))
return 1; return 1;

Loading…
Cancel
Save