Skip to content

Commit

Permalink
Add support for base public keys to vanitygen and oclvanitygen.
Browse files Browse the repository at this point in the history
Add partial private key combining feature to keyconv.
  • Loading branch information
samr7 committed Jun 30, 2012
1 parent 6c0f8a3 commit 9ac1c5e
Show file tree
Hide file tree
Showing 7 changed files with 169 additions and 24 deletions.
46 changes: 41 additions & 5 deletions keyconv.c
Original file line number Diff line number Diff line change
Expand Up @@ -24,10 +24,11 @@ usage(const char *progname)
{
fprintf(stderr,
"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"
"-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);
}

Expand All @@ -40,6 +41,7 @@ main(int argc, char **argv)
char pbuf[1024];
const char *key_in;
const char *pass_in = NULL;
const char *key2_in = NULL;
EC_KEY *pkey;
int parameter_group = -1;
int privtype, addrtype;
Expand All @@ -48,7 +50,7 @@ main(int argc, char **argv)
int opt;
int res;

while ((opt = getopt(argc, argv, "8E:e")) != -1) {
while ((opt = getopt(argc, argv, "8E:ec:")) != -1) {
switch (opt) {
case '8':
pkcs8 = 1;
Expand All @@ -70,6 +72,9 @@ main(int argc, char **argv)
}
pass_prompt = 1;
break;
case 'c':
key2_in = optarg;
break;
default:
usage(argv[0]);
return 1;
Expand Down Expand Up @@ -101,6 +106,33 @@ main(int argc, char **argv)
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) {
res = EVP_read_pw_string(pwbuf, sizeof(pwbuf),
"Enter password:", 1);
Expand Down Expand Up @@ -138,13 +170,17 @@ main(int argc, char **argv)
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("Protkey: %s\n", ecprot);
}

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);
vg_encode_privkey(pkey, privtype, ecprot);
printf("Privkey: %s\n", ecprot);
Expand Down
30 changes: 29 additions & 1 deletion oclvanitygen.c
Original file line number Diff line number Diff line change
Expand Up @@ -2124,6 +2124,14 @@ vg_opencl_loop(vg_context_t *vcp, cl_device_id did, int safe_mode, int verify,

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 */
for (i = 1; i < ncols; i++) {
EC_POINT_add(pgroup,
Expand Down Expand Up @@ -2590,11 +2598,12 @@ main(int argc, char **argv)
int safe_mode = 0;
vg_context_t *vcp = NULL;
cl_device_id did;
EC_POINT *pubkey_base = NULL;
const char *result_file = NULL;
const char *key_password = NULL;

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) {
case 'v':
verbose = 2;
Expand Down Expand Up @@ -2684,6 +2693,24 @@ main(int argc, char **argv)
case 'S':
safe_mode = 1;
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':
if (fp) {
fprintf(stderr, "Multiple files specified\n");
Expand Down Expand Up @@ -2785,6 +2812,7 @@ main(int argc, char **argv)
vcp->vc_verbose = verbose;
vcp->vc_result_file = result_file;
vcp->vc_remove_on_match = remove_on_match;
vcp->vc_pubkey_base = pubkey_base;

if (!vg_context_add_patterns(vcp, patterns, npatterns))
return 1;
Expand Down
48 changes: 43 additions & 5 deletions pattern.c
Original file line number Diff line number Diff line change
Expand Up @@ -39,6 +39,12 @@
* Common code for execution helper
*/

EC_KEY *
vg_exec_context_new_key(void)
{
return EC_KEY_new_by_curve_name(NID_secp256k1);
}

int
vg_exec_context_init(vg_context_t *vcp, vg_exec_context_t *vxcp)
{
Expand All @@ -55,7 +61,7 @@ vg_exec_context_init(vg_context_t *vcp, vg_exec_context_t *vxcp)

vxcp->vxc_bnctx = BN_CTX_new();
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);
EC_KEY_precompute_mult(vxcp->vxc_key, vxcp->vxc_bnctx);
return 1;
Expand Down Expand Up @@ -89,14 +95,24 @@ vg_exec_context_consolidate_key(vg_exec_context_t *vxcp)
void
vg_exec_context_calc_address(vg_exec_context_t *vxcp)
{
EC_POINT *pubkey;
const EC_GROUP *pgroup;
unsigned char eckey_buf[96], hash1[32], hash2[20];
int len;

vg_exec_context_consolidate_key(vxcp);
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,
EC_KEY_get0_public_key(vxcp->vxc_key),
pubkey,
POINT_CONVERSION_UNCOMPRESSED,
eckey_buf,
sizeof(eckey_buf),
Expand All @@ -105,6 +121,7 @@ vg_exec_context_calc_address(vg_exec_context_t *vxcp)
RIPEMD160(hash1, sizeof(hash1), hash2);
memcpy(&vxcp->vxc_binres[1],
hash2, 20);
EC_POINT_free(pubkey);
}

enum {
Expand Down Expand Up @@ -310,10 +327,30 @@ vg_output_match(vg_context_t *vcp, EC_KEY *pkey, const char *pattern)
int len;
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));
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)
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) {
len = vg_protect_encode_privkey(privkey_buf,
Expand Down Expand Up @@ -349,7 +386,6 @@ vg_output_match(vg_context_t *vcp, EC_KEY *pkey, const char *pattern)
printf("Privkey (ASN1): ");
dumphex(key_buf, len);
}

}

if (!vcp->vc_result_file || (vcp->vc_verbose > 0)) {
Expand Down Expand Up @@ -379,6 +415,8 @@ vg_output_match(vg_context_t *vcp, EC_KEY *pkey, const char *pattern)
fclose(fp);
}
}
if (free_ppnt)
EC_POINT_free(ppnt);
}


