Для данного закрытого ключа, сгенерированного MyEtherWallet , я хотел бы видеть, что у меня есть инструменты для независимого получения аналогичных результатов.
Написал оболочку вокруг Keccak , чтобы принимать как шестнадцатеричные, так и ASCII-входы для хеширования sha3-224, sha3-256, sha3-384 или sha3-512. Хэши соответствуют тестовым векторам . Хотел бы применить его с помощью команд bitcoin-explorer ( bx ) версии 3 , чтобы посмотреть, смогу ли я синтезировать адреса ETH. Если мне удастся синтезировать адреса для альткойнов ETH, XMR и MAX, я отправлю запрос на включение, чтобы добавить возможности хеширования sha3 в версию bx3, и обновлю эту вики , касающуюся применения bx к альткойнам.
Обновление: Ой! Я вижу, вы хотите это от закрытого ключа, а не от открытого ключа. Это сложнее. Вы должны сначала получить открытый ключ из закрытого ключа, что лучше всего сделать с помощью криптобиблиотеки EC. Я могу показать вам пример кода на Scala, но EC-математика для меня в основном черный ящик. Во-первых, интерпретируйте 256-битный закрытый ключ как большое целое число без знака. Затем см., например, здесь . Curve
представляет названную эллиптическую кривую secp256k1
. Детали математики, увы, мне не под силу, но надеюсь, в какой бы среде вы ни программировали, у вас есть доступ к высококачественной криптобиблиотеке.
Обновление 2: в ветке комментариев я предположил, где хэш-функция Ethereum отличается от стандарта SHA3. Мое предположение было ошибочным, версия, которую я считал несовместимым изменением, на самом деле использует версию Ethereum. Спасибо работе Эрика Маккарти , который подробно изучил это. Пожалуйста, смотрите этот комментарий ниже для более подробной информации.
OldDiversifiedKeccakPadding
и MultiRatePadding
. Ethereum использует старую стратегию. Я думаю (но не уверен!) для параметра диверсификатора установлено значение по умолчанию 0. На практике простой способ решить это - сравнить хэш пустой строки. Окончательно стандартизированный SHA3-256 хэширует пустую строку в a7ffc6f8bf1ed76651c14756a061d662f580ff4de43b49fa82d80a4b80f8434a
. Вариант Ethereum использует хэши той же строки, что и c5d2460186f7233c927e7db2dcc703c0e500b653ca82273b7bfad8045d85a470
.sha3_256
а старую версию как keccak_256
. Возможно, это неправильное название, поскольку сам Keccak был обновлен, но соглашение об именах кажется обычным. Вам нужно будет найти библиотеку, подходящую для ваших целей, которая делает доступным соответствующий, более старый вариант хэша.genShortMsg(1088, 512, 256, "keccak-256", true); // keccak-256, NOT FIPS202_SHA3_256
будет воспроизводить хэши, используемые для синтеза адресов Ethereum.Короче говоря, адреса ETH НЕ ВЫЧИСЛЯЮТСЯ с использованием разновидностей Keccak NIST.Для вычисления адресов ETH используются последние 20 байт хэша Keccak-256. Не следует использовать разновидности Keccak NIST FIPS 202, такие как KeccakCodePackage .
Однако взлом main.c и genKATShortMsg.cpp с помощью KeccakTools даст правильные адреса ETH, подробно описанные в комментарии выше.
Для следующего закрытого ключа ETH: b205a1e03ddf50247d8483435cd91f9c732bad281ad420061ab4310c33166276
. Связанный открытый ключ является результатом использования bx.
% echo b205a1e03ddf50247d8483435cd91f9c732bad281ad420061ab4310c33166276 | bx ec-to-public -u
04**6cb84859e85b1d9a27e060fdede38bb818c93850fb6e42d9c7e4bd879f8b9153fd94ed48e1f63312dce58f4d778ff45a2e5abb08a39c1bc0241139f5e54de7df**
Следующий KeccakTools/Example\ trails
файл конфигурации необходим для выполнения
../bin/KeccakTools
из Example\ trails
каталога.
% cat ShortMsgKAT.txt
\# Algorithm Name: NOT_FIPS202_SHA3_256
\# Principal Submitter: SKAHT
Len = 512
Msg = 6cb84859e85b1d9a27e060fdede38bb818c93850fb6e42d9c7e4bd879f8b9153fd94ed48e1f63312dce58f4d778ff45a2e5abb08a39c1bc0241139f5e54de7df
Файл с именем ShortMsgKAT_keccak-256.txt
создается из выполнения, KeccakTools
который будет содержать:
MD = 787EC5A5313A976F7BDF9EED**AFDEFC1937AE294C3BD55386A8B9775539D81653**
когда задокументированный выше взлом выполняется для сборки KeccakTools .
Отвечая на главный вопрос заголовка о 256-битных закрытых ключах и заголовке:
«Для данного закрытого ключа, сгенерированного MyEtherWallet, я хотел бы видеть, что у меня есть инструменты для независимого получения аналогичных результатов».
Во-первых, важно проверить размер закрытого ключа (независимо от того, сгенерирован ли он случайно или детерминировано), чтобы убедиться, что он действителен с точки зрения его использования в кривой secp256k1 (за пределами длины в битах ключа), прежде чем генерировать открытый ключ и адрес. (хотя многие приложения, такие как приведенное ниже, проверят для вас).
Примечание . Это относится и к Биткойну, а не только к Эфириуму, поскольку они используют одни и те же кривые, несмотря на то, что форматирование адреса отличается из-за разных шагов и используемых алгоритмов хэширования и кодирования (и хотя один и тот же закрытый ключ может использоваться в обоих случаях). , это отдельный разговор).
Хотя сама кривая равна конечному полю p
, равному: ((((((((2**256)-2**32)-2**9)-2**8)-2**7)-2**6)-2**4)-1)
и которое в шестнадцатеричном формате равно: '0xfffffffffffffffffffffffffffffffffffffffffffffffffffffffefffffc2f'
и имеет длину 256 двоичных битов, закрытый ключ не может быть больше, чем порядок, n
который немного меньше, даже если он также 256-битный:'0xfffffffffffffffffffffffffffffffebaaedce6af48a03bbfd25e8cd0364141'
То есть закрытый ключ не может быть больше, чемn
по параметрам кривой secp256k1 .
После выполнения этой проверки, чтобы убедиться, что ключ действителен, следующими шагами будет использование чего-то вроде библиотеки ECDSA вместе с библиотекой eth-keys в Python.
Ниже приведен пример такой программы на Python, которая принимает закрытый ключ или может генерировать ключи случайным образом (см. комментарий в коде после # for private_key_hex=hex(int(bin(secrets.randbits(256)),base=2))
):
import secrets
import math
import sha3
import ecdsa
from ecdsa import SigningKey, SECP256k1
from eth_keys import keys
private_key_hex=hex(int(input('paste a 0x-padded 64 character hex string, total 66 with 0x'),base=16))
scep256k1_curvelimit= int(0xfffffffffffffffffffffffffffffffebaaedce6af48a03bbfd25e8cd0364141) #Curve limit is
if int(private_key_hex,base=16) > scep256k1_curvelimit:
print('private key is out of the range of the curve and invalid, do not use!')
else:
print('private key is within range of curve')
#private_key_hex=hex(int(bin(secrets.randbits(256)),base=2)) Uncomment this to use RANDOM
private_key_hex_nopad=private_key_hex[2:]
private_key=bytearray.fromhex(private_key_hex_nopad)
def address_formatted(to_hash_str):
keccak = sha3.keccak_256()
out = ''
str_hash = to_hash_str.lower().replace('0x', '')
keccak.update(str_hash.encode('ascii'))
create_hash_digit = keccak.hexdigest()
for i, c in enumerate(str_hash):
if int(create_hash_digit[i], 16) >= 8:
out += c.upper()
else:
out += c
return '0x' + out
keccak = sha3.keccak_256()
f=private_key
private_key = ecdsa.SigningKey.from_string(f, curve=ecdsa.SECP256k1)
public_key = private_key.get_verifying_key().to_string()
keccak.update(public_key)
print(public_key)
address = keccak.hexdigest()[24:]
address_full = keccak.hexdigest()
print("Private key:", private_key.to_string().hex())
print("Public key: ", public_key.hex())
print("Ethereum Address, based on last 40 hex of Keccak Hash digest: ", address_formatted(address))
print('Full Hash Digest (address is last 40 characters): ',address_full,)
Примечание . Следующий фрагмент кода из приведенной выше программы не является необходимым, и я просто добавил его в информационных целях, поскольку зависимые библиотеки имеют встроенные проверки, чтобы определить, меньше ли закрытый ключ (секретный показатель) n
:
scep256k1_curvelimit= int(0xfffffffffffffffffffffffffffffffebaaedce6af48a03bbfd25e8cd0364141) #Curve limit is
if int(private_key_hex,base=16) > scep256k1_curvelimit:
print('private key is out of the range of the curve and invalid, do not use!')
else:
print('private key is within range of curve')
Вывод вышеуказанной программы, использующей криптографически безопасный случайно сгенерированный 256-битный ключ, будет выглядеть примерно так (не используйте эти значения в основной сети):
b'\xa2%\xbfV_\xf4\xea\x03\x9b\xcc\xba>&En\x91\x0c\xd7NF\x16\xd6~\xe0\xa1f\xe2m\xa6\xe5\xe5Z\x08\xd0\xfa\x16Y\xb4\xb5G\xbaq9\xcaS\x1fb\x90{\x9c.r\xb8\x07\x12\xf1\xc8\x1e\xceC\xc3?K\x8b'
Private key: c2c72dfbff11dfb4e9d5b0a20c620c58b15bb7552753601f043db91331b0db15
Public key: a225bf565ff4ea039bccba3e26456e910cd74e4616d67ee0a166e26da6e5e55a08d0fa1659b4b547ba7139ca531f62907b9c2e72b80712f1c81ece43c33f4b8b
Ethereum Address, based on last 40 hex of Keccak Hash digest: 0x6eA27154616a29708dce7650b475Dd6b82eBa6a3
Full Hash Digest (address is last 40 characters): f616607efea8e1a5c2f0f8576ea27154616a29708dce7650b475dd6b82eba6a3
Примечание : Keccak также можно получить как часть библиотеки Hashlib или установить из библиотеки pysha3 , в зависимости от установленной версии Python.
скат
% echo fc8fba997174132184998ab82b28e441e80c73236ccaf8b6a1efadc33febecfc | bx ec-to-public -u
:скат
скат
% ./keccak -x -256 cf90dc2b34937fff7cf1eb4b260f1e5610231134b864761e508505938bbef8fc00aeb265797336b74146e018da7b78070f1f1072540a2c3fe83637ca5d605b3c
b992c6ced76bf40cfe875feb 99d0dfbbb6eb831dc0605a82d084e5d930bc6631Грэм Пайл
скат