Author

Topic: myPrivateBitcoinKey релиз программы для генерации адресов (Read 3149 times)

newbie
Activity: 6
Merit: 0
Проверил свои домыслы. Как и предполагалось, проблема оказалась в библиотеке Crypto++. Она совершенно не годится для таких задач как быстрая генерация ECDSA пар, т.к. генерит всего лишь около тысячи ключей в секунду на процессоре i5.
Осваиваю openssl.
newbie
Activity: 6
Merit: 0
Quote
С одной стороны brain wallet  С другой стороны vanitygen
А между ними myPBK   Cheesy

vanitygen может создавать красивые адреса, но не может создавать их исходя из входных данных. Т.е. ключи эти нужно хранить либо на листочке, либо в кошельке, а кошелек на флешке. Работает очень быстро, спору нет.

brain wallet может генерировать адреса исходя из входных данных, но неустойчив к атаке грубым перебором паролей, т.к. ключи формируются мгновенно, что подрывает безопасность его применения. И у многих пользователей умыкнули их честно заработанные..

myPBK как и vanitygen может генерировать адреса по маске (здесь это не ключевой момент), и как и brain wallet по пользовательскому паролю-фразе, но на расчет требуется определенное время. Это сделано для того, чтобы атакующему брутфорсеру на проверку одной пасс-фразы нужно было потратить как можно больше времени.
hero member
Activity: 808
Merit: 1014
А для чего вообще нужна эта программа?

С одной стороны, есть проверенный временем brain wallet если нужно держать в голове пароль от кошелька.

С другой стороны есть vanitygen, позволяющий генерировать красивые публичные адреса кошельков. Генерация по маске PBK занимает доли секунд. При этом пользователь может выбрать любую маску любой длины и нет никаких дополнительных алгоритмов генерации приватных ключей, т.е. его использование более безопасно.

Так какая область применений вашей программы?
Xtc
legendary
Activity: 1973
Merit: 1028
;u
Quote
После ввода пасс-фразы, из нее формируется ее хеш по алгоритму SHA256. Затем это значение просто инкрементируется до того момента, пока 2-й символ в адресе не станет "P", 3-й - "B", 4-й - "K" они же являются идентификатором.
Ну нормально. По сути это brainwallet, но с перебором адресов до PBK
newbie
Activity: 6
Merit: 0
Quote
Пользуйся, раз разработал. Поделки без алгоритма и исходников...
Что я и делаю) Для этого и писалась.
И если бы она работала идеально, желания представить ее на общественный суд было бы гораздо меньше.
Кстати да, неплохая идея реализовать возможность каждому пользователю кроме пасс-фразы задавать свой алгоритм.
Я уже писал, что поделюсь исходниками со всеми желающими, просто пока они больше похожи на черновик чем на исходный код, все нужно приводить в порядок. Ну а алгоритм.. Наверное да, он важен. Хотя я конечно не представляю, как можно уместить 32-х байтный приватный ключ в 24 байтном адресе еще и за одну минуту. Хотя конечно если только представить, что ключ не 32 байта, или формируется например из 4-х - 5-ти байт. Но как я уже писал, я готов показать свою писанину. И на данном этапе развития программы, я не предлагаю сразу бросаться переводить все свои сбережения на такой адрес, все это только тестинг, обсуждение. К примеру какое максимальное время генерации готов ждать пользователь, ибо чем дольше, тем безопаснее. Хотя некоторые пользователи успешно пользуются сервисом brain wallet, где генерация ключей происходит сразу же после ввода пасс-фразы, и конечно же некоторым не повезло, потому что неверный подход изначально. Узнал я кстати о сервисе brain wallet уже после написания этой утилиты.

Так и быть. Добавлю пока что только алгоритм в шапку. 
Xtc
legendary
Activity: 1973
Merit: 1028
;u
Пользуйся, раз разработал. Поделки без алгоритма и исходников...
hero member
Activity: 808
Merit: 1014
Если не хотите пока публиковать исходники, то опубликуйте хотя бы алгоритм, по которому происходит сопоставление пользовательского пароля и приватного ключа. А так же основания, исходя из которых вы считаете, что невозможно обратное вычисление приватного ключа исходя из публичного.

