Electrum использует начальное число из 12 слов для генерации пары ключей, а затем иерархически генерирует адреса из этой пары ключей.
Я знаю, как генерировать иерархические адреса из пары ключей, но чего я не понимаю, так это того, как Electrum генерирует пару ключей из семени. Я понимаю, что начальное число состоит из слов, поступающих из списка слов длиной 2048 слов, но после этого мне непонятно, как оно начинает генерировать последовательность адресов.
Я хотел бы сделать генерацию HD либо на Java/C++/Python, либо на C#. Если я смогу понять этот процесс, я смогу воспроизвести его самостоятельно и сгенерировать иерархические адреса из семени.
РЕДАКТИРОВАТЬ:
Через день я нахожу эту реализацию Java... Спасибо за ответы!
Кошельки, созданные Electrum 1.x, содержат сид-слова, содержащие 12 слов (24 слова также возможны для сид-кодов, созданных пользователем ). При заданном массиве seed_words такой длины, отсчитываемом от нуля, этот псевдокод вычисляет master_private_key:
i = 0
while i < length(seed_words):
# convert each word into an int in the range [0,1625]
# based on the word's position in the sorted word list
seed_ints[i] = lookup_seed_word(seed_words[i])
i = i + 1
num_words = 1626
num_words2 = num_words * num_words
seed_hex_str = ""
i = 0
while i < length(seed_words):
# (hex8 converts an int into an ASCII string of
# exactly 8 zero-padded lowercase hex digits;
# % is the integer remainder operator
seed_hex_str = seed_hex_str + hex8( seed_ints[i ]
+ num_words * ( (seed_ints[i + 1] - seed_ints[i ]) % num_words )
+ num_words2 * ( (seed_ints[i + 2] - seed_ints[i + 1]) % num_words ))
i = i + 3
unstretched_seed = ascii_string_to_byte_array(seed_hex_str)
seed = byte_array() # an empty byte array
i = 0
while i < 100000:
# sha256 operates on and produces byte arrays
seed = sha256(seed + unstretched_seed)
i = i + 1
master_private_key = byte_array_to_int(seed, order=big_endian)
Если вам интересно, кажется, что причина, по которой вычисление seed_ints выглядит слишком сложным, может заключаться в том, чтобы избежать нарушения патента .
Для сравнения, кошельки, созданные Electrum 2.x, обычно содержат сид-слова, содержащие 13 слов, однако иногда их может быть меньше. (Технически возможно создать начальные числа практически любой длины, которые будут приняты при восстановлении кошелька Electrum 2.x.) Вот псевдокод, который вычисляет расширенный главный закрытый ключ BIP-32:
# Electrum 2.x doesn't separate mnemonic words with spaces in sentences for any CJK
# scripts when calculating the checksum or deriving a binary seed (even though this
# seems inappropriate for some CJK scripts such as Hiragana as used by the ja wordlist)
if language is CJK:
space = ""
else:
space = " "
seed_phrase = ""
i = 0
do:
word = seed_words[i]
normalize_unicode(word, normalization=nfkd)
remove_unicode_combining_marks(word) # e.g. accent marks
seed_phrase = seed_phrase + word
i = i + 1
if i ≥ length(seed_words):
exit-loop
seed_phrase = seed_phrase + space
seed_utf8 = unicode_to_byte_array(seed_phrase, format=utf8)
if hmac_sha512(key="Seed version", message=seed_utf8)[0] ≠ 1:
fail("invalid checksum")
stretched_seed = pbkdf2_hmac_sha512(password=seed_utf8, salt="electrum", iterations=2048, output_length=64)
seed_bytes = hmac_sha512(key="Bitcoin seed", message=stretched_seed)
private_key = byte_array_to_int(seed_bytes[0..31], order=big_endian)
chain_code_bytes = seed_bytes[32..63]
master_private_key = create_bip32_extended_private_key(private_key, chain_code_bytes)
BIP-39 , альтернативный метод получения, похож на Electrum 2.x, но не идентичен.
мистер Джонс
Кристофер Герни
Кристофер Герни
Томас В