Код Python для генерации собственного ключа ECDSA

Будет ли этот код Python генерировать действительный закрытый ключ ECDSA?

import random

def r(a, b):
    sys_ran = random.SystemRandom()
    return sys_ran.randint(a, b)

def create_private_key():
    hex_chars = '0123456789ABCDEF'
    ran_hex = '';

    for i in range(64):
        ran_hex += hex_chars[r(0, 15)]

    max_hex = 'FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEBAAEDCE6AF48A03BBFD25E8CD0364141'

    if int(ran_hex, 16) <= int(max_hex, 16):
        return ran_hex
    else:
        return create_private_key()

private_key = create_private_key()
print('Private key: ' + private_key)

Насколько я могу судить по Биткойн-вики , закрытый ключ ECDSA - любой символ 64 шестнадцатеричное (или соответствующее десятичное) число между 0x1 и 0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFBABAEDED6AF48A03BBFD25E8CD0364141. Он не упоминает ничего о каких-либо специальных алгоритмах, необходимых для того, чтобы закрытый ключ был действительным.

3 голоса | спросил zombio 22 +04002013-10-22T08:27:21+04:00312013bEurope/MoscowTue, 22 Oct 2013 08:27:21 +0400 2013, 08:27:21

3 ответа


4

Да, он будет генерировать случайный закрытый ключ ECDSA в шестнадцатеричной форме ASCII. Вам не нужно специально проверять, является ли ключ больше максимального - почти каждая реализация, которая будет принимать ключ ECDSA в шестнадцатеричном ASCII, знает, как обращаться с ключом выше максимально безопасного. (Вычитая максимальное значение из ключа, а затем используя это.)

ответил David Schwartz 23 +04002013-10-23T00:33:03+04:00312013bEurope/MoscowWed, 23 Oct 2013 00:33:03 +0400 2013, 00:33:03
2

Это не совсем отзывчиво на ваш вопрос, но в ответ на ответ Дэвида Шварца (который, в общем, «да»), я не думаю, что вам нужно воссоздать экземпляр SystemRandom для каждого генерируемого шестнадцатеричного символа. Из https://docs.python.org/2/library/random. HTML # random.SystemRandom :

  

[SystemRandom] использует функцию os.urandom () для генерации случайных чисел из источников, предоставляемых операционной системой. Не доступен для всех систем. Не полагается на состояние программного обеспечения, и последовательности не воспроизводятся. Соответственно, методы seed () и jumpahead () не действуют и игнорируются. Методы getstate () и setstate () поднимают NotImplementedError, если вызваны.

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

from random import SystemRandom
from binascii import hexlify
from struct import Struct

SYS_RAN = SystemRandom()
PACKER = Struct('>QQQQ')
MIN_VAL = 0x1L
MAX_VAL = 0xfffffffffffffffffffffffffffffffebaaedce6af48a03bbfd25e8cd0364141

def mkprivkey():
    key = SYS_RAN.randint(MIN_VAL, MAX_VAL)
    key0 = key >> 192
    key1 = (key >> 128) & 0xffffffffffffffff
    key2 = (key >> 64) & 0xffffffffffffffff
    key3 = key & 0xffffffffffffffff

    return hexlify(PACKER.pack(key0, key1, key2, key3))

В моем тестировании приведенное выше примерно на порядок быстрее, даже после нормализации вашего создание экземпляров SystemRandom и удаление теста, чтобы узнать, превысило ли вы максимальное значение (по предложению Дэвида Шварца):

% time python ./test_ecdsaprivkey.py
mkprivkey:          0.016 ms avg
create_private_key: 0.168 ms avg
python ./test_ecdsaprivkey.py  9.99s user 11.00s system 86% cpu 24.388 total

Конечно, это, вероятно, не имеет значения, если вы не создаете десятки тысяч ключей.

ответил posita 25 Maypm14 2014, 20:33:42
-2

import os import binascii private_key = binascii.hexlify(os.urandom(32)).decode() print("private key = " + private_key)

ответил satoshighost 16 Jam1000000amTue, 16 Jan 2018 09:46:35 +030018 2018, 09:46:35

Похожие вопросы

Популярные теги

security × 330linux × 316macos × 2827 × 268performance × 244command-line × 241sql-server × 235joomla-3.x × 222java × 189c++ × 186windows × 180cisco × 168bash × 158c# × 142gmail × 139arduino-uno × 139javascript × 134ssh × 133seo × 132mysql × 132