В криптовалюте безопасность - превыше всего, в том числе превыше удобства использования сторонних программ.

И пока вы не докажите, что вашей программой пользоваться абсолютно безопасно - всегда будет недоверие (и это абсолютно оправдано).

Генерируя приватные ключи сторонними программами следует исходить из того факта, что разработчики этих программ заложили в них алгоритм, позволяющий им восстанавливать приватные ключи по их публичным адресам. Априори это именно так и автору программы нужно именно доказать, что в его программе нет такого [зло]намеренного функционала.
legendary
Activity: 1148
Merit: 1051
Quote
если алгоритм знает автор программы, какой же он устойчивый, а тем более безопасный

Алгоритм формирования ключей очень прост, и я просто не вижу смысла его освещать. Безопасность основана не на алгоритме, а на достижении некоторой цели в публичном адресе по типу блокчейна.

Quote
и на хера, как это вяжется с генерацией адреса по пасс-фразе, или он будет одним и тем пока не переустановишь программу, которой он сгенерирован

Вы бы хоть попробовали запустить программу прежде чем писать, и сгенерить несколько ключей. Программа не требует выхода в сеть или доступа к файловой системе, и боятся пользователю нечего. Она очень простенькая, не требует установки, выложена в сеть безвозмездно, т.е. даром. Если кому-то нужно будет скину исходники. Но в паблик вылаживать не буду, пока не доведу программулину до "идеально работающей", и под этим тегом имею ввиду только скорость ее работы и ничего более.


Каким образом можно достичь "некоторой цели в публичном адресе",  дважды получив один и тот же адрес, без заранее известного алгоритма по которому будет генерироваться этот адрес, учитывая, что он у вас будет начинаться постоянно на 'PAB' и будет использоваться определённый пароль?

скорость  работы программы, судя по описанию, будет зависить от вашего железа и его величества случая, вы вообще проверяли адреса, отправляли с них на другие адреса, можно ссылки на блокчейн
newbie
Activity: 6
Merit: 0
Quote
если алгоритм знает автор программы, какой же он устойчивый, а тем более безопасный

Алгоритм формирования ключей очень прост, и я просто не вижу смысла его освещать. Безопасность основана не на алгоритме, а на достижении некоторой цели в публичном адресе по типу блокчейна.

Quote
и на хера, как это вяжется с генерацией адреса по пасс-фразе, или он будет одним и тем пока не переустановишь программу, которой он сгенерирован

Вы бы хоть попробовали запустить программу прежде чем писать, и сгенерить несколько ключей. Программа не требует выхода в сеть или доступа к файловой системе, и боятся пользователю нечего. Она очень простенькая, не требует установки, выложена в сеть безвозмездно, т.е. даром. Если кому-то нужно будет скину исходники. Но в паблик вылаживать не буду, пока не доведу программулину до "идеально работающей", и под этим тегом имею ввиду только скорость ее работы и ничего более.
legendary
Activity: 1148
Merit: 1051
Вашему вниманию релиз программы для генерации адресов Bitcoin по пасс-фразе, методом теоретически устойчивым к брутфорсу (перебору фраз). Пока что программа работает не так быстро как хотелось бы, думаю это связано с применением библиотеки Crypto++.
Алгоритм работы основан на достижении некоторой цели в публичном адресе Bitcoin исходя из вводных данных пользователем а не в случайном порядке. Первые 3 символа в сгенерированном адресе "PBK" выступают в качестве идентификатора такого адреса, для удобства идентификации адреса пользователем. Пасс-фраза должна быть больше 10 символов, желательно в разных раскладках, должна содержать спецсимволы и заглавные буквы, не должна содержать пробелов (проверка реализована только на кол-во символов). На калькуляцию адреса требуется некоторое кол-во времени, которое обычно занимает от 1-й до 2-х минут. При вводе одной и той -же пасс-фразы результат расчета всегда будет одним и тем-же.
Вопросы и предложения здесь. И если что, автор не причем).

myPrivateBitcoinKey: https://dropmefiles.com/GGUbF

Quote
теоретически устойчивым к брутфорсу

