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
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(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
def get_transaction_signature(self, tx, sk, vk): txin = list(filter(lambda x: vk in x['pubkeys'], tx.inputs())) if txin: tx_num = tx.inputs().index(txin[0]) pre_hash = Hash(bfh(tx.serialize_preimage(tx_num))) private_key = MySigningKey.from_secret_exponent(sk.secret, curve = SECP256k1) public_key = private_key.get_verifying_key() sig = private_key.sign_digest_deterministic(pre_hash, hashfunc=hashlib.sha256, sigencode = ecdsa.util.sigencode_der) assert public_key.verify_digest(sig, pre_hash, sigdecode = ecdsa.util.sigdecode_der) result = bh2u(sig) + int_to_hex(tx.nHashType() & 255, 1) return result.encode('utf-8') return b''
def get_transaction_signature(transaction, inputs, secret_keys): "get transaction signature" signatures = {} for txin in transaction.inputs(): pubkey = txin['pubkeys'][0] if pubkey in inputs: tx_num = transaction.inputs().index(txin) pre_hash = Hash(bfh(transaction.serialize_preimage(tx_num))) private_key = MySigningKey.from_secret_exponent(secret_keys[pubkey].secret, curve=SECP256k1) public_key = private_key.get_verifying_key() sig = private_key.sign_digest_deterministic(pre_hash, hashfunc=hashlib.sha256, sigencode=ecdsa.util.sigencode_der) assert public_key.verify_digest(sig, pre_hash, sigdecode=ecdsa.util.sigdecode_der) signatures[txin['tx_hash'] + ":" + str(txin['tx_pos'])] = (bh2u(sig) + int_to_hex(transaction.nHashType() & 255, 1)).encode('utf-8') return signatures
def show_qr(self): from electroncash.bitcoin import base_encode, bfh text = bfh(str(self.tx)) text = base_encode(text, base=43) self.app.qr_dialog(_("Raw Transaction"), text)