Esempio n. 1
0
 def verify_tx_signature(self, signature, transaction, verification_key,
                         utxo):
     '''Verify the signature for a specific utxo ("prevout_hash:n") given a
     transaction and verification key.'''
     txin = list(
         filter(
             lambda x:
             (verification_key in x['pubkeys'] and utxo == "{}:{}".format(
                 x['tx_hash'], x['tx_pos'])), transaction.inputs()))
     if txin:
         tx_num = transaction.inputs().index(txin[0])
         pre_hash = Hash(bfh(transaction.serialize_preimage(tx_num)))
         order = generator_secp256k1.order()
         r, s = ecdsa.util.sigdecode_der(bfh(signature.decode()[:-2]),
                                         order)
         sig_string = ecdsa.util.sigencode_string(r, s, order)
         compressed = len(verification_key) <= 66
         for recid in range(0, 4):
             try:
                 pubk = MyVerifyingKey.from_signature(sig_string,
                                                      recid,
                                                      pre_hash,
                                                      curve=SECP256k1)
                 pubkey = bh2u(point_to_ser(pubk.pubkey.point, compressed))
                 if verification_key == pubkey:
                     return True
             except:
                 continue
     else:
         return False
 def verify_tx_signature(self, signature, transaction, verification_key):
     "It verifies the transaction signatures"
     txin = list(
         filter(lambda x: verification_key in x['pubkeys'],
                transaction.inputs()))
     if txin:
         tx_num = transaction.inputs().index(txin[0])
         pre_hash = Hash(bfh(transaction.serialize_preimage(tx_num)))
         order = generator_secp256k1.order()
         r, s = ecdsa.util.sigdecode_der(bfh(signature.decode()[:-2]),
                                         order)
         sig_string = ecdsa.util.sigencode_string(r, s, order)
         compressed = len(verification_key) <= 66
         for recid in range(0, 4):
             try:
                 pubk = MyVerifyingKey.from_signature(sig_string,
                                                      recid,
                                                      pre_hash,
                                                      curve=SECP256k1)
                 pubkey = bh2u(point_to_ser(pubk.pubkey.point, compressed))
                 if verification_key == pubkey:
                     return True
             except:
                 continue
     else:
         return False
Esempio n. 3
0
 def verify_tx_signature(signature, transaction, verification_key, utxo):
     '''Verify the signature for a specific utxo ("prevout_hash:n") given a
     transaction and verification key. Ensures that the signature is valid
     AND canonically encoded, so it will be accepted by network.
     '''
     tx_num = None
     for n, x in enumerate(transaction.inputs()):
         if (verification_key in x['pubkeys']
                 and utxo == "{}:{}".format(x['tx_hash'], x['tx_pos'])):
             tx_num = n
             break
     else:
         # verification_key / utxo combo not found in tx inputs, bail
         return False
     # calculate sighash digest (implicitly this is for sighash 0x41)
     pre_hash = Hash(bfh(transaction.serialize_preimage(tx_num)))
     order = generator_secp256k1.order()
     try:
         sigbytes = bfh(signature.decode())
     except ValueError:
         # not properly hex encoded or UnicodeDecodeError (garbage data)
         return False
     if not sigbytes or sigbytes[-1] != 0x41:
         return False
     DERsig = sigbytes[:
                       -1]  # lop off the sighash byte for the DER check below
     try:
         # ensure DER encoding is canonical, and extract r,s if OK
         r, s = CoinUtils.IsValidDERSignatureEncoding_With_Extract(DERsig)
     except AssertionError:
         return False
     if (s << 1) > order:
         # high S values are rejected by BCH network
         return False
     try:
         pubkey_point = ser_to_point(bfh(verification_key))
     except:
         # ser_to_point will fail if pubkey is off-curve, infinity, or garbage.
         return False
     vk = MyVerifyingKey.from_public_point(pubkey_point, curve=SECP256k1)
     try:
         return vk.verify_digest(DERsig,
                                 pre_hash,
                                 sigdecode=ecdsa.util.sigdecode_der)
     except:
         # verify_digest returns True on success, otherwise raises
         return False
Esempio n. 4
0
 def __init__(self, window, wallet, network_settings,
              period = 10.0, logger = None, password=None, timeout=60.0,
              typ=Messages.DEFAULT  # NB: Only DEFAULT is currently supported
              ):
     super().__init__()
     cls = type(self)
     self.daemon = True
     self.timeout = timeout
     self.version = cls.PROTOCOL_VERSION + (1 if networks.net.TESTNET else 0)
     self.type = typ
     assert self.type == Messages.DEFAULT, "BackgroundShufflingThread currently only supports DEFAULT shuffles"
     cls.latest_shuffle_settings = cls.ShuffleSettings(self.type, Messages.TYPE_NAME_DICT[self.type], self.version, 0, 0, self.FEE)
     # set UPPER_BOUND and LOWER_BOUND from config keys here. Note all instances will see these changes immediately.
     cls.update_lower_and_upper_bound_from_config()
     self.period = period
     self.logger = logger
     self.wallet = wallet
     self.window = window
     self.host = network_settings.get("host", None)
     self.info_port = network_settings.get("info", None)
     self.port = 1337  # default value -- will get set to real value from server's stat port in run() method
     self.poolSize = 3  # default value -- will get set to real value from server's stat port in run() method
     self.banScore = 0  # comes from stats port -- our own personal ban score
     self.banned = False  # comes from stats port. True if our IP is banned (default ban duration: 30 mins)
     self.ssl = network_settings.get("ssl", None)
     self.lock = threading.RLock()
     self.password = password
     self.threads = {scale:None for scale in self.scales}
     self.shared_chan = Channel(switch_timeout=None)  # threads write a 3-tuple here: (killme_flg, thr, msg)
     self.stop_flg = threading.Event()
     self.last_idle_check = 0.0  # timestamp in seconds unix time
     self.done_utxos = dict()
     self._paused = False
     self._coins_busy_shuffling = set()  # 'prevout_hash:n' (name) set of all coins that are currently being shuffled by a ProtocolThread. Both wallet locks should be held to read/write this.
     self._last_server_check = 0.0  # timestamp in seconds unix time
     self._dummy_address = Address.from_pubkey(EC_KEY(number_to_string(1337, generator_secp256k1.order())).get_public_key())  # dummy address
     # below 4 vars are related to the "delayed unreserve address" mechanism as part of the bug #70 & #97 workaround and the complexity created by it..
     self._delayed_unreserve_addresses = dict()  # dict of Address -> time.time() timestamp when its shuffle ended
     self._last_delayed_unreserve_check = 0.0  # timestamp in seconds unix time
     self._delayed_unreserve_check_interval = 60.0  # check these addresses every 60 seconds.
     self._delayed_unreserve_timeout = 600.0  # how long before the delayed-unreserve addresses expire; 10 minutes