Development

修改 vanitygen 以從大量給定的私鑰生成

  • January 2, 2019

我最近才使用 vanitygen 並弄清楚如何從給定的十六進制私鑰創建地址,這是我的程式碼

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);
   }

我嘗試執行程序並期望這樣的結果

地址:14m54cDDgC96ptqTz66431PoD7f6CPmsHE

私鑰:5JGKRxEqgMQU1SC86uJHt6Bp6hBZCyea6PHfWvPDpuMsYFiiQpE

從技術上講,當我每次生成一個地址時它都可以工作,但是當我-k用來保持它生成它時,它會出現很多隨機地址,而不是我想要的

地址:18b9xT21uxvmwU31whAcnW7ytag7Qdz5wH

地址:1LKHy9Y8pMTsNdwfZXYexKegNvXc6UTm9C

地址:16esSUcRDz1um1bBWhBynSvmJUqXZWTHd7

….

我的理解是它保持我給定密鑰的乘法值以創建新地址並且需要一段時間才能到達循環以再次設置私鑰pkey。有什麼方法可以跳過這部分並讓它每次都生成純新私鑰。我打算用我自己的隨機密鑰生成器替換它來恢復我的紙錢包,謝謝

你可以改變

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

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

您還可以將 替換為test_func檢查公鑰是否是您要查找的函式的函式。由於您將始終使用該-k選項,因此您可以switch

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

引用自:https://bitcoin.stackexchange.com/questions/83309