BIP47

BIP47, иллюстрация гадкого утенка

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

Этот компромисс так же стар, как и Белая книга. Сатоши уже предостерегал нас от этого риска в своей книге, опубликованной в конце 2008 года:

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

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

Существует множество решений для получения нескольких платежей без повторного использования адресов. Каждый из них имеет свои компромиссы и недостатки. Среди всех этих решений естьBIP47, предложение, разработанное Юстусом Ранвье и опубликованное в 2015 году для генерации многоразовых кодов платежей. Их цель состоит в том, чтобы иметь возможность осуществлять несколько транзакций одному и тому же лицу, без повторного использования адреса.

Первоначально это предложение получило пренебрежительный прием со стороны части сообщества, и оно никогда не было добавлено в Bitcoin Core. Некоторое программное обеспечение все еще решило реализовать его на своей стороне. Таким образом, Samourai Walletразработал собственную реализацию BIP47: PayNym. Сегодня эта реализация, очевидно, доступна на Samourai Wallet для смартфонов, а также наSparrow Walletдля ПК.

Со временем Samourai запрограммировал новые функции, непосредственно связанные с PayNym. Теперь существует целая экосистема инструментов для оптимизации конфиденциальности пользователей на основе PayNym и BIP47.

В этой статье вы узнаете о принципе работы BIP47 и PayNym, механизмах этих протоколов и практических применениях, которые из них вытекают. Я собираюсь поговорить только о первой версии BIP47, той, которая в настоящее время используется для PayNym, но версии 2, 3 и 4 работают почти так же.

Единственное существенное отличие заключается в уведомлении транзакции. Версия 1 использует простой адрес с OP_RETURN для уведомления, версия 2 использует сценарий multisig (bloom-multisig) с OP_RETURN, а версии 3 и 4 просто используют сценарий multisig (cfilter-multisig). Механизмы, упомянутые в этой статье, и в частности изученные криптографические методы, поэтому применимы ко всем четырем версиям. На сегодняшний день в реализации PayNym на Samurai Wallet и Sparrow используется первая версия BIP47.

Проблема повторного использования адресов.

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

Чтобы узнать больше о генерации адреса получения, я советую вам прочитать последнюю часть этой статьи: Биткойн-кошелек — Bitcoin ebook extract Democratized 2.

Кроме того, вы, вероятно, уже слышали от опытного биткойнера, что получение адресов предназначено для одноразового использования, и поэтому необходимо генерировать новый для любого нового платежа, поступающего в ваш кошелек. Хорошо, но почему?

В принципе, повторное использование адреса напрямую не ставит под угрозу ваши средства. Использование криптографии на эллиптических кривых дает возможность доказать сети, что у вас есть закрытый ключ, не раскрывая этот ключ. Таким образом, вы можете заблокировать несколько разных UTXO на одном и том же адресе и потратить их в разное время. Если вы не раскроете закрытый ключ, связанный с этим адресом, никто не сможет получить доступ к вашим средствам. Проблема повторного использования адресов является скорее проблемой конфиденциальности.

Как упоминалось во введении, прозрачность и распределение сети Bitcoin означает, что любой пользователь, при условии, что у него есть доступ к узлу, может наблюдать за транзакциями платежной системы. В результате он может видеть различные балансы адресов. Затем Сатоши Накамото поднял возможность генерации новых пар ключей и, следовательно, новых адресов для любого нового платежа, поступающего в кошелек. Цель состоит в том, чтобы иметь дополнительный брандмауэр на случай связи между личностью пользователя и одной из его пар ключей.

Сегодня, с наличием компаний по анализу цепочек и развитием KYC, использование пустых адресов больше не является дополнительным брандмауэром, а обязанностью для всех, кто заботится минимум об их конфиденциальности.

Поиск конфиденциальности не является комфортом или максималистской фантазией биткойнера. Это конкретная настройка, которая напрямую влияет на вашу личную безопасность и безопасность ваших средств. Чтобы вы поняли, вот очень конкретный пример:

— Боб покупает биткоин в DCA (Dollars Cost Average), то есть он приобретает небольшое количество биткоинов через равные промежутки времени, чтобы сгладить свою цену входа. Боб всегда отправляет купленные средства на один и тот же адрес получателя. Он покупает 0,01 биткойна каждую неделю и отправляет их на тот же адрес. Через два года Боб накопил на этом адресе целый биткоин.

— Пекарь за углом принимает платежи в биткоинах. Счастливый возможность тратить биткоины, Боб отправляется покупать свою палочку в сатс. Для оплаты он использует заблокированные средства со своим адресом. Его пекарь теперь знает, что у него есть биткойн. Эта большая сумма может вызвать некоторую зависть, и Боб потенциально рискует подвергнуться физическому нападению впоследствии.

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

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

Существует множество решений для этих организаций. Каждый из них имеет свои преимущества и недостатки, но на сегодняшний день, и как мы увидим позже, BIP47 действительно отличается от остальных.

Эта проблема повторного использования адресов далеко не незначительна для Bitcoin. Как вы можете видеть из приведенной ниже диаграммы, извлеченной ссайта oxt.me, общий уровень повторного использования адресов пользователями Bitcoin в настоящее время составляет52%:

График OXT.me эволюцию общей скорости повторного использования адресов в сети Bitcoin.

Фото: https://oxt.me/charts

Большинство этих повторных использований происходит от бирж, которые по соображениям эффективности и удобства повторно используют один и тот же адрес много раз. На сегодняшний день BIP47 был бы лучшим решением, чтобы остановить это явление на биржах. Это позволило бы снизить общую скорость повторного использования адресов, не вызывая слишком больших трений для этих объектов.

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

Принципы BIP47 и PayNym.

BIP47 стремится предложить простой способ получения многих платежей, не используя при этом повторно адреса. Его работа основана на использовании многоразового кода платежа.

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

Затем пользователь может свободно сообщать свой платежный код (в социальных сетях, на своем веб-сайте …) без риска потери конфиденциальности, в отличие от традиционного адреса приема или открытого ключа.

Чтобы совершить обмен, обоим пользователям нужно будет иметь биткойн-кошелек с реализацией BIP47, такой как PayNym на Samurai Wallet или Sparrow Wallet. Объединение платежных кодов двух пользователей позволит установить между ними секретный канал. Чтобы правильно наладить этот канал, эмитенту придется провести транзакцию по цепочке Bitcoin: транзакцию уведомления (об этом я расскажу чуть позже).

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

Таким образом, код платежа действует как виртуальный идентификатор, полученный из семени кошелька. Вструктуре деривации HD-кошелька код платежа находится в глубине 3, на уровне учетных записей кошелька.

Структура HD кошелька и размещение многоразового кода платежа BIP47

Его обходная цель составляет 47′ (0x8000002F) со ссылкой на BIP47. Например, производный путь для повторно используемого кода платежа будет следующим:

m/47'/0'/0'/

Итак, вы можете себе представить, как выглядит код платежа, вот мой:

