В Главе четвертой мы рассмотрели, как биткойны генерируются и вводятся в экономику. Мы объяснили, что биткойны генерируются примерно каждые десять минут в ходе решения математической задачи. В этой главе мы рассмотрим более подробно, как это работает. Чтобы разобраться в добыче биткойна, нам нужно познакомиться с другой идеей из компьютерных наук: это хеширование, или криптографический хеш.
Хеширование – это очень интересная концепция, которая, как и асимметричная криптография, является одной из ключевых идей в сфере безопасности программного обеспечения. Как мы делали ранее, давайте начнем с представления задачи. Если у меня есть компьютерная система, как я мог бы безопасно хранить пароль каждого пользователя таким образом, что если система будет скомпрометирована, то пользовательские пароли – не будут? Другими словами, по очевидным причинам это плохая идея – хранить базу данных, содержащую тысячи или миллионы пользовательских паролей.
Решение этой задачи включает в себя криптографический хеш. Процесс хеширования получает нечто на вход, например, пароль, и пропускает эти входные данные через алгоритм, который выводит большое число, называемое «хеш». Хеш определяют две отличительные особенности. Во-первых, для одних и тех же входных данных процесс хеширования всегда возвращает одинаковый результат. Например, если вы вводите пароль, который пропускается через алгоритм хеширования, генерирующий определенное число, то каждый раз будет генерироваться одно и то же число. Во-вторых, хеширование – это однонаправленный процесс. Невозможно взять значение хеша и при помощи обратной разработки раскрыть, что было на входе. Эти два свойства и определяют криптографический хеш. Если бы процесс был обратим, он назывался бы не хешированием, а старым добрым шифрованием/дешифрованием, и это совершенно другая тема.
Оказывается, процесс хеширования значений имеет множество полезных особенностей в приложении к компьютерным наукам. Одной из задач, которые мы предлагали выше, была задача о безопасном хранении пользовательских паролей в системе. Вместо того, чтобы хранить пароль пользователя, мы сперва хешируем его пароль и храним значение хеша. Когда пользователь пытается в следующий раз войти в систему при помощи пароля, нам не нужно знать, каким был его пароль, мы только должны знать, что пароль совпадает с тем, что был введен в прошлый раз. Другими словами, если хеш введенного пароля совпадает с хешем, хранящимся в базе данных, мы знаем, что пользователь ввел правильный пароль – хотя мы не знаем, и не хотим знать, что это был за пароль. Если позже наша система будет скомпрометирована, атакующий получит только список хешей паролей, необратимых и не имеющих никакой ценности.
Если вы похожи на меня, этот процесс покажется вам очаровательным, но вы, вероятно, спросите себя – если пароли хешируются, как же получается, что если вы забыли пароль к определенной системе, то компания может выслать вам его по электронной почте. Это очень хороший вопрос. Это означает, что пароли не хешируются, и эта система крайне небезопасна. Печально, но многие системы сегодня допускают это. Это одна из причин, по которым нужно использовать разные пароли для каждой из систем, к которым вы имеете доступ. Когда в новостях обнаруживается, что система была «хакнута» и тысячи паролей скомпрометированы, это случается потому, что проектировщики системы не смогли обеспечить безопасность пользовательских паролей с помощью техники хеширования, которая повсеместно считается наилучшим подходом.
Ради интереса заметим, что, если вы забыли пароль к системе, которая надлежащим образом хеширует пароли пользователей, правильный подход – это сброс пароля системой, когда пароль заменяется каким-нибудь временным значением, что позволяет вам поменять его на что-нибудь другое, когда вы войдете в систему. Однако, надо заметить, что такой подход не гарантирует, что система на самом деле хеширует пароли.
Теперь, каким образом все это относится к добыче биткойна? Ну, мы сказали, что обратная разработка хеша невозможна. Технически говоря, теоретически она возможна посредством того, что называется атака «грубой силой» – перебор всех возможных входных комбинаций до тех пор, пока не получится такой же хеш. Однако, на практике количество комбинаций астрономически велико, что делает такую атаку невозможной в практических целях. Также нужно заметить, что разные входные значения могут выдать в результате одинаковое значение хеша, это явление называется коллизией и случается крайне редко, если использовать правильный алгоритм хеширования, так что для нашего обсуждения здесь это неважно.
Теперь давайте предположим, что есть только миллион возможных значений хеша, число между нулем и миллионом. В реальности, конечно, мы знаем, что возможно гораздо больше миллиона значений хеша, но давайте продолжим с миллионом, чтобы проиллюстрировать мою мысль. Таким образом, шансы правильно угадать верные входные данные для данного хеша будут один к миллиону. Имея достаточное количество попыток и достаточное время, в конце концов я найду исходные данные, которые после хеширования дадут значение, которое я пытаюсь подобрать.
Давайте предположим, что процесс проб и ошибок занимает двадцать четыре часа чтобы найти совпадение (современный домашний компьютер сделает миллион итераций меньше, чем за секунду, но давайте оставим двадцать четыре часа для нашего примера). Помня, что в нашем примере мы сказали, что все значения хеша – это числа между нулем и миллионом, давайте предположим, что вместо нахождения входных данных, которые дадут определенное значение хеша, мы хотели бы найти входные данные, хеширование которых даст число, меньшее или равное 10. То есть, мы хотим найти любой вход, который даст в результате значение хеша 1, 2, 3, 4, 5, 6, 7, 8, 9 или 10. В этом случае в десять раз более вероятно, что полученное нами значение хеша подойдет, поэтому наш компьютер найдет совпадение в среднем в десять раз быстрее – теперь потребуется примерно 2,4 часа вместо 24 часов.
Если бы я хотел создать задачу, которая будет решаться быстрее, скажем, решаться за 10 минут, я бы поднял ограничение до любого хеша между 1 и 150. Задача теперь в 150 раз проще, чем в первом примере, и быстрый подсчет покажет, что такая задача должна решаться нашим (медленным) компьютером примерно за 10 минут. Что случится, если второй, настолько же мощный компьютер подключится к попыткам найти решение задачи? Теперь ее можно будет решить в два раза быстрее. Если я хочу, чтобы решение все равно занимало 10 минут, я должен буду сделать задачу в два раза труднее, задав условие, что значение хеша должно быть теперь меньше 75, а не 150. По мере того, как все больше компьютеров подключаются к решению задачи, и они все эффективнее начинают решать задачу, мы делаем ее более сложной, задавая меньший диапазон приемлемых значений хеша.
И, если вы до сих пор не догадались, это и есть задача, которую биткойн-сеть предлагает биткойн-майнерам. Разница, конечно, в том, что существует гораздо больше миллиона комбинаций, числа так велики, что их так просто и не назовешь. Все биткойн-майнеры мира в то время, пока я пишу этот текст, коллективно обрабатывают примерно 350 000 000 000 000 000 входных значений в секунду в попытке найти то самое значение, хеш которого попадет в определенный диапазон значений хеша.
Биткойн-сеть регулярно оценивает сложность задачи, и, если задача решается быстрее или медленнее, чем за установленный интервал 10 минут, тогда задача соответствующим образом подстраивается посредством расширения или сокращения диапазона приемлемых значений хеша. Из всех компьютеров мира, пытающихся решить задачу, только первый решивший получает биткойны «в награду», и процесс начинается заново. Следующий вопрос тогда: как остальная биткойн-сеть подтверждает, что задача была решена, и каким образом в этом процессе генерируются биткойны? Первый вопрос простой. Компьютер, который решил задачу, объявляет об этом решении биткойн-сети, и другие компьютеры проверяют решение. Хотя обратная разработка входного значения для данного диапазона значений хеша – это медленный процесс проб и ошибок, но как только решение найдено, его легко проверить, просто пропустив предложенное решение через алгоритм хеширования и убедившись, что результирующее значение хеша попадает в заданный диапазон. Затем добытые биткойны выдаются на определенный майнером адрес, вводя новые биткойны в экономику. Так же, как монархи в старину выпускали тэлли под налоги, которые никогда не будут собраны, и банки выпускали банкноты под средства, которых у них не было, биткойн-сеть медленно генерирует новые биткойны. Ключевая разница между биткойном и другими системами, однако, состоит в том, что во всех предыдущих системах частота генерации валюты устанавливалась по прихоти монарха, правительства, банка или, в последние времена, контролируемого правительством центрального банка. Частота генерации биткойна устанавливается алгоритмически, и не может быть предметом манипуляций участников рынка – она предопределена. Частота генерации определяется биткойн-протоколом, и со временем понижается, пока в конце концов биткойны не перестанут генерироваться вообще. Для любой даты в прошлом или будущем можно подсчитать примерное количество биткойнов в обращении.
Рис. 4. Распределение биткойнов по времени