def validate_transaction(self, txn): # validate transactions signature recovered_pubkey = signing.recover_pubkey(txn.header, txn.header_signature) header = TransactionHeader() header.ParseFromString(txn.header) if recovered_pubkey == header.signer_pubkey: return True else: return False
def get_verifying_key(serialized_msg, serialized_sig): """Attempts to recover a public key from a message and a signature. Args: serialized_msg (str): A serialized message. serialized_sig (str): A serialized signature. Returns: str: a public key. """ return signing.recover_pubkey(serialized_msg, serialized_sig)
def test_bulk_keymatch(self): """ Tests key recovery over several keys """ msg = 'foo' for _ in range(0, 20): priv = pbt.random_key() sig = pbt.ecdsa_sign(msg, priv) native_recovered = pbct_nativerecover.recover_pubkey(msg, sig) py_recovered = pbt.ecdsa_recover(msg, sig) self.assertEquals(native_recovered, py_recovered, "Priv Key that failed: {}".format(priv))
def test_pbt_match(self): """ Tests matching results between pybitcointools and native ECDSA key recovery """ # This key has a small public key value which tests padding wifstr = '5JtMb6tmM9vT6QHyM7RR8pjMViqccukgMFNCPvG5xhLVf6CMoGx' priv = pbt.encode_privkey(pbt.decode_privkey(wifstr, 'wif'), 'hex') msg = 'foo' sig = pbt.ecdsa_sign(msg, priv) native_recovered = pbct_nativerecover.recover_pubkey(msg, sig) py_recovered = pbt.ecdsa_recover(msg, sig) self.assertEquals(native_recovered, py_recovered)
def test_compressed_keys(self): """ Tests compressed key """ msg = 'foo' priv = pbt.encode_privkey(pbt.random_key(), 'hex_compressed') sig = pbt.ecdsa_sign(msg, priv) # Force old pybitcointools to behave v, r, s = pbt.decode_sig(sig) if v < 31: v += 4 sig = pbt.encode_sig(v, r, s) pub = pbt.compress(pbt.privtopub(priv)) native_recovered = pbct_nativerecover.recover_pubkey(msg, sig) self.assertEquals(native_recovered, pub, "Priv Key that failed: {}".format(priv))
def validate_block(self, block): # validate block signature valid = True recovered_pubkey = signing.recover_pubkey(block.header, block.header_signature) header = BlockHeader() header.ParseFromString(block.header) if recovered_pubkey != header.signer_pubkey: valid = False # validate all batches in block. These are not all batches in the # batch_ids stored in the block header, only those sent with the block. total = len(block.batches) index = 0 while valid and index < total: valid = self.validate_batch(block.batches[index]) index += 1 return valid
def validate_batch(self, batch): # validate batch signature valid = True recovered_pubkey = signing.recover_pubkey(batch.header, batch.header_signature) header = BatchHeader() header.ParseFromString(batch.header) if recovered_pubkey != header.signer_pubkey: valid = False # validate all transactions in batch total = len(batch.transactions) index = 0 while valid and index < total: txn = batch.transactions[index] valid = self.validate_transaction(txn) if valid: txn_header = TransactionHeader() txn_header.ParseFromString(txn.header) if txn_header.batcher_pubkey != header.signer_pubkey: valid = False index += 1 return valid