PM8TJSBiQmNQDwTogMAbyqJe2PE2kQXjtgh88MRTxsrnHC8zpEtJ8j7Aj628oUFk8X6P5rJ7P5qDudE4Hwq9JXSRzGcZJbdJAjM9oVQ1UKU5j2nr7VR5 

Он также может быть закодирован в QRcode для облегчения связи:

PayNym BIP47 Код повторно используемого платежа к QR-коду

Что касается PayNym Bots, то эти роботы, которые мы видим в Twitter, являются просто визуальными представлениями вашего платежного кода, сделанного Samurai Wallet. Они создаются с помощью хэш-функции, что делает их практически уникальными. Вот мой с его именем пользователя:

+throbbingpond8B1
PayNym Бот

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

Для пользователя процесс оплаты BIP47 с реализацией PayNym предельно прост. Допустим, Алиса хочет отправить платежи Бобу:

  1. Боб распространяет свой QR-код или непосредственно свой многоразовый платежный код. Он может разместить его на своем веб-сайте, в своих различных публичных социальных сетях или отправить Алисе через другие средства связи.
  2. Алиса открывает свое программное обеспечение Samurai или Sparrow и сканирует или вставляет код платежа Боба.
  3. Алиса связывает свой PayNym с Bob’s («Follow» на английском языке). Эта операция выполняется вне блокчейна и остается полностью бесплатной.
  4. Алиса соединяет свой PayNym с Бобом («Connect»). Эта операция выполняется «по цепочке». Алиса должна заплатить комиссию за майнинг транзакций, а также фиксированную плату в размере 15 000 сат за услугу на Samourai. Плата за услуги предлагается на Sparrow. Этот шаг называется транзакцией уведомления.
  5. Как только транзакция уведомления будет подтверждена, Алиса может создать платежную транзакцию BIP47 для Боба. Его кошелек автоматически сгенерирует новый пустой адрес получения, для которого только Боб имеет закрытый ключ.

Проведение транзакции уведомления, т.е. подключение Вашего PayNym, является обязательным предварительным шагом для совершения платежей BIP47. С другой стороны, как только это будет сделано, отправитель сможет сделать несколько платежей получателю (ровно 2^32), без необходимости совершать транзакцию уведомления снова.

Возможно, вы видели, что есть две разные операции, которые связывают PayNym вместе: ссылка и подключение. Операция соединения («connect») соответствует транзакции уведомления BIP47, которая является просто транзакцией Bitcoin с определенной информацией, передаваемой через OP_RETURN выход. Таким образом, это помогает установить зашифрованную связь между двумя пользователями, чтобы создать общие секреты, необходимые для генерации новых пустых принимающих адресов.

С другой стороны, операция link («следовать» или «перелинковывать») позволяет установить ссылку на Soroban, зашифрованный протокол связи на основе Tor, специально разработанный командами Samourai.

Подведем итоги:

  • Связывание двух PayNym («подписаться») совершенно бесплатно. Это помогает устанавливать зашифрованные «внецепочные» коммуникации, особенно для того, чтобы использовать инструментысовместных транзакций Samourai (Stowaway или StonewallX2). Эта операция специфична для PayNym. Он не описан в BIP47.
  • За подключение двух PayNyms взимается плата. Это включает в себя выполнение транзакции уведомления, чтобы инициировать соединение. Его стоимость состоит из любых сборов за обслуживание, сборов за транзакционный майнинг и 546 спутников, отправленных на адрес уведомления получателя, чтобы предупредить их об открытии туннеля. Эта операция связана с BIP47. После этого отправитель может сделать несколько платежей BIP47 получателю.

Для того, чтобы иметь возможность подключить два PayNym, они уже должны быть подключены.

Учебные пособия: Использование PayNym.

Теперь, когда мы увидели теорию, давайте вместе изучим практику. Идея учебников ниже состоит в том, чтобы связать мой PayNym на моем кошельке Sparrow с моим PayNym на моем кошельке Samurai. В первом уроке показано, как совершить транзакцию с использованием многократно используемого кода платежа от Samurai до Sparrow, а во втором учебнике описан тот же механизм от Sparrow до Samourai.

Я сделал эти учебники на Testnet. Это не настоящие биткоины.

Создайте транзакцию BIP47 с помощью кошелька Samourai.

Чтобы начать, вам, очевидно, понадобится приложение Samourai Wallet. Вы можете скачать его непосредственно из Google Play Store или сфайлом APK, доступным наофициальном сайте Samourai.

После инициализации кошелька, если вы еще этого не сделали, запросите PayNym, нажав на плюс (+) в правом нижнем углу, затем на «PayNym».

Первым шагом для осуществления платежа BIP47 будет получение повторно используемого кода платежа от нашего получателя. Затем мы сможем подключиться к нему, а впоследствии подключить:

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

Вот как сделать транзакцию BIP47 на кошельке Samourai:

Создайте транзакцию BIP47 с помощью кошелька Sparrow.

Так же, как и для Samourai, у вас, очевидно, должно быть программное обеспечение Sparrow. Он доступен на компьютере. Вы можетескачатьего сих официального сайта.

Не забудьте проверитьподпись разработчика ицелостность загруженного программного обеспечения перед его установкой на свой компьютер.

Создайте кошелек и запросите PayNym, нажав «Показать PayNym» в меню «Инструмент» в верхней панели:

Открытие меню PayNym на Sparrow

Затем вам нужно будет связать и связать ваш PayNym с вашим получателем. Для этого введите его многоразовый платежный код в окне «Найти контакт», следуйте за ним, затем завершите транзакцию уведомления, нажав на «Связать контакт»:

Поиск и подключение к PayNym на Sparrow

Как только транзакция уведомления подтверждена, платежи могут быть отправлены на повторно используемый код платежа. Вот как это сделать:

Теперь, когда мы смогли изучить практический аспект реализации PayNym BIP47, давайте вместе посмотрим, как работают все эти механизмы, и какие криптографические методы используются.

Работа BIP47.

Для изучения механизмов BIP47 необходимо понять структуру иерархического детерминированного (HD) портфеля, механизмы получения дочерних пар ключей, а также принципы криптографии эллиптических кривых. К счастью, вы можете найти в моем блоге всю эту информацию, необходимую для понимания этой части:

Повторно используемый код платежа.

Как объясняетсяво второй частиэтой статьи, многоразовый код платежа находится в глубине трех HD кошелька. Он, наконец, несколько сопоставим с xpub, как по своему размещению и структуре, так и по своей роли.

