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

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;
  • 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 Jan 2 at 11:15
  • the check public key seems to work perfectly fine though – Dan Minh Toan Jan 2 at 11:25
  • 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 >= 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.GoodLuck – MCCCS Jan 2 at 12:21
  • You’re welcome. Let me know if you’re stuck or it doesn’t work. – MCCCS Jan 3 at 3:41
  • 1
    @DanMinhToan Is this what you're looking for: github.com/samr7/vanitygen/blob/master/oclengine.c#L1906 – MCCCS Feb 13 at 13:10

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.