URI: 
       tecc_fast.py - electrum - Electrum Bitcoin wallet
  HTML git clone https://git.parazyd.org/electrum
   DIR Log
   DIR Files
   DIR Refs
   DIR Submodules
       ---
       tecc_fast.py (5934B)
       ---
            1 # taken (with minor modifications) from pycoin
            2 # https://github.com/richardkiss/pycoin/blob/01b1787ed902df23f99a55deb00d8cd076a906fe/pycoin/ecdsa/native/secp256k1.py
            3 
            4 import os
            5 import sys
            6 import traceback
            7 import ctypes
            8 from ctypes import (
            9     byref, c_byte, c_int, c_uint, c_char_p, c_size_t, c_void_p, create_string_buffer,
           10     CFUNCTYPE, POINTER, cast
           11 )
           12 
           13 from .logging import get_logger
           14 
           15 
           16 _logger = get_logger(__name__)
           17 
           18 
           19 SECP256K1_FLAGS_TYPE_MASK = ((1 << 8) - 1)
           20 SECP256K1_FLAGS_TYPE_CONTEXT = (1 << 0)
           21 SECP256K1_FLAGS_TYPE_COMPRESSION = (1 << 1)
           22 # /** The higher bits contain the actual data. Do not use directly. */
           23 SECP256K1_FLAGS_BIT_CONTEXT_VERIFY = (1 << 8)
           24 SECP256K1_FLAGS_BIT_CONTEXT_SIGN = (1 << 9)
           25 SECP256K1_FLAGS_BIT_COMPRESSION = (1 << 8)
           26 
           27 # /** Flags to pass to secp256k1_context_create. */
           28 SECP256K1_CONTEXT_VERIFY = (SECP256K1_FLAGS_TYPE_CONTEXT | SECP256K1_FLAGS_BIT_CONTEXT_VERIFY)
           29 SECP256K1_CONTEXT_SIGN = (SECP256K1_FLAGS_TYPE_CONTEXT | SECP256K1_FLAGS_BIT_CONTEXT_SIGN)
           30 SECP256K1_CONTEXT_NONE = (SECP256K1_FLAGS_TYPE_CONTEXT)
           31 
           32 SECP256K1_EC_COMPRESSED = (SECP256K1_FLAGS_TYPE_COMPRESSION | SECP256K1_FLAGS_BIT_COMPRESSION)
           33 SECP256K1_EC_UNCOMPRESSED = (SECP256K1_FLAGS_TYPE_COMPRESSION)
           34 
           35 
           36 class LibModuleMissing(Exception): pass
           37 
           38 
           39 def load_library():
           40     if sys.platform == 'darwin':
           41         library_paths = (os.path.join(os.path.dirname(__file__), 'libsecp256k1.0.dylib'),
           42                          'libsecp256k1.0.dylib')
           43     elif sys.platform in ('windows', 'win32'):
           44         library_paths = (os.path.join(os.path.dirname(__file__), 'libsecp256k1-0.dll'),
           45                          'libsecp256k1-0.dll')
           46     elif 'ANDROID_DATA' in os.environ:
           47         library_paths = ('libsecp256k1.so',)
           48     else:  # desktop Linux and similar
           49         library_paths = (os.path.join(os.path.dirname(__file__), 'libsecp256k1.so.0'),
           50                          'libsecp256k1.so.0')
           51 
           52     exceptions = []
           53     secp256k1 = None
           54     for libpath in library_paths:
           55         try:
           56             secp256k1 = ctypes.cdll.LoadLibrary(libpath)
           57         except BaseException as e:
           58             exceptions.append(e)
           59         else:
           60             break
           61     if not secp256k1:
           62         _logger.error(f'libsecp256k1 library failed to load. exceptions: {repr(exceptions)}')
           63         return None
           64 
           65     try:
           66         secp256k1.secp256k1_context_create.argtypes = [c_uint]
           67         secp256k1.secp256k1_context_create.restype = c_void_p
           68 
           69         secp256k1.secp256k1_context_randomize.argtypes = [c_void_p, c_char_p]
           70         secp256k1.secp256k1_context_randomize.restype = c_int
           71 
           72         secp256k1.secp256k1_ec_pubkey_create.argtypes = [c_void_p, c_void_p, c_char_p]
           73         secp256k1.secp256k1_ec_pubkey_create.restype = c_int
           74 
           75         secp256k1.secp256k1_ecdsa_sign.argtypes = [c_void_p, c_char_p, c_char_p, c_char_p, c_void_p, c_void_p]
           76         secp256k1.secp256k1_ecdsa_sign.restype = c_int
           77 
           78         secp256k1.secp256k1_ecdsa_verify.argtypes = [c_void_p, c_char_p, c_char_p, c_char_p]
           79         secp256k1.secp256k1_ecdsa_verify.restype = c_int
           80 
           81         secp256k1.secp256k1_ec_pubkey_parse.argtypes = [c_void_p, c_char_p, c_char_p, c_size_t]
           82         secp256k1.secp256k1_ec_pubkey_parse.restype = c_int
           83 
           84         secp256k1.secp256k1_ec_pubkey_serialize.argtypes = [c_void_p, c_char_p, c_void_p, c_char_p, c_uint]
           85         secp256k1.secp256k1_ec_pubkey_serialize.restype = c_int
           86 
           87         secp256k1.secp256k1_ecdsa_signature_parse_compact.argtypes = [c_void_p, c_char_p, c_char_p]
           88         secp256k1.secp256k1_ecdsa_signature_parse_compact.restype = c_int
           89 
           90         secp256k1.secp256k1_ecdsa_signature_normalize.argtypes = [c_void_p, c_char_p, c_char_p]
           91         secp256k1.secp256k1_ecdsa_signature_normalize.restype = c_int
           92 
           93         secp256k1.secp256k1_ecdsa_signature_serialize_compact.argtypes = [c_void_p, c_char_p, c_char_p]
           94         secp256k1.secp256k1_ecdsa_signature_serialize_compact.restype = c_int
           95 
           96         secp256k1.secp256k1_ecdsa_signature_parse_der.argtypes = [c_void_p, c_char_p, c_char_p, c_size_t]
           97         secp256k1.secp256k1_ecdsa_signature_parse_der.restype = c_int
           98 
           99         secp256k1.secp256k1_ecdsa_signature_serialize_der.argtypes = [c_void_p, c_char_p, c_void_p, c_char_p]
          100         secp256k1.secp256k1_ecdsa_signature_serialize_der.restype = c_int
          101 
          102         secp256k1.secp256k1_ec_pubkey_tweak_mul.argtypes = [c_void_p, c_char_p, c_char_p]
          103         secp256k1.secp256k1_ec_pubkey_tweak_mul.restype = c_int
          104 
          105         secp256k1.secp256k1_ec_pubkey_combine.argtypes = [c_void_p, c_char_p, c_void_p, c_size_t]
          106         secp256k1.secp256k1_ec_pubkey_combine.restype = c_int
          107 
          108         # --enable-module-recovery
          109         try:
          110             secp256k1.secp256k1_ecdsa_recover.argtypes = [c_void_p, c_char_p, c_char_p, c_char_p]
          111             secp256k1.secp256k1_ecdsa_recover.restype = c_int
          112 
          113             secp256k1.secp256k1_ecdsa_recoverable_signature_parse_compact.argtypes = [c_void_p, c_char_p, c_char_p, c_int]
          114             secp256k1.secp256k1_ecdsa_recoverable_signature_parse_compact.restype = c_int
          115         except (OSError, AttributeError):
          116             raise LibModuleMissing('libsecp256k1 library found but it was built '
          117                                    'without required module (--enable-module-recovery)')
          118 
          119         secp256k1.ctx = secp256k1.secp256k1_context_create(SECP256K1_CONTEXT_SIGN | SECP256K1_CONTEXT_VERIFY)
          120         ret = secp256k1.secp256k1_context_randomize(secp256k1.ctx, os.urandom(32))
          121         if not ret:
          122             _logger.error('secp256k1_context_randomize failed')
          123             return None
          124 
          125         return secp256k1
          126     except (OSError, AttributeError) as e:
          127         _logger.error(f'libsecp256k1 library was found and loaded but there was an error when using it: {repr(e)}')
          128         return None
          129 
          130 
          131 _libsecp256k1 = None
          132 try:
          133     _libsecp256k1 = load_library()
          134 except BaseException as e:
          135     _logger.error(f'failed to load libsecp256k1: {repr(e)}')
          136 
          137 
          138 if _libsecp256k1 is None:
          139     # hard fail:
          140     sys.exit(f"Error: Failed to load libsecp256k1.")