Вот различные части, которые составляют 80-байтовый код платежа:

  • Байт 0:Версия. Если мы используем первую версию BIP47, то этот байт будет равен 0x01.
  • Байт 1: битовое поле. Это место зарезервировано для предоставления дополнительных указаний в случае конкретного использования. Если просто использовать PayNym, этот байт будет равен 0x00.
  • Байт 2: Соотношение y. Этот байт указывает на 0x02 или 0x03 на основе четности (четного или нечетного числа) значения ординаты нашего открытого ключа. Для получения дополнительной информации об этойпрактике, пожалуйста, прочитайте шаг 1 раздела «Получение адреса»этой статьи.
  • От байта 3 до байта 34: Значение x. Эти байты указывают на абсциссу нашего открытого ключа. Сцепление x и четность y дают нам сжатый открытый ключ.
  • От байта 35 до байта 66: Строковый код. Это место зарезервировано для строкового кода, связанного с вышеупомянутым открытым ключом.
  • От байта 67 до байта 79: заполнение. Это место зарезервировано для возможных будущих разработок. Для версии 1 мы просто ставим нули, чтобы заполнить до 80 байт, размер данных OP_RETURN вывода.

Вот шестнадцатеричное представление моего многоразового кода платежа, представленного в предыдущей части, с цветами, соответствующими байтам, представленным выше:

0x010002a0716529bae6b36c5c9aa518a52f9c828b46ad8d907747f0d09dcd4d9a39e97c3c5f37c470c390d842f364086362f6122f412e2b0c7e7fc6e32287e364a7a36a00000000000000000000000000

Затем также необходимо добавить байт префикса «P», чтобы с первого взгляда определить, что мы имеем дело с кодом платежа. Этот байт 0x47.

0x47010002a0716529bae6b36c5c9aa518a52f9c828b46ad8d907747f0d09dcd4d9a39e97c3c5f37c470c390d842f364086362f6122f412e2b0c7e7fc6e32287e364a7a36a00000000000000000000000000

Наконец, мывычисляем контрольную сумму этогокода платежа с помощью HASH256, т.е. двойного хэша сфункцией SHA256. Первые четыре байта этого конденсата извлекаются и объединяются в конце (розовым цветом).

0x47010002a0716529bae6b36c5c9aa518a52f9c828b46ad8d907747f0d09dcd4d9a39e97c3c5f37c470c390d842f364086362f6122f412e2b0c7e7fc6e32287e364a7a36a00000000000000000000000000567080c4

Код платежа готов, остается только конвертировать его в Base 58:

PM8TJSBiQmNQDwTogMAbyqJe2PE2kQXjtgh88MRTxsrnHC8zpEtJ8j7Aj628oUFk8X6P5rJ7P5qDudE4Hwq9JXSRzGcZJbdJAjM9oVQ1UKU5j2nr7VR5 

Как вы можете заметить, эта конструкция сильно напоминает структурурасширенного открытого ключатипа «xpub».

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

Конкретно, чтобы получить открытый ключ и код цепочки повторно используемого кода платежа, мы вычислим главный закрытый ключ из seed, затем выведем дочернюю пару с индексом 47 + 2^31 (усиленное выведение). Затем выводим два дочерних пары с индексом 2^31 (усиленное определение).

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

Криптографический метод: обмен ключами Диффи-Хеллмана, установленный на эллиптических кривых (ECDH).

Криптографическим методом, используемым на основе BIP47, является ECDH (Эллиптическая кривая Диффи-Хеллмана = обмен ключами Диффи-Хеллмана, установленный на эллиптических кривых). Этот протокол является вариантом классического обмена ключами Диффи-Хеллмана.

Диффи-Хеллман, в своей первой версии, является ключевым протоколом соглашения, введенным в 1976 году, который позволяет двум людям, из двух пар (открытые ключи и закрытые ключи), определять общий секрет путем обмена по незащищенному каналу связи.

Схема генерации секрета, совместно используемого с Диффи-Хеллманом

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

Зашифрованная связь с Общим секретом Диффи-Хеллмана

Чтобы достичь этого обмена, Диффи-Хеллман использует модульную арифметику для вычисления общего секрета. Вот как это работает с точки зрения непрофессионала:

  • Алиса и Боб определяют общий цвет, в данном случае желтый. Этот цвет известен всем. Это общедоступные данные.
  • Алиса выбрала секретный цвет, вот красный. Он смешивает два цвета, что придает ему оранжевый.
  • Боб выбрал секретный цвет, здесь утка голубая. Он смешивает два цвета, что придает ему небесно-голубой цвет.
  • Алиса и Боб могут обмениваться полученными цветами: оранжевым и небесно-голубым. Этот обмен может осуществляться в незащищенной сети и наблюдаться злоумышленниками.
  • Алиса смешивает небесно-голубой цвет, полученный от Боба, с его секретным цветом (красным). Она становится коричневой.
  • Боб смешивает оранжевый цвет, полученный от Алисы, с ее секретным цветом (утиный синий). Он приобретает такой же коричневый цвет.
Схема популяризации функционирования Диффи-Хеллмана

Фото: Оригинальная идея: A.J. Han VinckVector version: FlugaalTranslation: Dereckson, Общественное достояние, через Викисклад. https://commons.wikimedia.org/wiki/File:Diffie-Hellman_Key_Exchange_(fr).svg

В этой популяризации коричневый цвет представляет секрет, разделяемый между Алисой и Бобом. Надо представить, что в реальности злоумышленнику невозможно разделить оранжевый и небесно-голубой цвета, чтобы найти тайные цвета Алисы или Боба.

Теперь давайте изучим, как это на самом деле работает. На первый взгляд, Диффи-Хеллман кажется сложным для понимания. В реальности принцип работы практически детский. Прежде чем подробно описать его механизмы, я быстро напомню о двух математических понятиях, которые нам понадобятся (и которые, кстати, также используются во многих других криптографических методах).

  1. Простоечисло — это натуральное число, которое допускает только два делителя: 1 и само себя. Например, число 7 является простым, потому что его можно разделить только на 1 и 7 (само по себе). С другой стороны, число 8 не является простым, потому что его можно разделить на 1, 2, 4 и 8. Поэтому он допускает не только два делителя, но и четыре целочисленных и положительных делителя.
  2. «По модулю» (обозначаемому «mod» или «%») — математическая операция, позволяющая между двумя целыми числами возвращать остаток евклидова деления первого на второе число. Например, 16мод5 равен 1.

Обмен ключами Диффи-Хеллмана между Алисой и Бобом работает следующим образом:

  • Алиса и Боб определяют два общих числа: pиg. p— простое число. Чем больше это числоp, тем безопаснее будет Диффи-Хеллман. gпримитивный кореньp. Эти два числа могут быть переданы в ясной форме в незащищенной сети, они являются эквивалентами желтого цвета в популяризации выше. Алиса и Боб просто должны иметь точно такие же значенияpиg.
  • Как только параметры выбраны, Алиса и Боб определяют секретное случайное число. Случайное число, полученное Алисой, называетсяa (эквивалентно красному цвету), а случайное число, полученное Бобом, называетсяb (эквивалентно цвету утки синий). Эти два числа должны оставаться в секрете.
  • Вместо того, чтобы обмениваться этими числамиaиb, каждая часть будет вычислятьA(прописные) иB(прописные) таким образом, что:
# A est égal à g puissance a modulo p :
A = g^a % p 