если алгоритм знает автор программы, какой же он устойчивый, а тем более безопасный
Quote
Первые 3 символа в сгенерированном адресе "PBK" При вводе одной и той -же пасс-фразы результат расчета всегда будет одним и тем-же.

и на хера, как это вяжется с генерацией адреса по пасс-фразе, или он будет одним и тем пока не переустановишь программу, которой он сгенерирован  Grin

мутно как-то всё
newbie
Activity: 6
Merit: 0
Вашему вниманию релиз программы для генерации адресов Bitcoin по пасс-фразе, методом теоретически устойчивым к брутфорсу (перебору фраз). Пока что программа работает не так быстро как хотелось бы, думаю это связано с применением библиотеки Crypto++.
Алгоритм работы основан на достижении некоторой цели в публичном адресе Bitcoin исходя из вводимых пользователем данных, а не методом генерации больших псевдослучайных чисел. Первые 3 символа в сгенерированном адресе "PBK" выступают в качестве идентификатора такого адреса, для удобства идентификации адреса пользователем и они же являются нашей целью. Пасс-фраза должна быть больше 10 символов, желательно в разных раскладках, должна содержать спецсимволы и заглавные буквы, не должна содержать пробелов (проверка реализована только на кол-во символов). На калькуляцию адреса требуется некоторое кол-во времени, которое обычно занимает от 10 секунд до 2-х минут. При вводе одной и той -же пасс-фразы результат расчета всегда будет одним и тем-же.
Вопросы и предложения здесь. И если что, автор не при делах).

myPrivateBitcoinKey (скачать)
(09.01.2016 Обновлено до v.0.02. Небольшие изменения в коде по оптимизации.)

Какой же алгоритм? Он прост как 3 рубля, но в то же время относительно безопасен.
После ввода пасс-фразы, из нее формируется ее хеш по алгоритму SHA256. Затем это значение просто инкрементируется до того момента, пока 2-й символ в адресе не станет "P", 3-й - "B", 4-й - "K" они же являются идентификатором. Этот измененный хеш и есть наш приватный ключ. Точки Px Py проходят рандомную проверку с последним уровнем безопасности. При совпадении происходит стандартный расчет приватного ключа в формате WIF и его кодировка в стандарт base58.
Функция кодировки в base58 была написана собственноручно для библиотеки Crypto++ и проверена многократно.  Здесь я разместил ее код.

В будущем планируется оптимизация кода для увеличения скорости генерации и соответственно для большей безопасности (хотя даже сейчас этот метод безопаснее чем например сервис brain wallet в десятки тысяч раз). А так-же экспорт ключей из программы в клиент.

Пример использования программы:
Code:

'my Private Bitcoin Key' version 0.01

Фраза должна содержать не менее 10 символов, не менее одной заглавной буквы
и не менее одного спецсимвола типа $ или & или любого другого кроме пробела

Enter pass-phrase (without space): 0987654321

Calculate......
      845.keys/sec  ||  Iterations: 10990.  || ~107 sec remaining


Input (hex):        30393837363534333231
Private Key in WIF: 8017756315EBD47B7110359FC7B168179BF6F2DF3646FCC888BC8AA05C78B3B5DC8B8D8267
Private Key:        17756315ebd47b7110359fc7b168179bf6f2df3646fcc888bc8aa05c78b3b5dch
Px Py ext:          0400A21ACEC8BB30581D095B1CBC47A1D04AFA5AAD558376E11AD0EB630FFC56594D4EEC3798E87473950EC649EA66F273186B263DEF93B1CF72F8382A0420D67E
Hash Px Py ext:     5002C7502C96325B11A3F3B343398DA6A2E750D4E94146F5D0828EE87E96F4A2
Adress (hex):       000431C369D927414B519F38CF247DA8BE68D956E199D45CBF

Adress base58:      1PBKPJ38tyGgztVvPkCZPo4JgAbRBy96W
PrivateKey base58:  5HzcoGSYFLLKEGAqNEnrCWAp3KrcxGWzWB1kLSsVf8REKUdDmhg

Iterations: 11036.
Time: 14 sec

Заходим на сайт xorbin.com и пишем в первом поле строчку "0987654321" (без кавычек), смотрим ее хеш, сравниваем с нашим приватным ключом. Убеждаемся что строчки почти идентичны, различие в нескольких последних байтах, т.к. наш приватный ключ это сумма хеша и количества итераций над этим приватным ключом.

