user88630: 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

user38618: 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;


88630: <p>I just using vanitygen recently &amp; figure how to create address from a given hex private key, this is my code</p>

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

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

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

            npoints++;
            vxcp-&gt;vxc_delta = 0;

            if (vcp-&gt;vc_pubkey_base)
                EC_POINT_add(pgroup,
                    ppnt[0],
                    ppnt[0],
                    vcp-&gt;vc_pubkey_base,
                    vxcp-&gt;vxc_bnctx);

            for (nbatch = 1;
                (nbatch &lt; ptarraysize) &amp;&amp; (npoints &lt; rekey_at);
                nbatch++, npoints++) {
                EC_POINT_add(pgroup,
                    ppnt[nbatch],
                    ppnt[nbatch - 1],
                    pgen, vxcp-&gt;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 &lt; ptarraysize) &amp;&amp; (npoints &lt; rekey_at);
                nbatch++, npoints++) {
                EC_POINT_add(pgroup,
                    ppnt[nbatch],
                    ppnt[nbatch],
                    pbatchinc,
                    vxcp-&gt;vxc_bnctx);
            }
        }

        /*
         * The single most expensive operation performed in this
         * loop is modular inversion of ppnt-&gt;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-&gt;vxc_bnctx);

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

            SHA256(hash_buf, hash_len, hash1);
            RIPEMD160(hash1, sizeof(hash1), &amp;vxcp-&gt;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 &gt;= output_interval) {
            output_interval = vg_output_timing(vcp, c, &amp;tvstart);
            if (output_interval &gt; 250000)
                output_interval = 250000;
            c = 0;
        }

        vg_exec_context_yield(vxcp);
    }
</code></pre>

<p>I try to run the program &amp; expect result like this</p>

<blockquote>
  <p>Address: 14m54cDDgC96ptqTz66431PoD7f6CPmsHE </p>
  
  <p>Priv key: 5JGKRxEqgMQU1SC86uJHt6Bp6hBZCyea6PHfWvPDpuMsYFiiQpE</p>
</blockquote>

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

<blockquote>
  <p>Address: 18b9xT21uxvmwU31whAcnW7ytag7Qdz5wH</p>
  
  <p>Address: 1LKHy9Y8pMTsNdwfZXYexKegNvXc6UTm9C</p>
  
  <p>Address: 16esSUcRDz1um1bBWhBynSvmJUqXZWTHd7</p>
  
  <p>....</p>
</blockquote>

<p>What i understand is it keep multiply value of my given key to make new address &amp; it take a while to reach loop to set private key in <code>pkey</code> again. Is there any way that i can skip this part &amp; 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</p>
 38618: <p>You can change</p>

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

<p>to</p>

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

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

<pre><code>        test_func(vxcp);
        npoints = 0;
        rekey_at = 0;
        i = nbatch;
</code></pre>