# B est égal g puissance b modulo p :
B = g^b % p
  • Эти числаA (эквивалент оранжевого цвета) иB (эквивалентный небесно-голубому цвету) будут обмениваться между двумя сторонами. Обмен может осуществляться в чистой форме в незащищенной сети.
  • Алиса, которая теперь знает оB, вычислит значениеzтаким образом, что:
 # z est égal à B puissance a modulo p :
 z = B^a % p
  • Напоминаем, что B = g^b % p. Итак, мы имеем:
z = B^a % p
z = (g^b)^a % p

# Conformément aux règles de calculs sur les puissances : 
(x^n)^m = x^nm

# On a donc :
z = g^ba % p
  • Боб, который теперь знает обA, также рассчитает значениеzтаким образом, что:
 # z est égal à A puissance b modulo p :
 z = A^b % p
 
 # On a donc :
 z = (g^a)^b % p
 z = g^ab % p
 z = g^ba % p

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

Техническая рабочая схема Диффи-Хеллмана

Злоумышленник, обладающий p,g,A иB, не сможет вычислить a,b или z. Сделать это означало бы обратить вспять экспоненциацию. Этого вычисления невозможно достичь, кроме как пробуя все возможности одну за другой, поскольку одна работает на конечном поле. Это было бы эквивалентно вычислению дискретного логарифма, т.е. обратного экспоненциального в конечной циклической группе.

Таким образом, пока кто-то выбираетбольшие a, bиp, Диффи-Хеллман в безопасности. Как правило, при параметрах 2048 бит (число 600 цифр в десятичной дроби) тестирование всех возможностей дляaиbбудет химерическим. На сегодняшний день с числами такого размера алгоритм считается безопасным.

Именно на этом уровне кроется главный недостаток протокола Диффи-Хеллмана. Чтобы быть в безопасности, алгоритм должен использовать большие числа. В результате мы теперь предпочитаем использовать алгоритм ECDH, вариант Диффи-Хеллмана с использованием алгебраической кривой, и в данном случаеэллиптической кривой. Это позволит нам работать на гораздо меньших количествах, сохраняя при этом эквивалентную безопасность, и, следовательно, сократить ресурсы, необходимые для вычислений и хранения.

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

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

Грубо говоря, закрытый ключ — это случайное число между 1 и n-1 (n — порядок кривой), а открытый ключ — это уникальная точка на кривой, определяемая закрытым ключом путем сложения и удвоения точек от генерирующей точки таким образом, что:

K = k·G

ГдеK— открытый ключ, k— закрытый ключ, аG— генерирующая точка.

Одним из свойств этой ключевой пары является то, что очень легко определить K, зная k и G, но сегодня невозможно определитьk, знаяKи G. Это односторонняя функция.

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

Поэтому мы будем использовать это свойство для адаптации нашего алгоритма Диффи-Хеллмана. Таким образом, принцип работы ECDH заключается в следующем:

  • Алиса и Боб вместе договариваются о криптографически безопасной эллиптической кривой и ее параметрах. Эта информация является общедоступной.
  • Алиса генерирует случайное числоka, котороебудет ее закрытым ключом. Этот закрытый ключ должен оставаться секретным. Он определяет свой открытый ключKaпутем добавления и удвоения точек на выбранной эллиптической кривой.
Ka = ka·G
  • Боб также генерирует случайное число, которое будет его закрытым ключомkb. И вычисляет связанный открытый ключKb.
Kb = kb·G
  • Алиса и Боб обмениваются своими открытыми ключамиKaиKbчерез незащищенную публичную сеть.
  • Алиса вычисляет точку (x,y) на кривой, применяя свой закрытый ключkaиз открытого ключа Bob Kb.
(x,y) = ka·Kb
  • Боб вычисляет точку (x,y) на кривой, применяя свой закрытый ключkbизоткрытого ключа Алисы Ка.
(x,y) = kb·Ka
  • Алиса и Боб получают одну и ту же точку на эллиптической кривой. Общим секретом будет абсциссаxэтой точки.

Они получают один и тот же общий секрет, потому что:

(x,y) = ka·Kb = ka·kb·G = kb·ka·G = kb·Ka

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

Таким образом, ECDH является алгоритмом обмена ключами. Он часто будет использоваться вместе с другими криптографическими методами для определения протокола. Например, ECDH используется в основе TLS (Transport Layer Security), протокола шифрования и аутентификации, используемого для транспортного уровня Интернета. TLS использует ECDHE для обмена ключами, вариант ECDH, где ключи эфемерны для обеспечения постоянной конфиденциальности. В дополнение к последнему, TLS также использует алгоритм аутентификации, такой как ECDSA, алгоритм шифрования, такой как AES, ихэш-функцию, такую как SHA256.

TLS определяет, в частности, «s» в «https», а также небольшой замок, который вы видите в своем интернет-браузере в левом верхнем углу, которые гарантируют вам шифрование связи. Таким образом, вы используете ЕСПЧ, читая эту статью, и вы, вероятно, используете ее ежедневно, не осознавая этого.

Транзакция уведомления.

Как мы обнаружили в предыдущей части, ECDH является вариантом обмена Диффи-Хеллмана с участием ключевых пар, установленных на эллиптической кривой. Это хорошо, ключевые пары, соблюдающие этот стандарт, у нас есть много наших биткойн-кошельков!

Поэтому идея будет заключаться в том, чтобы использовать ключевые парыиерархических детерминированных кошельков Биткойнаобеих заинтересованных сторон для установления общих и эфемерных секретов между ними. Поэтому в BIP47 используется ECDHE (эллиптическая кривая Диффи-Хеллмана эфемерная).

ECDHE впервые используется в BIP47 для передачи кода платежа от отправителя получателю. Это знаменитая транзакция уведомления. Действительно, для использования BIP47 каждая из двух сторон (отправитель, отправляющий платежи, и получатель, получающий платежи) должна знать код платежа другой стороны. Это будет необходимо для получения эфемерных открытых ключей и, следовательно, выделенных принимающих адресов.

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

Действительно, как я уже упоминал, адреса BIP47 не являются производными от seed получателя (в противном случае вы могли бы также использовать один из егоxpubsнапрямую), а являются результатом расчета с участием двух кодов платежей: кода получателя и кода отправителя. Поэтому, если получатель потеряет свой кошелек и попытается восстановить его из своего семени, ему обязательно придется иметь все коды платежей людей, которые отправили ему биткоины через BIP47.

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

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

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

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

Действительно, код платежа напрямую не выводит адреса, используемые для приема платежей BIP47. Вместо этого адреса получаются путем применения ECDHE между дочерними ключами кодов платежей обеих сторон.

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

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

Например, предположим, что я хочу пожертвовать с BIP47 мирному протестному движению в Канаде:

  • Эта организация опубликовала свой платежный код непосредственно на своем веб-сайте или в социальных сетях.
  • Поэтому этот код связан с движением.
  • Я извлекаю этот код платежа.
  • Прежде чем я смогу отправить им транзакцию, мне нужно убедиться, что они знают мой личный код платежа, который также связан с моей личностью, поскольку я использую его для получения транзакций из моих социальных сетей.

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

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

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

