Modify vanitygen to generate from massive amount of given private key

0

I just using vanitygen recently & figure how to create address from a given hex private key, this is my code

while (!vcp->vc_halt) {
         if (++npoints >= rekey_at) {
            vg_exec_context_upgrade_lock(vxcp);
            /* Generate a new random private key */
            BIGNUM start;
            BIGNUM *res;
            BN_init(&start);
            res = &start;
            BN_hex2bn(&res, "3B1BCC5A67F38853810972B1DA8A67148FAD78C6CD6F22B2C823D141BE59C81C"); //Set up hex private key
            vg_set_privkey(res, pkey);
            //EC_KEY_generate_key(pkey); default code
            if (vcp->vc_privkey_prefix_length > 0) {
                BIGNUM *pkbn = BN_dup(EC_KEY_get0_private_key(pkey));
                unsigned char pkey_arr[32];
                assert(BN_bn2bin(pkbn, pkey_arr) < 33);
                memcpy((char *)pkey_arr, vcp->vc_privkey_prefix, vcp->vc_privkey_prefix_length);
                for (int i = 0; i < vcp->vc_privkey_prefix_length / 2; i++) {
                    int k = pkey_arr[i];
                    pkey_arr[i] = pkey_arr[vcp->vc_privkey_prefix_length - 1 - i];
                    pkey_arr[vcp->vc_privkey_prefix_length - 1 - i] = k;
                }
                BN_bin2bn(pkey_arr, 32, pkbn);
                EC_KEY_set_private_key(pkey, pkbn);

                EC_POINT *origin = EC_POINT_new(pgroup);
                EC_POINT_mul(pgroup, origin, pkbn, NULL, NULL, vxcp->vxc_bnctx);
                EC_KEY_set_public_key(pkey, origin);
            }
            npoints = 0;

            /* Determine rekey interval */
            EC_GROUP_get_order(pgroup, vxcp->vxc_bntmp,
                vxcp->vxc_bnctx);
            BN_sub(vxcp->vxc_bntmp2,
                vxcp->vxc_bntmp,
                EC_KEY_get0_private_key(pkey));
            rekey_at = BN_get_word(vxcp->vxc_bntmp2);
            if ((rekey_at == 0xffffffffL) || (rekey_at > rekey_max))
                rekey_at = rekey_max;
            assert(rekey_at > 0);

            EC_POINT_copy(ppnt[0], EC_KEY_get0_public_key(pkey));
            vg_exec_context_downgrade_lock(vxcp);

            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++) {
                EC_POINT_add(pgroup,
                    ppnt[nbatch],
                    ppnt[nbatch - 1],
                    pgen, vxcp->vxc_bnctx);
            }

         }
        else {
            /*
             * Common case
             *
             * EC_POINT_add() can skip a few multiplies if
             * one or both inputs are affine (Z_is_one).
             * This is the case for every point in ppnt, as
             * well as pbatchinc.
             */
            assert(nbatch == ptarraysize);
            for (nbatch = 0;
                (nbatch < ptarraysize) && (npoints < rekey_at);
                nbatch++, npoints++) {
                EC_POINT_add(pgroup,
                    ppnt[nbatch],
                    ppnt[nbatch],
                    pbatchinc,
                    vxcp->vxc_bnctx);
            }
        }

        /*
         * The single most expensive operation performed in this
         * loop is modular inversion of ppnt->Z.  There is an
         * algorithm implemented in OpenSSL to do batched inversion
         * that only does one actual BN_mod_inverse(), and saves
         * a _lot_ of time.
         *
         * To take advantage of this, we batch up a few points,
         * and feed them to EC_POINTs_make_affine() below.
         */

        EC_POINTs_make_affine(pgroup, nbatch, ppnt, vxcp->vxc_bnctx);

        for (i = 0; i < nbatch; i++, vxcp->vxc_delta++) {
            /* Hash the public key */
            len = EC_POINT_point2oct(pgroup, ppnt[i],
                (vcp->vc_compressed) ? POINT_CONVERSION_COMPRESSED : POINT_CONVERSION_UNCOMPRESSED,
                eckey_buf,
                (vcp->vc_compressed) ? 33 : 65,
                vxcp->vxc_bnctx);
            assert(len == 65 || len == 33);

            SHA256(hash_buf, hash_len, hash1);
            RIPEMD160(hash1, sizeof(hash1), &vxcp->vxc_binres[1]);

            switch (test_func(vxcp)) {
            case 1:
                npoints = 0;
                rekey_at = 0;
                i = nbatch;
                break;
            case 2:
                goto out;
            default:
                break;
            }
        }

        c += i;
        if (c >= output_interval) {
            output_interval = vg_output_timing(vcp, c, &tvstart);
            if (output_interval > 250000)
                output_interval = 250000;
            c = 0;
        }

        vg_exec_context_yield(vxcp);
    }