Транзакция монет с этим адресом: https://blockchain.info/address/1PBKPJ38tyGgztVvPkCZPo4JgAbRBy96W

Исходник
Code:
#include 
#include
#include
#include "osrng.h"
#include "eccrypto.h"
#include
#include
#include
#include
#include
#include
#include "sha.h"
#include "ripemd.h"
#include "hex.h"
#include "cryptlib.h"
#include "filters.h"
#include "secblock.h"
#include "algparam.h"
#include "integer.h"
#include

using namespace std;
using namespace CryptoPP;
using namespace CryptoPP::ASN1;
using CryptoPP::SecBlock;

  string base58_encode(Integer num, string vers)
  {
    string alphabet[58] = {"1","2","3","4","5","6","7","8","9","A","B","C","D","E","F",
    "G","H","J","K","L","M","N","P","Q","R","S","T","U","V","W","X","Y","Z","a","b","c",
    "d","e","f","g","h","i","j","k","m","n","o","p","q","r","s","t","u","v","w","x","y","z"};
    int base_count = 58; string encoded; Integer div; Integer mod;
    while (num >= base_count)
    {
        div = num / base_count;   mod = (num - (base_count * div));
        encoded = alphabet[ mod.ConvertToLong() ] + encoded;   num = div;
    }
    encoded = vers + alphabet[ num.ConvertToLong() ] + encoded;
    return encoded;
  }