Шаблон конфиденциальности схемы повторно используемого кода платежа

На самом деле, для классической модели конфиденциальности Биткойна часто бывает трудно полностью нарушить поток информации между ключевой парой и пользователем, особенно при проведении транзакций удаленно. Например, в случае кампании по сбору пожертвований получатель будет обязан раскрыть адрес или открытый ключ на своем веб-сайте или в социальных сетях. Правильное использование BIP47, т.е. с транзакцией уведомления, позволяет решить эту проблему благодаря ECDHE и уровню шифрования, который мы будем изучать.

Очевидно, что классическая модель конфиденциальности Биткойна по-прежнему наблюдается на уровне эфемерных открытых ключей, полученных из ассоциации двух платежных кодов. Эти две модели взаимозависимы. Здесь просто хочу подчеркнуть, что, в отличие от классического использования открытого ключа для получения биткоинов, код платежа может быть связан с личностью, потому что информация «Боб совершает транзакцию с Алисой» нарушается в другое время. Код платежа используется для генерации платежных адресов, но, глядя только на блокчейн, невозможно связать платежную транзакцию BIP47 с кодами платежей, используемыми для ее совершения.

Построение уведомительной сделки.

Теперь давайте посмотрим, как работает эта транзакция уведомления. Допустим, Алиса хочет отправить деньги Бобу с помощью BIP47. В моем примере Алиса выступает в качестве отправителя, а Боб в качестве получателя. Последний опубликовал свой платежный код на своем веб-сайте. Алиса уже знает код платежа Боба.

1.Алиса вычисляет секрет, общий с ECDH:

  • Она выбирает пару ключейиз своего HD-кошелька, который находится в другой ветви ее платежного кода. Будьте осторожны, эта пара не должна быть легко связана с адресом уведомления Алисы или с личностью Алисы (см. предыдущий раздел).
  • Алиса выбирает закрытый ключ для этой пары. Мы называем его «а» (строчная буква).
a
  • Алиса извлекает открытый ключ, связанный с адресом уведомления Боба. Этот ключ является первой дочерней компанией, полученной после кода платежа Боба (индекс 0). Мы называем этот открытый ключ «B» (прописная буква). Закрытый ключ, связанный с этим открытым ключом, называется «b» (строчная буква). «B» определяется путемсложения и удвоения точекsна эллиптической кривой от «G» (генерирующая точка) с «b» (закрытый ключ).
B = b·G
  • Алиса вычисляет секретную точку «S» (прописную) на эллиптической кривой, добавляя и удваивая точки, применяя свой закрытый ключ «a» из открытого ключа Боба «B».
S = a·B
  • Алиса вычисляет ослепляющий коэффициент «f», который зашифрует ее платежный код. Для этого он определит псевдослучайный номер с функцией HMAC-SHA512. Во втором входе этой функции она использует значение, которое сможет найти только Боб: (x), которое является абсциссой секретной точки, рассчитанной ранее. Первым входом является (o), который является UTXO, потребляемымв качестве входных данных этой транзакции (outpoint).
f = HMAC-SHA512(o, x)

2.Алиса преобразует свой личный код платежа в базу 2 (двоичную).

3.It должен использовать этот ослепляющий фактор в качестве ключа для выполнения симметричного шифрования полезной нагрузки своего кода платежа. Используемый алгоритм шифрования — это простоXOR. Выполненная операция сопоставима сфигурой Вернама, также называемой «Одноразовым блокнотом»:

  • Алиса сначала разделяет свой ослепляющий фактор на две части: первые 32 байта называются «f1», а последние 32 байта — «f2». Итак, мы имеем:
f = f1 || f2
  • Алиса вычисляет шифр (x’) абсциссы открытого ключа (x) своего платежного кода и зашифрованный (c’) своего строкового кода (c) отдельно. «F1» и «F2» действуют как ключи шифрования соответственно. Используется операция XOR (или эксклюзив).
x' = x XOR f1
c' = c XOR f2
  • Алиса заменяет фактические значения открытого ключа abscissa (x) и строкового кода (c) в своем платежном коде на зашифрованные значения (x’) и (c’).

Прежде чем продолжить техническое описание этой транзакции уведомления, давайте остановимся на этой операции XOR. XOR — логический оператор битового уровня, основанный на булевой алгебре. Из двух битовых операндов он возвращает 1, если биты одного ранга различны, и возвращает 0, если биты одного ранга равны. Вот таблица истинности XOR по значениям операндов D и E:

DED XOR E
000
011
101
110

Как что:

0110 XOR 1110 = 1000

Или:

010011 XOR 110110 = 100101

С ECDH использование XOR в качестве уровня шифрования особенно последовательно. Во-первых, благодаря этому оператору шифрование симметрично. Это позволит получателю расшифровать код платежа с помощью того же ключа, который включал шифрование. Ключ шифрования и расшифровки вычисляется из секрета, совместно используемого с помощью ECDH.

Эта симметрия обеспечивается свойствами коммутативности и ассоциативности оператора XOR:

 # Autres propriétés :
 -> D ⊕ D = 0
 -> D ⊕ 0 = D
 
 # Commutativité :
 D ⊕ E = E ⊕ D
 
 # Associativité :
 D ⊕ (E ⊕ Z) = (D ⊕ E) ⊕ Z = D ⊕ E ⊕ Z
 
 # Symétrie :
 Si : D ⊕ E = L
 Alors :  D ⊕ L = D ⊕ (D ⊕ E) = D ⊕ D ⊕ E = 0 ⊕ E = E
 ->  D ⊕ L = E

Во-вторых, этот метод шифрования очень похож на шифр Vernam (One-Time Pad), единственный известный на сегодняшний день алгоритм шифрования, который имеет безусловную (или абсолютную) безопасность. Чтобы шифр Вернама имел эту характеристику, ключ шифрования должен быть совершенно случайным, иметь тот же размер, что и сообщение, и использоваться только один раз. В методе шифрования, используемом здесь для BIP47, ключ действительно имеет тот же размер, что и сообщение, ослепляющий фактор точно такой же размер, как и сцепление абсциссы открытого ключа с цепным кодом кода платежа. Этот ключ шифрования используется только один раз. С другой стороны, этот ключ не является результатом идеальной опасности, поскольку этоHMAC. Это скорее псевдослучайно. Так что это не фигура Вернама, но метод приближается.

Вернемся к нашему построению транзакции уведомления:

4.Поэтому Алиса в настоящее время имеет свой код платежа с зашифрованной полезной нагрузкой. Он будет создавать и транслировать транзакцию, включающую его открытый ключ «A» в качестве входных данных, выход на адрес уведомления Боба и выходной OP_RETURN, состоящий из его кода платежа с зашифрованной полезной нагрузкой. Эта транзакция является транзакцией уведомления.

OP_RETURN является Opcode, т.е. скриптом, который позволяет пометитьвывод транзакции Bitcoinкак недопустимый. Сегодня он используется для распространения или закрепления информации на блокчейне Биткойна. Он может хранить до 80 байт данных, которые записываются в цепочку, и поэтому видны всем остальным пользователям.

Как мы видели впредыдущей части, Диффи-Хеллман используется для создания общего секрета между двумя пользователями, которые общаются по незащищенной сети и потенциально наблюдаются злоумышленниками. В BIP47 ECDH используется для того, чтобы иметь возможность общаться в сети Bitcoin, которая по своей природе является прозрачной коммуникационной сетью и наблюдается многими злоумышленниками. Общий секрет, вычисляемый через обмен ключами Диффи-Хеллмана на эллиптической кривой, затем используется для шифрования секретной информации, подлежащей передаче: код платежа отправителя (Алиса).

Вот диаграмма из BIP47, которая иллюстрирует то, что только что было описано:

Схема Алисы отправляет свой скрытый код платежа на адрес уведомления Боба

Фото: Многоразовые коды платежей для иерархических детерминированных кошельков, Юстус Ранвье. https://github.com/bitcoin/bips/blob/master/bip-0047.mediawiki

Если мы сопоставим этот шаблон с тем, что я описал вам ранее:

  • «Кошелек Priv-Key» на стороне Алисы соответствует :a.
  • «Child Pub-Key 0» на стороне Боба соответствует :B.
  • «Общий секрет уведомления» соответствует:f.
  • «Замаскированный код платежа» соответствует скрытому коду платежа, т.е. с зашифрованной полезной нагрузкой: x’ и c’.
  • «Транзакция уведомления» — это транзакция, содержащая OP_RETURN.

Я суммирую шаги, которые мы только что видели вместе, чтобы завершить транзакцию уведомления:

  • Алиса извлекает код платежа Боба и адрес уведомления.
  • Алиса выбирает принадлежащий ей UTXO из своего HD кошелька с соответствующей парой ключей.
  • Он вычисляет секретную точку на эллиптической кривой с помощью ECDH.
  • Он использует эту секретную точку для расчета HMAC, который является ослепляющим фактором.
  • Она использует этот ослепляющий фактор для шифрования полезной нагрузки своего личного кода платежа.
  • Он использует OP_RETURN вывод транзакции для передачи скрытого кода платежа Бобу.

Для того чтобы более подробно понять, как это работает, и в частности использование OP_RETURN, давайте вместе изучим реальную транзакцию уведомления. Я сделал транзакцию такого типа в Testnet, которую вы можете найти, нажав здесь:

https://mempool.space/fr/testnet/tx/0e2e4695a3c49272ef631426a9fd2dae6ec3a469e3a39a3db51aa476cd09de2e

TXID:

0e2e4695a3c49272ef631426a9fd2dae6ec3a469e3a39a3db51aa476cd09de2e
Уведомление о транзакции BIP47

Фото: https://blockstream.info/

Наблюдая за этой транзакцией, мы уже можем видеть, что она имеет один вход и 4 выхода:

  • Первым выводом является OP_RETURN, содержащая мой скрытый код платежа.
  • Второй вывод 546 sats указывает на адрес уведомления моего получателя.
  • Третий выход в 15 000 спутников представляет собой плату за обслуживание, потому что я использовал Samourai Wallet для создания этой транзакции.
  • Четвертый выход в два миллиона спутников представляет собойобмен, то есть оставшуюся разницу моих входных данных, которая возвращается на другой адрес, принадлежащий мне.

Наиболее интересным для изучения, очевидно, является вывод 0 с использованием OP_RETURN. Давайте подробнее рассмотрим, что в нем есть:

Вывод OP_RETURN уведомления транзакции BIP47

Фото: https://blockstream.info/

Обнаруживаем скрипт вывода в шестнадцатеричном формате:

6a4c50010002b13b2911719409d704ecc69f74fa315a6cb20fdd6ee39bc9874667703d67b164927b0e88f89f3f8b963549eab2533b5d7ed481a3bea7e953b546b4e91b6f50d800000000000000000000000000

В этом скрипте мы можем препарировать несколько частей:

6a4c50010002b13b2911719409d704ecc69f74fa315a6cb20fdd6ee39bc9874667703d67b164927b0e88f89f3f8b963549eab2533b5d7ed481a3bea7e953b546b4e91b6f50d800000000000000000000000000

# Des opcodes :
6a4c

# Un octet qui indique la taille de la charge utile (80 octets) :
50

# Les métadonnées de mon code de paiement en clair :
010002

# L'abscisse chiffrée de la clé publique de mon code de paiement :
b13b2911719409d704ecc69f74fa315a6cb20fdd6ee39bc9874667703d67b164

# Le code de chaine chiffré de mon code de paiement :
927b0e88f89f3f8b963549eab2533b5d7ed481a3bea7e953b546b4e91b6f50d8

# Du rembourrage pour arriver à 80 octets :
00000000000000000000000000

Среди опкодов мы можем распознать 0x6a, который обозначает OP_RETURN, и 0x4c, который обозначает OP_PUSHDATA1. Байт, следующий за этим последним опкодом, указывает размер полезной нагрузки, следующей. Он указывает на 0x50, или 80 байт.

Затем идет код платежа с зашифрованной полезной нагрузкой.

Вот мой незашифрованный код платежа, используемый в этой транзакции:

# En base 58 :
PM8TJQCyt6ovbozreUCBrfKqmSVmTzJ5vjqse58LnBzKFFZTwny3KfCDdwTqAEYVasn11tTMPc2FJsFygFd3YzsHvwNXLEQNADgxeGnMK8Ugmin62TZU

# En base 16 (HEX) :
4701000277507c9c17a89cfca2d3af554745d6c2db0e7f6b2721a3941a504933103cc42add94881210d6e752a9abc8a9fa0070e85184993c4f643f1121dd807dd556d1dc000000000000000000000000008604e4db

Если мы сравним мой код платежа в понятном виде с OP_RETURN, то увидим, что HRP (в коричневом) и контрольная сумма (в розовом) не передаются. Это нормально, эта информация предназначена для человека.

Затем мы можем распознать (зеленым цветом) версию (0x01), битовое поле (0x00) и четность открытого ключа (0x02). И, в конце кода платежа, пустые байты черного цвета (0x00), которые позволяют заполнению достигать в общей сложности 80 байт. Все эти метаданные передаются в прозрачном (незашифрованном виде).

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

Получение уведомления о сделке.

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

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

1.Боб отслеживает транзакции, которые создают выходные данные с его адресом уведомления.

2.Когда транзакция имеет выходные данные на своем адресе уведомления, Боб анализирует ее, чтобы увидеть, содержит ли она выходные OP_RETURN стандарту BIP47.

3.Если первый байт полезной нагрузки OP_RETURN 0x01, Боб начинает поиск возможного секрета, которым поделились с ECDH:

  • Боб выбирает открытый ключ в качестве входных данных для транзакции. То есть открытый ключ Алисы с именем «А» с:
A = a·G
  • Боб выбирает закрытый ключ «b», связанный с его личным адресом уведомления:
b
  • Боб вычисляет секретную точку «S» (ECDH shared secret) на эллиптической кривой путем сложения и удвоения точек, применяя свой закрытый ключ «b» к открытому ключу Алисы «A»:
S = b·A
  • Боб определяет ослепляющий фактор «f», который будет расшифровывать полезную нагрузку кода платежа Алисы. Точно так же, как Алиса вычислила ранее, Боб найдет «f», применив HMAC-SHA512 к (x) значению abscissa секретной точки «S» и (o) UTXO, потребляемому в качестве входных данных этой транзакции уведомления:
f = HMAC-SHA512(o, x)

4.Bob интерпретирует OP_RETURN данные в транзакции уведомления как код платежа. Он просто расшифрует полезную нагрузку этого потенциального кода платежа благодаря ослепляющему фактору «f»:

  • Боб разделяет ослепляющий фактор «f» на две части: первые 32 байта «f» будут «f1», а последние 32 байта — «f2».
  • Боб расшифровывает значение зашифрованной абсциссы (x’) открытого ключа платежного кода Алисы:
x = x' XOR f1
  • Боб расшифровывает значение зашифрованного строкового кода (c’) кода платежа Алисы:
c = c' XOR f2

5.Bob проверяет, является ли значение открытого ключа кода платежа Алисы частью группы secp256k1. Если это так, он интерпретирует это как действительный код платежа. В противном случае он игнорирует эту транзакцию.

Теперь, когда Боб знает код платежа Алисы, она может отправить ему до 2^32 платежей, без необходимости переделывать транзакцию уведомления такого типа.

Почему это работает? Как Бобу удается определить тот же ослепляющий фактор, что и Алиса, и таким образом взломать ее платежный код? Рассмотрим более подробно работу ECDH в том, что только что было описано.

Прежде всего, мы имеем дело с симметричным шифрованием. Это означает, что ключ шифрования и ключ расшифровки имеют одно и то же значение. Этот ключ в транзакции уведомления является ослепляющим фактором (f = f1 || f2). Поэтому Алиса и Боб должны получить одинаковое значение для f, не передавая его напрямую, поскольку злоумышленник может украсть его и расшифровать секретную информацию.

Этот ослепляющий фактор получается путем применения HMAC-SHA512 к двум значениям: абсциссе секретной точки и UTXO, потребляемой в качестве входных данных для транзакции. Поэтому Боб должен иметь эти две части информации, чтобы расшифровать полезную нагрузку платежного кода Алисы.

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

Как видно из части о Диффи-Хеллмане, просто обмениваясь соответствующими открытыми ключами и тайно применяя свои закрытые ключи к открытому ключу друг друга, Алиса и Боб могут найти точную и секретную точку на эллиптической кривой. Транзакция уведомления опирается на следующий механизм:

# La paire de clés de Bob :
B = b·G

# La paire de clés d'Alice :
A = a·G

# Pour un point secret S (x,y) :
S = a·B = a·b·G = b·a·G = b·A
Схема, генерирующая общий секрет с ECDHE

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

Боб интерпретирует транзакцию уведомления Алисы

Фото: Многоразовые коды платежей для иерархических детерминированных кошельков, Юстус Ранвье. https://github.com/bitcoin/bips/blob/master/bip-0047.mediawiki

Если мы сопоставим этот шаблон с тем, что я описал вам ранее:

  • «Кошелек Pub-Key» на стороне Алисы соответствует :A.
  • «Child Priv-Key 0» на стороне Боба соответствует :b.
  • «Общий секрет уведомления» соответствует:f.
  • «Замаскированный код платежа» соответствует скрытому коду платежа Алисы, т.е. с зашифрованной полезной нагрузкой: x’ и c’.
  • «Транзакция уведомления» — это транзакция, содержащая OP_RETURN.

Я резюмирую шаги, которые мы только что видели вместе, чтобы получить и интерпретировать транзакцию уведомления:

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

Платежная транзакция BIP47.

Теперь давайте вместе изучим процесс оплаты с помощью BIP47. Чтобы напомнить вам о текущей ситуации:

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

Прежде чем объяснить этот процесс, я думаю, важно вспомнить, над какими индексамимы в настоящее время работаем:

Производныйпуть кода платежаописывается как m/47’/0’/0’/.

Следующая глубина распределяет индексы следующим образом:

  • Первая нормальная дочерняя пара (не усиленная) используется для генерации адреса уведомления, о котором мы говорили в предыдущей части: m/47’/0’/0’/0/0/0/.
  • Обычные дочерние пары ключей используются в ECDH для генерации адресов приема платежей BIP47, как мы увидим в этой части: m/47’/0’/0’/ от 0 до 2 147 483 647/.
  • Усиленные дочерние пары ключей представляют собой эфемерные коды платежей: m/47’/0’/0’/ от 0′ до 2,147,483,647’/.

Каждый раз, когда Алиса хочет отправить платеж Бобу, она получает новый, уникальный пустой адрес, опять же благодаря протоколу ECDH:

  • Алиса выбирает первый закрытый ключ, полученный из ее личного многократно используемого кода платежа:
a
  • Алиса выбирает первый неиспользуемый открытый ключ, полученный из кода платежа Боба. Этот открытый ключ, мы будем называть его «B». Он связан с закрытым ключом «b», о котором знает только Боб.
B = b·G
  • Алиса вычисляет секретную точку «S» на эллиптической кривой, добавляя и удваивая точки, применяя свой закрытый ключ «a» из открытого ключа Боба «B»:
S = a·B
  • Из этой секретной точки Алиса вычислит общий секрет «s» (строчная буква). Для этого он выбирает абсциссу секретной точки «S» с именем «Sx» и передает это значение в хэш-функцию SHA256.
s = SHA256(Sx)

Не доверяйте. Проверять! Если вы хотите понять основы хэш-функции, вы найдете свое счастье вэтой статье. И если вы не доверяете NIST (вы правы), и вы хотите иметь возможность подробно понять, как работает SHA256, я объясню все вэтой статье.

  • Алиса использует этот общий секрет «s» для вычисления адреса получения платежа в биткойнах. Во-первых, он проверяет, что «s» содержится в порядке кривой secp256k1. Если нет, он увеличивает индекс открытого ключа Боба, чтобы получить еще один общий секрет.
  • На втором шаге он вычисляет открытый ключ «K0», добавляя к эллиптической кривой точки «B» и «s· G». Другими словами, Алиса добавляет открытый ключ, полученный из кода платежа Боба «B», с другой точкой, вычисляемой на эллиптической кривой путем сложения и удвоения точек с общим секретом «s» из генерирующей точки кривой secp256k1 «G». Эта новая точка представляет собой открытый ключ, и мы называем его «K0»:
K0 = B + s·G
  • С помощью этого открытого ключа «K0» Алиса может получить пустой принимающий адрес стандартным способом (например, SegWit V0 в Bech32).