Expand Down
4 changes: 3 additions & 1 deletion pattern.h
Original file line number Diff line number Diff line change
Expand Up @@ -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_consolidate_key(vg_exec_context_t *vxcp);
extern void vg_exec_context_calc_address(vg_exec_context_t *vxcp);
extern EC_KEY *vg_exec_context_new_key(void);


/* Implementation-specific lock/unlock/consolidate */
extern void vg_exec_downgrade_lock(vg_exec_context_t *vxcp);
extern int vg_exec_upgrade_lock(vg_exec_context_t *vxcp);


typedef void (*vg_free_func_t)(vg_context_t *);
typedef int (*vg_add_pattern_func_t)(vg_context_t *,
char ** const patterns, int npatterns);
Expand Down Expand Up @@ -89,6 +90,7 @@ struct _vg_context_s {
vg_hash160_sort_func_t vc_hash160_sort;
enum vg_format vc_format;
int vc_pubkeytype;
EC_POINT *vc_pubkey_base;
};


Expand Down
24 changes: 17 additions & 7 deletions util.c
Original file line number Diff line number Diff line change
Expand Up @@ -236,16 +236,22 @@ vg_b58_decode_check(const char *input, void *buf, size_t len)
}

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 binres[21] = {0,};
unsigned char hash1[32];

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;
SHA256(eckey_buf, pend - eckey_buf, hash1);
RIPEMD160(hash1, sizeof(hash1), &binres[1]);
Expand All @@ -254,7 +260,8 @@ vg_encode_address(const EC_KEY *pkey, int addrtype, char *result)
}

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 *eckey_buf = script_buf + 2;
Expand All @@ -267,9 +274,12 @@ vg_encode_script_address(const EC_KEY *pkey, int addrtype, char *result)
script_buf[67] = 0x51; // OP_1
script_buf[68] = 0xae; // OP_CHECKMULTISIG

i2o_ECPublicKey((EC_KEY*)pkey, &eckey_buf);
assert(eckey_buf - script_buf == 67);

EC_POINT_point2oct(pgroup,
ppoint,
POINT_CONVERSION_UNCOMPRESSED,
eckey_buf,
65,
NULL);
binres[0] = addrtype;
SHA256(script_buf, 69, hash1);
RIPEMD160(hash1, sizeof(hash1), &binres[1]);
Expand Down
7 changes: 5 additions & 2 deletions util.h
Original file line number Diff line number Diff line change
Expand Up @@ -36,8 +36,11 @@ 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_script_address(const EC_KEY *pkey, int addrtype, char *result);
extern void vg_encode_address(const EC_POINT *ppoint, const EC_GROUP *pgroup,
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 int vg_set_privkey(const BIGNUM *bnpriv, EC_KEY *pkey);
extern int vg_decode_privkey(const char *b58encoded,
Expand Down
Loading

0 comments on commit 9ac1c5e

Please sign in to comment.