Найти в Дзене
Первая тема

Ваш Bitcoin принадлежит не только вам!

Оглавление

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

Немного теории....

Bitcoin можно разделить на три составные части: кошелек, транзакции, блокчейн. Больший интерес сейчас для нас представляет первая часть — Кошелек. В привычном для нас понимании «Кошелек» — это место, где хранятся наши средства, но в технологии bitcoin на кошельке средства совсем не хранятся. Сам кошелек лишь хранит некоторый код или ключ (приватный).

О том, как в общем работает цифровая подпись можно почитать тут

Приватный ключ в Bitcoin генерируется на основании алгоритма ECDSA. В этом алгоритме приватный ключ представляет собой некоторое 256 битное натуральное число, то есть это обычное целое число:

от 1 до 115792089237316195423570985008687907852837564279074904382605163141518161494337

Даже число 1234 — это действительный приватный ключ.

Как известно, bitcoin использует криптографию на эллиптических кривых(Elliptic curve cryptography, ECC) и кривую Secp256k1. Для понимания это совсем не сложный алгоритм, но один из самых криптостойких.

Допустим, мы выбрали случайное целое число k (из диапазона, который указан выше) — это будет наш приватный ключ, тогда наш публичный
ключ
H = kG (где G — это базовая точка или base point). Чтобы было понятно, то точка G это заранее определенная точка на кривой Secp256k1, умножение k на G — это скалярное умножение, иными словами мы складываем точку G саму с собой k раз. Соответственно получается H это так же точка, которая имеет свои координаты на кривой Secp256k1, эти координаты и являются нашим публичным ключем. Для того, чтобы понять, как складывается точка на кривой сама с собой и почему так происходит, советую почитать вот тут.

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

Есть еще одно замечание. Так как публичный ключ это ни что иное, как координаты точки на кривой (то есть координаты x и y), то нам достаточно знать лишь первую координату x, а координату y можно просто вычислить решив уравнение (функцию). А теперь на пальцах. Функция Secp256k1 выглядит вот так:

График этой функции выглядит вот так:

-2

Зная координату x некоторой точки, координату y мы узнаем просто подставив x в уравнение нашей функции, и решив его. Решив данное уравнение мы получим два значения y (положительное и отрицательное), чтобы не путаться принято записывать префиксы перед координатами при том или ином знаке координаты y.

Собственно для чего это нам нужно. В bitcoin есть два типа публичных ключей: несжатый (uncompressed) и сжатый (compressed). Несжатый публичный ключ— это две координаты (x и y) точки и добавленный префикс 0x04. Сжатый публичный ключ — это одна координата (x) точки, и в зависимости от знака y префикс 0х02 или 0х03.

-3

То есть, из одного приватного ключа мы можем получить два валидных адреса bitcoin (сжатый и несжатый).

Теперь пару слов о том, откуда появляется наш адрес bitcoin (например, 1HZwkjkeaoZfTSaJxDw6aKkxp45agDiEzN). Адрес напрямую связан с публичным ключем. Нет, адрес это не публичный ключ, как некоторые думают, адрес — это хэш публичного ключа. Причем это не обычный хэш, а необратимый хэш. Как из публичного ключа очень сложно получить приватный, так и из адреса (хэша) очень сложно получить публичный ключ.

-4

Итак, получаем из публичного ключа наш адрес:

  • Берем наш публичный ключ (public_key) в несжатом (uncompressed) формате
    048c52afa558dbc9491f10482c75bba962e8cfd46207e5d9aff7bd4f603f2c602a824e82959e5b74d3a8e3da9a75657fdb07071200e9dad73a99f1c29ae0eaffa1
  • Считаем хэш публичного ключа с помощью вот такой хэш-функции RIPEMD160(SHA256(public_key)). Получаем a09d85626673a7f0b1feeb5af166fb12f50c1dbe
  • Переводим результат в Base58Check с префиксом 0x00
    1FeFpSsfSysQgwSVM5eDRrm3qKkhN1mARq