int main()
{
    setlocale(0, "");
    ECDSA::PrivateKey K1;
    ECDSA::PublicKey K2;
    AutoSeededRandomPool prng;

    byte L0[] = { 0x00 };
    SecByteBlock L0_byte(L0, sizeof(L0));

    byte L04[] = { 0x04 };
    SecByteBlock L04_byte(L04, sizeof(L04));

    byte L80[] = { 0x80 };
    SecByteBlock L80_byte(L80, sizeof(L80));

    RIPEMD160 hash;
    SHA256 hash2;

/*-----------------------------------------------------------------------------*/
Integer number_iteration;
   byte hash_sha256[32];
   SecByteBlock xy_byte;
   Integer privateKey;
   SecByteBlock hash_rip160_temp(20);
   SecByteBlock hash_rip160;
   SecByteBlock hash_sha256_valid_temp(32);
   SecByteBlock hash_sha256_valid(4);
   SecByteBlock hex_key;
   string bitcoin_adress;
   SecByteBlock qx(32);
   SecByteBlock qy(32);
   string input;
   string vers;
   SecByteBlock input_hash(32);
   SecByteBlock hash_pK_byte(32);
   SecByteBlock hash_pK_byte_valid(4);
   SecByteBlock pK_byte(32);
   Integer i;
   int count_it = 0;

cout << endl << "'my Private Bitcoin Key' version 0.02" << endl <<"" << endl <<
"Фраза должна содержать не менее 10 символов, не менее одной заглавной буквы" << endl << "и не менее одного спецсимвола типа $ или & или любого другого кроме пробела" << endl << endl <<
"Enter pass-phrase (without space): ";
cin >> input;

for (; input.length() < 10;) {cout << input << " <- Wrong input data! Try again: "; cin >> input;}

SHA256().CalculateDigest(input_hash, reinterpret_cast(&input[0]), input.length());
i.Decode(input_hash, 32);

cout << endl << "Calculate......" << endl;
long long now(time(0));

 char ba[35];
 while (ba[1] != 0x50 || ba[2] != 0x42 || ba[3] != 0x4b)
 {
K1.Initialize(secp256k1(), i);
privateKey = K1.GetPrivateExponent();
K1.MakePublicKey(K2);
   ECP::Point q = K2.GetPublicElement();

    (q.x).Integer::Encode (qx, 32 /*(q.x).MinEncodedSize(Integer::UNSIGNED)*/, Integer::UNSIGNED);
    (q.y).Integer::Encode (qy, 32 /*(q.y).MinEncodedSize(Integer::UNSIGNED)*/, Integer::UNSIGNED);
     xy_byte = L04_byte;
     xy_byte += qx;
     xy_byte += qy;

         hash2.CalculateDigest(hash_sha256, xy_byte, 65);

         hash.Update(hash_sha256, 32);
         hash.TruncatedFinal(hash_rip160_temp, 20/*hash_rip160_temp.size()*/);

         hash_rip160 = L0_byte;
         hash_rip160 += hash_rip160_temp;

         hash2.Update(hash_rip160, 21);
         hash2.TruncatedFinal(hash_sha256_valid_temp, 32/*sizeof(hash_sha256_valid_temp)*/);

         hash2.Update(hash_sha256_valid_temp, 32);
         hash2.TruncatedFinal(hash_sha256_valid, 4/*sizeof(hash_sha256_valid)*/);
/*----------------------------------------------------------------------------------------------*/

         hex_key = hash_rip160;
         hex_key += hash_sha256_valid;

         bitcoin_adress = base58_encode(Integer (hex_key, 25, Integer::UNSIGNED), "1");

    strcpy( ba, bitcoin_adress.c_str() );

 number_iteration++;
 count_it++;

 if (count_it >= 99)
      {
        if (!(time(0) - now) == 0)

              cout << "      " << number_iteration / (time(0) - now) << "keys/sec" <<
              "  ||  Iterations: " << dec << number_iteration << "  || ~" << 120 - (time(0) - now) << " sec remaining\r";

        count_it = 0;
      }
 i++;

 }
 privateKey.Integer::Encode (pK_byte, 32, Integer::UNSIGNED);
 pK_byte = L80_byte += pK_byte;

 hash2.CalculateDigest(hash_pK_byte, pK_byte, 33);

 hash2.Update(hash_pK_byte, 32);
    hash2.TruncatedFinal(hash_pK_byte_valid, 4);

 pK_byte += hash_pK_byte_valid;

  HexEncoder encoder;

  string Hash_Px_Py_ext;
    encoder.Attach(new StringSink( Hash_Px_Py_ext ));
    encoder.Put( hash_sha256, sizeof(hash_sha256));

         string Px_Py_ext;
           encoder.Attach ( new StringSink( Px_Py_ext ));
           encoder.Put( xy_byte, xy_byte.size() );

                string input_string;
                  encoder.Attach( new StringSink( input_string ));
                  encoder.Put( reinterpret_cast( &input[0]), input.length() );

                       string pK_byte_string;
                         encoder.Attach( new StringSink( pK_byte_string ));
                         encoder.Put( pK_byte, pK_byte.size() );

  cout << endl << endl << endl <<
    "Input (hex):        " << input_string << endl <<
    "Private Key in WIF: " << pK_byte_string << endl <<
    "Private Key:        " << hex << privateKey << endl;

  cout <<
    "Px Py ext:          " << Px_Py_ext << endl <<
    "Hash Px Py ext:     " << Hash_Px_Py_ext << endl;

if (K2.Validate( prng, 3 ))
{
     string hash_rip160_string_temp;
       encoder.Attach( new StringSink( hash_rip160_string_temp ));
       encoder.Put( hash_rip160_temp, hash_rip160_temp.size() );

          string hash_sha256_valid_string;
            encoder.Attach( new StringSink( hash_sha256_valid_string ));
            encoder.Put( hash_sha256_valid, hash_sha256_valid.size() );

               string hex_key_string;
                 encoder.Attach( new StringSink( hex_key_string ));
                 encoder.Put( hex_key, hex_key.size() );

                    string hash_rip160_string;
                      encoder.Attach( new StringSink( hash_rip160_string ));
                      encoder.Put( hash_rip160, hash_rip160.size() );


  cout <<
    "Adress (hex):       " << hex_key_string << endl << endl;
  cout <<
    "Adress base58:      " << bitcoin_adress << endl <<
    "PrivateKey base58:  " << base58_encode(Integer (pK_byte, 37, Integer::UNSIGNED), "") << endl << endl <<
    "Iterations: " << dec << number_iteration << endl <<
    "Time: " << time(0) - now << " sec\a" << endl;
    _getch();
  }
else cout << endl << "False! Please use another pass-phrase!";
/*-------------------------------------------------------------------*/
_getch();

}

Jump to: