Как получить закрытый ключ из двух подписей с одинаковым значением k?

Я написал свой собственный алгоритм подписи ECDSA только для создания модульных тестов.

С его помощью я создал две подписи, которые шли в транзакцию 56ec7ca7df... , отправляющую из 1GXFXm3es... . В этих подписях использовались одни и те же значения k, хотя значения k никогда не должны использоваться повторно.

Позже кто-то смог украсть 0,0016 биткойнов у 1GXFXm3es.... и отправить их на 17WRjamox6VhTUaHsTWfFnMNDYHvwCtWio.

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

Как получить закрытый ключ из двух подписей с одинаковым значением k?

Для получения дополнительной информации о том, как найти kзначения с учетом пластичности транзакций, см. мой ответ: bitcoin.stackexchange.com/a/35850/6091

Ответы (3)

Подписи ECDSA представляют собой пары (r,s), где r=(k G).x mod n и s = (m + r x)/k mod n, где x — секретный ключ, k — случайный одноразовый номер, а m это сообщение.

Если у вас есть два значения s s1 и s2 для одного и того же секретного ключа и с одним и тем же одноразовым номером k (и, следовательно, с одним и тем же значением r), ​​выполняется следующее:

  • s1 = (m1 + r*x)/k
  • s2 = (m2 + r*x)/k

Отсюда мы можем вывести:

  • s1 * k = m1 + r*x
  • с2 * к = м2 + г*х
  • (s1 - s2) * k = m1 - m2
  • k = (m1 - m2) / (s1 - s2)
  • х = (s1 * (m1 - m2) / (s1 - s2) - m1) / r
  • x = (m1 s2 - m2 s1) / (r*(s1 - s2)) (все по модулю n)

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

Этот вид атаки известен и активно используется в сети Биткойн как минимум с 2013 года: https://bitcointalk.org/index.php?topic=271486.0 . Не используйте повторно значения k. Используйте RFC6979 для их детерминированного, но безопасного создания.

Также обратите внимание, что недостаточно, чтобы одноразовые номера были разными . Они также не могут быть связаны известным образом. Например, вы не можете использовать k для одной подписи и k+1 для следующей работы.

Спасибо. Мне нужны были детерминированные подписи, поэтому я просто ввел фиксированное число для своих модульных тестов. Но RFC6979 — гораздо лучшее решение.
В итоге я реализовал RFC6979, и это значительно упростило взаимодействие с подписями.

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

Это просто!!

1. https://blockchain.info/tx/56ec7ca7dfea1c105acf0974331686e973b737e1fd97fc7f970a0cf0882ba7ac?format=hex

2. https://2xoin.com/getRSZfromRawTX/

"sigR": "00db0c51cc634a4096374b0b895584a3ca2fb3bea4fd0ee2361f8db63a650fcee6",
"sigS": "59a23e4521da413a2c7d0f9a668eedc2e5eac88347c67c48dcca0128fda1cad7",
"sigZ": "4b2cdf712dc7d3fac8e7ed63b3a2e806556ca7d5c30ed5f4b34dbb2a12b0c18f",
"pubKey": "02ac75a5bd9640d55b8300fad347740ac447e4604fbc59260c2dce39f356a0558f",

"sigR": "00db0c51cc634a4096374b0b895584a3ca2fb3bea4fd0ee2361f8db63a650fcee6",
"sigS": "39d5e056231a5823dc0957e3d0fa3923ce71f781ad67140a6433fe6829bdf811",
"sigZ": "1cd506860c52d7e042f56b33a856b94fdefa3bcc808a06dd3b82619db2c01969",
"pubKey": "02ac75a5bd9640d55b8300fad347740ac447e4604fbc59260c2dce39f356a0558f",

возможное k = 539

Открытый ключ: C 02db0c51cc634a4096374b0b895584a3ca2fb3bea4fd0ee2361f8db63a650fcee6

возможно k = fffffffffffffffffffffffffffffffebaaedce6af48a03bbfd25e8cd0363c08

Открытый ключ: C 03db0c51cc634a4096374b0b895584a3ca2fb3bea4fd0ee2361f8db63a650fcee6 !!!!!

Приватный ключ = 79c7f119413edb1a9a9a2ea655196e0e3b6380b6d612dcc69c7c143816c8ef29

C L1JSKFNgNh7FyNw642ofHzivm8ua4EqpEqZyVQ8rmC6q6S9RgzYj

Вот ответ на ваш вопрос!