add Litecoin address and compressed address support
This commit is contained in:
16
pattern.c
16
pattern.c
@@ -528,9 +528,14 @@ vg_output_match_console(vg_context_t *vcp, EC_KEY *pkey, const char *pattern)
|
||||
}
|
||||
|
||||
assert(EC_KEY_check_key(pkey));
|
||||
vg_encode_address(ppnt,
|
||||
EC_KEY_get0_group(pkey),
|
||||
vcp->vc_pubkeytype, addr_buf);
|
||||
if (vcp->vc_compressed)
|
||||
vg_encode_address_compressed(ppnt,
|
||||
EC_KEY_get0_group(pkey),
|
||||
vcp->vc_pubkeytype, addr_buf);
|
||||
else
|
||||
vg_encode_address(ppnt,
|
||||
EC_KEY_get0_group(pkey),
|
||||
vcp->vc_pubkeytype, addr_buf);
|
||||
if (isscript)
|
||||
vg_encode_script_address(ppnt,
|
||||
EC_KEY_get0_group(pkey),
|
||||
@@ -550,7 +555,10 @@ vg_output_match_console(vg_context_t *vcp, EC_KEY *pkey, const char *pattern)
|
||||
}
|
||||
}
|
||||
if (!vcp->vc_key_protect_pass) {
|
||||
vg_encode_privkey(pkey, vcp->vc_privtype, privkey_buf);
|
||||
if (vcp->vc_compressed)
|
||||
vg_encode_privkey_compressed(pkey, vcp->vc_privtype, privkey_buf);
|
||||
else
|
||||
vg_encode_privkey(pkey, vcp->vc_privtype, privkey_buf);
|
||||
}
|
||||
|
||||
if (!vcp->vc_result_file || (vcp->vc_verbose > 0)) {
|
||||
|
||||
@@ -88,6 +88,7 @@ enum vg_format {
|
||||
|
||||
/* Application-level context, incl. parameters and global pattern store */
|
||||
struct _vg_context_s {
|
||||
int vc_compressed;
|
||||
int vc_addrtype;
|
||||
int vc_privtype;
|
||||
unsigned long vc_npatterns;
|
||||
|
||||
44
util.c
44
util.c
@@ -259,6 +259,30 @@ vg_encode_address(const EC_POINT *ppoint, const EC_GROUP *pgroup,
|
||||
vg_b58_encode_check(binres, sizeof(binres), result);
|
||||
}
|
||||
|
||||
void
|
||||
vg_encode_address_compressed(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;
|
||||
|
||||
EC_POINT_point2oct(pgroup,
|
||||
ppoint,
|
||||
POINT_CONVERSION_COMPRESSED,
|
||||
eckey_buf,
|
||||
sizeof(eckey_buf),
|
||||
NULL);
|
||||
pend = eckey_buf + 0x21;
|
||||
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_script_address(const EC_POINT *ppoint, const EC_GROUP *pgroup,
|
||||
int addrtype, char *result)
|
||||
@@ -306,6 +330,26 @@ vg_encode_privkey(const EC_KEY *pkey, int addrtype, char *result)
|
||||
vg_b58_encode_check(eckey_buf, 33, result);
|
||||
}
|
||||
|
||||
void
|
||||
vg_encode_privkey_compressed(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]);
|
||||
eckey_buf[nbytes+1] = 1;
|
||||
|
||||
vg_b58_encode_check(eckey_buf, 34, result);
|
||||
}
|
||||
|
||||
int
|
||||
vg_set_privkey(const BIGNUM *bnpriv, EC_KEY *pkey)
|
||||
{
|
||||
|
||||
3
util.h
3
util.h
@@ -38,10 +38,13 @@ extern int vg_b58_decode_check(const char *input, void *buf, size_t len);
|
||||
|
||||
extern void vg_encode_address(const EC_POINT *ppoint, const EC_GROUP *pgroup,
|
||||
int addrtype, char *result);
|
||||
extern void vg_encode_address_compressed(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 void vg_encode_privkey_compressed(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);
|
||||
|
||||
28
vanitygen.c
28
vanitygen.c
@@ -114,7 +114,7 @@ vg_thread_loop(void *arg)
|
||||
|
||||
} else {
|
||||
eckey_buf = hash_buf;
|
||||
hash_len = 65;
|
||||
hash_len = (vcp->vc_compressed)?33:65;
|
||||
}
|
||||
|
||||
while (!vcp->vc_halt) {
|
||||
@@ -194,11 +194,11 @@ vg_thread_loop(void *arg)
|
||||
for (i = 0; i < nbatch; i++, vxcp->vxc_delta++) {
|
||||
/* Hash the public key */
|
||||
len = EC_POINT_point2oct(pgroup, ppnt[i],
|
||||
POINT_CONVERSION_UNCOMPRESSED,
|
||||
(vcp->vc_compressed)?POINT_CONVERSION_COMPRESSED:POINT_CONVERSION_UNCOMPRESSED,
|
||||
eckey_buf,
|
||||
65,
|
||||
(vcp->vc_compressed)?33:65,
|
||||
vxcp->vxc_bnctx);
|
||||
assert(len == 65);
|
||||
assert(len == 65 || len == 33);
|
||||
|
||||
SHA256(hash_buf, hash_len, hash1);
|
||||
RIPEMD160(hash1, sizeof(hash1), &vxcp->vxc_binres[1]);
|
||||
@@ -311,10 +311,11 @@ usage(const char *name)
|
||||
"-i Case-insensitive prefix search\n"
|
||||
"-k Keep pattern and continue search after finding a match\n"
|
||||
"-1 Stop after first match\n"
|
||||
"-L Generate litecoin address\n"
|
||||
"-N Generate namecoin address\n"
|
||||
"-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"
|
||||
"-F <format> Generate address with the given format (pubkey, compressed, 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"
|
||||
@@ -358,11 +359,15 @@ main(int argc, char **argv)
|
||||
int pattfpi[MAX_FILE];
|
||||
int npattfp = 0;
|
||||
int pattstdin = 0;
|
||||
int compressed = 0;
|
||||
|
||||
int i;
|
||||
|
||||
while ((opt = getopt(argc, argv, "vqnrik1eE:P:NTX:F:t:h?f:o:s:")) != -1) {
|
||||
while ((opt = getopt(argc, argv, "Lvqnrik1eE:P:NTX:F:t:h?f:o:s:")) != -1) {
|
||||
switch (opt) {
|
||||
case 'c':
|
||||
compressed = 1;
|
||||
break;
|
||||
case 'v':
|
||||
verbose = 2;
|
||||
break;
|
||||
@@ -389,6 +394,11 @@ main(int argc, char **argv)
|
||||
privtype = 180;
|
||||
scriptaddrtype = -1;
|
||||
break;
|
||||
case 'L':
|
||||
addrtype = 48;
|
||||
privtype = 176;
|
||||
scriptaddrtype = -1;
|
||||
break;
|
||||
case 'T':
|
||||
addrtype = 111;
|
||||
privtype = 239;
|
||||
@@ -402,7 +412,10 @@ main(int argc, char **argv)
|
||||
case 'F':
|
||||
if (!strcmp(optarg, "script"))
|
||||
format = VCF_SCRIPT;
|
||||
else
|
||||
else
|
||||
if (!strcmp(optarg, "compressed"))
|
||||
compressed = 1;
|
||||
else
|
||||
if (strcmp(optarg, "pubkey")) {
|
||||
fprintf(stderr,
|
||||
"Invalid format '%s'\n", optarg);
|
||||
@@ -544,6 +557,7 @@ main(int argc, char **argv)
|
||||
caseinsensitive);
|
||||
}
|
||||
|
||||
vcp->vc_compressed = compressed;
|
||||
vcp->vc_verbose = verbose;
|
||||
vcp->vc_result_file = result_file;
|
||||
vcp->vc_remove_on_match = remove_on_match;
|
||||
|
||||
Reference in New Issue
Block a user