Browse Source

ecc: abstract away some usage of python-ecdsa: randrange

hard-fail-on-bad-server-string
SomberNight 5 years ago
parent
commit
004acb906d
No known key found for this signature in database GPG Key ID: B33B5F232C6271E9
  1. 9
      electrum/daemon.py
  2. 8
      electrum/ecc.py
  3. 6
      electrum/mnemonic.py
  4. 4
      electrum/tests/test_bitcoin.py
  5. 7
      electrum/util.py

9
electrum/daemon.py

@ -30,7 +30,7 @@ import traceback
import sys import sys
import threading import threading
from typing import Dict, Optional, Tuple, Iterable from typing import Dict, Optional, Tuple, Iterable
from base64 import b64decode from base64 import b64decode, b64encode
from collections import defaultdict from collections import defaultdict
import aiohttp import aiohttp
@ -44,7 +44,7 @@ from aiorpcx import TaskGroup
from .network import Network from .network import Network
from .util import (json_decode, to_bytes, to_string, profiler, standardize_path, constant_time_compare) from .util import (json_decode, to_bytes, to_string, profiler, standardize_path, constant_time_compare)
from .util import PR_PAID, PR_EXPIRED, get_request_status from .util import PR_PAID, PR_EXPIRED, get_request_status
from .util import log_exceptions, ignore_exceptions from .util import log_exceptions, ignore_exceptions, randrange
from .wallet import Wallet, Abstract_Wallet from .wallet import Wallet, Abstract_Wallet
from .storage import WalletStorage from .storage import WalletStorage
from .wallet_db import WalletDB from .wallet_db import WalletDB
@ -124,11 +124,10 @@ def get_rpc_credentials(config: SimpleConfig) -> Tuple[str, str]:
rpc_password = config.get('rpcpassword', None) rpc_password = config.get('rpcpassword', None)
if rpc_user is None or rpc_password is None: if rpc_user is None or rpc_password is None:
rpc_user = 'user' rpc_user = 'user'
import ecdsa, base64
bits = 128 bits = 128
nbytes = bits // 8 + (bits % 8 > 0) nbytes = bits // 8 + (bits % 8 > 0)
pw_int = ecdsa.util.randrange(pow(2, bits)) pw_int = randrange(pow(2, bits))
pw_b64 = base64.b64encode( pw_b64 = b64encode(
pw_int.to_bytes(nbytes, 'big'), b'-_') pw_int.to_bytes(nbytes, 'big'), b'-_')
rpc_password = to_string(pw_b64, 'ascii') rpc_password = to_string(pw_b64, 'ascii')
config.set_key('rpcuser', rpc_user) config.set_key('rpcuser', rpc_user)

8
electrum/ecc.py