Как только Алиса получит этот принимающий адрес «K0», принадлежащий Бобу, она может построить классическую транзакцию Bitcoin, выбрав UTXO, который принадлежит ей, на другой ветви ее HD-кошелька и потратив средства на адрес «K0» Боба.

Алиса отправляет биткоины с BIP47 Бобу

Фото: Многоразовые коды платежей для иерархических детерминированных кошельков, Юстус Ранвье. https://github.com/bitcoin/bips/blob/master/bip-0047.mediawiki

Если мы сопоставим этот шаблон с тем, что я описал вам ранее:

  • «Child Priv-Key» со стороны Алисы соответствует :a.
  • «Child Pub-Key 0» на стороне Боба соответствует :B.
  • «Секрет платежа 0» соответствует :s.
  • «Оплата Pub-Key 0» соответствует:K0.

Я резюмирую шаги, которые мы только что видели вместе, чтобы отправить платеж BIP47:

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

Если она хочет сделать второй платеж, она воспроизведет вышеуказанные шаги, за исключением того, что она выберет второй открытый ключ, полученный из кода платежа Боба. То есть следующий неиспользуемый ключ. Затем у него будет второй адрес получения, принадлежащий Бобу «K1».

Алиса получает три адреса получения BIP47 от Боба

Фото: Многоразовые коды платежей для иерархических детерминированных кошельков, Юстус Ранвье. https://github.com/bitcoin/bips/blob/master/bip-0047.mediawiki

Он может продолжаться и получать до 2^32 пустых адресов, принадлежащих Бобу.

Со стороны, глядя на блокчейн Биткоина, теоретически невозможно отличить платеж BIP47 от обычного платежа. Вот пример платежной транзакции BIP47 в Testnet:

https://blockstream.info/testnet/tx/94b2e59510f2e1fa78411634c98a77bbb638e28fb2da00c9f359cd5fc8f87254

TXID:

94b2e59510f2e1fa78411634c98a77bbb638e28fb2da00c9f359cd5fc8f87254

Это выглядит как классическая транзакция с потребляемым входом, платежным выходом 210 000 спутников и обменом:

Биткойн-платежная транзакция с BIP47

Фото: https://blockstream.info/

Получение оплаты BIP47 и получение закрытого ключа.

Алиса только что сделала свой первый платеж на пустой адрес BIP47, принадлежащий Бобу. Теперь давайте вместе посмотрим, как Боб получает этот платеж. Мы также увидим, почему у Алисы нет доступа к закрытому ключу адреса, который она только что сгенерировала, и как Боб находит этот ключ, чтобы потратить биткойны, которые он только что получил.

Как только Боб получает уведомление о транзакции от Алисы, он получает открытый ключ BIP47 «K0» еще до того, как его корреспондент отправит ему какой-либо платеж. Поэтому он соблюдает любые платежи по соответствующему адресу. На самом деле, он даже сразу выведет несколько адресов, которые он будет наблюдать (K0, K1, K2, K3 …). Вот как он получает этот открытый ключ «K0»:

  • Боб выбирает первый дочерний закрытый ключ, полученный из его кода платежа. Этот закрытый ключ называется «b». Он связан с открытым ключом «B», с помощью которого Алиса выполниласвои вычисления на предыдущем шаге:
b
  • Боб выбирает первый открытый ключ Алисы, полученный из ее кода платежа. Этот ключ называется «A». Он связан с закрытым ключом «а», с помощью которого Алиса делала свои расчеты, и о котором знает только Алиса. Боб может выполнить этот процесс, так как он знает код платежа Алисы, который был отправлен ему странзакцией уведомления.
 A = a·G
  • Боб вычисляет секретную точку «S», добавляя и удваивая точки на эллиптической кривой, применяя свой закрытый ключ «b» к открытому ключу Алисы «A». Здесь мы находим использование ECDH, которое гарантирует нам, что эта точка «S» будет одинаковой для Боба и для Алисы.
S = b·A
  • Точно так же, как это сделала Алиса, Боб изолирует абсциссу от этой точки «S». Мы назвали это значение «Sx». Он передает это значение в функцию SHA256, чтобы найти общий секрет «s» (строчная буква).
s = SHA256(Sx)
  • Все еще так же, как и Алиса, Боб вычисляет точку «s· G» на эллиптической кривой. Затем он добавляет эту секретную точку своим открытым ключом «B». Затем он получает новую точку на эллиптической кривой, которую он интерпретирует как открытый ключ «K0»:
K0 = B + s·G

Как только у Боба есть этот открытый ключ «K0», он может получить связанный закрытый ключ, чтобы иметь возможность потратить свои биткойны. Он единственный, кто может генерировать это число.

  • Боб складывает закрытый ключ своей дочери «b», полученный из его личного кода платежа. Он единственный, кто может получить значение «b». Затем он добавляет «b» с общим секретом «s», чтобы получить закрытый ключ k0, K0:
k0 = b + s

Используя групповой закон эллиптической кривой, Боб получает именно тот закрытый ключ, который используется Алисой. Поэтому мы имеем:

K0 = k0·G
Боб генерирует свои адреса получения BIP47

Фото: Многоразовые коды платежей для иерархических детерминированных кошельков, Юстус Ранвье. https://github.com/bitcoin/bips/blob/master/bip-0047.mediawiki

Если мы сопоставим этот шаблон с тем, что я описал вам ранее:

  • «Child Priv-Key 0» на стороне Боба соответствует :b.
  • «Child Pub-Key 0» на стороне Алисы соответствует :A.
  • «Секрет платежа 0» соответствует :s.
  • «Оплата Pub-Key 0» соответствует:K0.
  • «Оплата Priv-Key 0» соответствует :k0.

Я суммирую шаги, которые мы только что видели вместе, чтобы получить платеж BIP47 и рассчитать соответствующий закрытый ключ:

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

Поскольку Алиса не может получить «b», закрытый ключ Боба, она не может определить k0, закрытый ключ, связанный с адресом получения BIP47 Боба.

Схематично мы можем представить вычисление общего секрета «S» следующим образом:

Вычисляет секрет, общий с ECDHE

Как только общий секрет найден с ECDH, Алиса и Боб вычисляют открытый ключ платежа BIP47 «K0», и Боб также вычисляет связанный закрытый ключ «k0»:

Получение адреса получения BIP47 из общего секрета

Возврат платежа BIP47.

Поскольку Боб знает о многоразовом платежном коде Алисы, у него уже есть вся информация, необходимая для отправки ей возмещения. Ему не нужно будет снова связываться с Алисой, чтобы запросить какую-либо информацию. Он просто должен будет уведомить ее с помощью транзакции уведомления, в частности, чтобы она могла получить свои адреса BIP47 со своим семенем, затем он также может отправить ей до 2^ 32 платежей.

Затем Боб может возместить Алисе то же самое, что она отправила ему платежи. Роли меняются местами:

Боб отправляет Алисе возмещение с помощью BIP47

Фото: Многоразовые коды платежей для иерархических детерминированных кошельков, Юстус Ранвье. https://github.com/bitcoin/bips/blob/master/bip-0047.mediawiki

Источник