Permalink
Browse files

Add support for base public keys to vanitygen and oclvanitygen.

Add partial private key combining feature to keyconv.
  • Loading branch information...
1 parent 6c0f8a3 commit 9ac1c5e21d74f9476acfd0f44fad8b626d1d2595 @samr7 committed Jun 30, 2012
Showing with 169 additions and 24 deletions.
  1. +41 −5 keyconv.c
  2. +29 −1 oclvanitygen.c
  3. +43 −5 pattern.c
  4. +3 −1 pattern.h
  5. +17 −7 util.c
  6. +5 −2 util.h
  7. +31 −3 vanitygen.c
View
@@ -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);
}
@@ -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;
@@ -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;
@@ -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;
@@ -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);
@@ -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);
View
@@ -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,
@@ -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;
@@ -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");
@@ -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;
View
@@ -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)
{
@@ -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;
@@ -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),
@@ -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 {
@@ -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,
@@ -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)) {
@@ -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);
}
View
@@ -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);
@@ -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;
};
View
24 util.c
@@ -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]);
@@ -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;
@@ -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]);
View
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 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,
Oops, something went wrong.

0 comments on commit 9ac1c5e

Please sign in to comment.