Мы использовали криптографически стойкие хэш функции — RIPEMD160 и SHA256, поэтому строку, полученную на шаге 2, преобразовать обратно в строку на шаге 1 на данный момент невозможно. Наверное, вы заметили, что на шаге 3 мы использовали некую функцию Base58Check.

Base58Check похожа на Base64, но есть два отличия:
Первое отличие — в
Base58Check убраны символы 0,O,l,I — сделано это потому, что эти символы легко перепутать между собой.
Второе отличие — как раз таки в этом самом
Check (checksum). К концу строки добавляется первые 4 байта от хэш-функции SHA256(SHA256(строка))

-5

Что же мы имеем. Мы знаем откуда берется приватный и публичный ключи, мы знаем как генерируется адрес.

Осталось рассмотреть еще один момент связанный с ключами и эллиптическими кривыми. Ранее мы разобрали формулу H = kG (где k это приватный ключ, G заранее известная базовая точка, и H — публичный ключ). Дело в том, что если мы знаем k и G, то чтобы получить H нам необходимо совсем немного времени, а вот если нам известны H и G, то подобрать k будет неимоверно сложной задачей, которая может занять огромное количество времени. Подборка этого k называется задачей дискретного логарифмирования. Рассмотрим тот вариант, что вы придумали некий алгоритм, который находит k за ограниченный и сравнительно малый промежуток времени. То есть, зная публичный ключ H вы сможете найти приватный ключ k. Но в bitcoin публичный ключ в открытом виде нигде не фигурирует, есть лишь адрес, а это хэш публичного ключа. Соответственно, чтобы получить приватный ключ нам сначала необходимо декодировать хэш (адрес) в публичный ключ, а только потом, зная публичный ключ, подбирать приватный. По отдельности эти две задачи неимоверно сложны в данный момент, а вместе они сложны вдвойне.

Рассмотрим распространенный случай: перебор закрытых ключей

Как говорили ранее, что приватных ключей bitcoin ограниченное количество. Если быть точными то 115792089237316195423570985008687907852837564279074904382605163141518161494337 ключей. Не имею представления как правильно назвать данное число, но оно невероятно большое. Так вот, а давайте будем генерировать эти ключи и адреса по порядку, то есть начиная с первого приватного ключа. (Python3 + библиотека PyCoin). Получим примерно такое:

-6

Код Python3:

-7

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

А теперь о том, почему вероятность найти кошелек со средствами невероятна.

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

Первая проблема. Допустим вы сможете генерировать в секунду не по одной паре приватный ключ/адрес, а скажем по миллиарду. Чтобы сгенерировать все возможные ключи и адреса у вас уйдет 73434861261616054936308336509822366725543863698043445194447 лет. Здорово, правда?

Вторая проблема. Даже если вы сможете сгенерировать все пары приватный ключ/адрес, то хранить вам их будет попросту негде. Даже если взять всю память существующих носителей на планете, то это всё равно будет в разы меньше, чем нужно для хранения такого количества информации.

Сама идея генерации всех приватных ключей не нова. В сети есть несколько ресурсов, так называемых «генераторов по требованию». Суть в том, что этот генератор не хранит все приватные ключи разом, он генерирует их по запросу, по 100-150 шт. Пример таких генераторов https://privatekeys.pw и https://www.bitcoinlist.io/

ИТОГ

Мы разобрали пример того, как могут быть украдены ваши средства. Хоть и вероятность очень мала, но всё же она есть. На самом деле, описанное выше относится не только к bitcoin, но и к большинству других криптовалют, т.к. алгоритмы генерации публичных/приватных ключей одинаковы и построены на криптографии на эллиптических кривых.

P.S.

Описанное выше носит лишь информационный характер, а некоторые моменты описаны достаточно обобщенно. Все действия вы производите на свой страх и риск.

-8