@ -35,7 +35,7 @@ from ecdsa.curves import SECP256k1
from ecdsa.ellipticcurve import Point from ecdsa.ellipticcurve import Point
from ecdsa.util import string_to_number, number_to_string from ecdsa.util import string_to_number, number_to_string
from .util import bfh, bh2u, assert_bytes, to_bytes, InvalidPassword, profiler from .util import bfh, bh2u, assert_bytes, to_bytes, InvalidPassword, profiler, randrange
from .crypto import (sha256d, aes_encrypt_with_iv, aes_decrypt_with_iv, hmac_oneshot) from .crypto import (sha256d, aes_encrypt_with_iv, aes_decrypt_with_iv, hmac_oneshot)
from .ecc_fast import do_monkey_patching_of_python_ecdsa_internals_with_libsecp256k1 from .ecc_fast import do_monkey_patching_of_python_ecdsa_internals_with_libsecp256k1
from . import msqr from . import msqr
@ -145,7 +145,7 @@ class _MyVerifyingKey(ecdsa.VerifyingKey):
G = curve.generator G = curve.generator
order = G.order() order = G.order()
# extract r,s from signature # extract r,s from signature
r, s = util.sigdecode_string(sig, order) r, s = get_r_and_s_from_sig_string(sig, order)
# 1.1 # 1.1
x = r + (recid//2) * order x = r + (recid//2) * order
# 1.3 # 1.3
@ -299,7 +299,7 @@ class ECPubkey(object):
raise Exception('Wrong encoding') raise Exception('Wrong encoding')
ecdsa_point = self._pubkey.point ecdsa_point = self._pubkey.point
verifying_key = _MyVerifyingKey.from_public_point(ecdsa_point, curve=SECP256k1) verifying_key = _MyVerifyingKey.from_public_point(ecdsa_point, curve=SECP256k1)
verifying_key.verify_digest(sig_string, msg_hash, sigdecode=ecdsa.util.sigdecode_string) verifying_key.verify_digest(sig_string, msg_hash, sigdecode=get_r_and_s_from_sig_string)
def encrypt_message(self, message: bytes, magic: bytes = b'BIE1') -> bytes: def encrypt_message(self, message: bytes, magic: bytes = b'BIE1') -> bytes:
""" """
@ -416,7 +416,7 @@ class ECPrivkey(ECPubkey):
@classmethod @classmethod
def generate_random_key(cls): def generate_random_key(cls):
randint = ecdsa.util.randrange(CURVE_ORDER) randint = randrange(CURVE_ORDER)
ephemeral_exponent = number_to_string(randint, CURVE_ORDER) ephemeral_exponent = number_to_string(randint, CURVE_ORDER)
return ECPrivkey(ephemeral_exponent) return ECPrivkey(ephemeral_exponent)

6
electrum/mnemonic.py

@ -28,9 +28,7 @@ import hashlib
import unicodedata import unicodedata
import string import string
import ecdsa from .util import resource_path, bfh, bh2u, randrange
from .util import resource_path, bfh, bh2u
from .crypto import hmac_oneshot from .crypto import hmac_oneshot
from . import version from . import version
from .logging import Logger from .logging import Logger
@ -180,7 +178,7 @@ class Mnemonic(Logger):
entropy = 1 entropy = 1
while entropy < pow(2, n - bpw): while entropy < pow(2, n - bpw):
# try again if seed would not contain enough words # try again if seed would not contain enough words
entropy = ecdsa.util.randrange(pow(2, n)) entropy = randrange(pow(2, n))
nonce = 0 nonce = 0
while True: while True:
nonce += 1 nonce += 1

4
electrum/tests/test_bitcoin.py

@ -16,7 +16,7 @@ from electrum.bip32 import (BIP32Node, convert_bip32_intpath_to_strpath,
from electrum.crypto import sha256d, SUPPORTED_PW_HASH_VERSIONS from electrum.crypto import sha256d, SUPPORTED_PW_HASH_VERSIONS
from electrum import ecc, crypto, constants from electrum import ecc, crypto, constants
from electrum.ecc import number_to_string, string_to_number from electrum.ecc import number_to_string, string_to_number
from electrum.util import bfh, bh2u, InvalidPassword from electrum.util import bfh, bh2u, InvalidPassword, randrange
from electrum.storage import WalletStorage from electrum.storage import WalletStorage
from electrum.keystore import xtype_from_derivation from electrum.keystore import xtype_from_derivation
@ -103,7 +103,7 @@ class Test_bitcoin(ElectrumTestCase):
def _do_test_crypto(self, message): def _do_test_crypto(self, message):
G = ecc.generator() G = ecc.generator()
_r = G.order() _r = G.order()
pvk = ecdsa.util.randrange(_r) pvk = randrange(_r)
Pub = pvk*G Pub = pvk*G
pubkey_c = Pub.get_public_key_bytes(True) pubkey_c = Pub.get_public_key_bytes(True)

7
electrum/util.py

@ -47,6 +47,7 @@ from aiohttp_socks import SocksConnector, SocksVer
from aiorpcx import TaskGroup from aiorpcx import TaskGroup
import certifi import certifi
import dns.resolver import dns.resolver
import ecdsa
from .i18n import _ from .i18n import _
from .logging import get_logger, Logger from .logging import get_logger, Logger
@ -1266,3 +1267,9 @@ def resolve_dns_srv(host: str):
'port': srv.port, 'port': srv.port,
} }
return [dict_from_srv_record(srv) for srv in srv_records] return [dict_from_srv_record(srv) for srv in srv_records]
def randrange(bound: int) -> int:
"""Return a random integer k such that 1 <= k < bound, uniformly
distributed across that range."""
return ecdsa.util.randrange(bound)

Loading…
Cancel
Save