Browse Source

Add support for base public keys to vanitygen and oclvanitygen.

Add partial private key combining feature to keyconv.
master
samr7 12 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) @@ -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) @@ -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) @@ -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) @@ -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) @@ -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) @@ -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);

30
oclvanitygen.c

@ -2124,6 +2124,14 @@ l_rekey: @@ -2124,6 +2124,14 @@ l_rekey:
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) @@ -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) @@ -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) @@ -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;

48
pattern.c

@ -39,6 +39,12 @@ @@ -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) @@ -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) @@ -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) @@ -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) @@ -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) @@ -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) @@ -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);
}

4
pattern.h

@ -54,12 +54,13 @@ extern int vg_exec_context_init(vg_context_t *vcp, vg_exec_context_t *vxcp); @@ -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 { @@ -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;
};

24
util.c

@ -236,7 +236,8 @@ out: @@ -236,7 +236,8 @@ out:
}
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,};
@ -244,8 +245,13 @@ vg_encode_address(const EC_KEY *pkey, int addrtype, char *result) @@ -244,8 +245,13 @@ vg_encode_address(const EC_KEY *pkey, int addrtype, char *result)
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) @@ -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) @@ -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]);

7
util.h

@ -36,8 +36,11 @@ extern void dumpbn(const BIGNUM *bn); @@ -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,

34
vanitygen.c

@ -304,6 +304,13 @@ vg_thread_loop(void *arg) @@ -304,6 +304,13 @@ vg_thread_loop(void *arg)
npoints++;
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;
(nbatch < ptarraysize) && (npoints < rekey_at);
nbatch++, npoints++) {
@ -468,6 +475,7 @@ usage(const char *name) @@ -468,6 +475,7 @@ usage(const char *name)
"-T Generate bitcoin testnet address\n"
"-X <version> Generate address with the given version\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 <password> Encrypt private keys with <password> (UNSAFE)\n"
"-t <threads> Set number of worker threads (Default: number of CPUs)\n"
@ -501,8 +509,9 @@ main(int argc, char **argv) @@ -501,8 +509,9 @@ main(int argc, char **argv)
int npatterns = 0;
int nthreads = 0;
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) {
case 'v':
verbose = 2;
@ -538,13 +547,31 @@ main(int argc, char **argv) @@ -538,13 +547,31 @@ main(int argc, char **argv)
if (!strcmp(optarg, "script"))
format = VCF_SCRIPT;
else
if (strcmp(optarg, "pubkey"))
{
if (strcmp(optarg, "pubkey")) {
fprintf(stderr,
"Invalid format '%s'\n", optarg);
return 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 'e':
prompt_password = 1;
break;
@ -675,6 +702,7 @@ main(int argc, char **argv) @@ -675,6 +702,7 @@ main(int argc, char **argv)
vcp->vc_remove_on_match = remove_on_match;
vcp->vc_format = format;
vcp->vc_pubkeytype = pubkeytype;
vcp->vc_pubkey_base = pubkey_base;
if (!vg_context_add_patterns(vcp, patterns, npatterns))
return 1;

Loading…
Cancel
Save