I try to run the program & expect result like this

Address: 14m54cDDgC96ptqTz66431PoD7f6CPmsHE

Priv key: 5JGKRxEqgMQU1SC86uJHt6Bp6hBZCyea6PHfWvPDpuMsYFiiQpE

Technically it work when i generate a single address everytime but when i use -k to keep it generating it turn up lots of random address not as i intented to

Address: 18b9xT21uxvmwU31whAcnW7ytag7Qdz5wH

Address: 1LKHy9Y8pMTsNdwfZXYexKegNvXc6UTm9C

Address: 16esSUcRDz1um1bBWhBynSvmJUqXZWTHd7

....

What i understand is it keep multiply value of my given key to make new address & it take a while to reach loop to set private key in pkey again. Is there any way that i can skip this part & make it generate pure new private key everytime. I intened to replace this with my own random key generator to recover my paper wallet, thank you

Dan Minh Toan

Posted 2019-01-02T07:43:18.843

Reputation: 28

Answers

1

You can change

        switch (test_func(vxcp)) {
        case 1:
            npoints = 0;
            rekey_at = 0;
            i = nbatch;
            break;
        case 2:
            goto out;
        default:
            break;
        }

to

        switch (test_func(vxcp)) {
        case 2:
            goto out;
        default:
            npoints = 0;
            rekey_at = 0;
            i = nbatch;
            break;
        }

You can also replace the test_func with a function in which you check if the public key is the one you're looking for. Since you'll always use the -k option, you can replace the switch with

        test_func(vxcp);
        npoints = 0;
        rekey_at = 0;
        i = nbatch;

MCCCS

Posted 2019-01-02T07:43:18.843

Reputation: 5 827

OK, i just change it & it work but look like the program doesn't use 100% CPU anymore & it only generate few thoundsands private key per seconds. Do you have any suggestion?Dan Minh Toan 2019-01-02T11:15:32.443

the check public key seems to work perfectly fine thoughDan Minh Toan 2019-01-02T11:25:12.540

You should add "array of private keys" in "execute context" (vxcp) in pattern.h. Above the part that contains /* Common case, you should call the RNG for all of the points and set the points to the public keys. You should also remove the condition if (++npoints &gt;= rekey_at) { and the else part associated with it. In vg_exec_context_consolidate_key, which is called by the test_func, youshould change the pointer to private key so that it points to your array you added to execute_context in pattern.h and takes the index of pk.Lastly, increasing ptarraysize should improveperfomnc.GoodLuckMCCCS 2019-01-02T12:21:40.283

You’re welcome. Let me know if you’re stuck or it doesn’t work.MCCCS 2019-01-03T03:41:04.693

hi, it's me again. I want to modify the same fuction on GPU, can you suggest some idea to run it on oclvanitygen without multiply key? Ididn't have expericnce with opencl. The core function was in "oclengine.c" but there're no "if (++npoints >= rekey_at)" so it was hard to know where to edit the codeDan Minh Toan 2019-02-13T11:11:31.473

1

@DanMinhToan Is this what you're looking for: https://github.com/samr7/vanitygen/blob/master/oclengine.c#L1906

MCCCS 2019-02-13T13:10:30.933

yes, it has the same key generator but the multiply funtion was differentDan Minh Toan 2019-02-13T14:37:23.330

i tried to reduce the rekey_max value to 1 to make sure it use the seed every time generate a new privkey(normally, it'll search 100000000 keys before use the seed again), turn out it decrease the performance as well (about 85keys/s), if i change from a single EC_key to key array, there're error show up. How can i make it use only rng seed but maximize the performance at the same time?Dan Minh Toan 2019-02-25T07:14:15.093