def verifyTxSig(self, tx_bytes, sig, K, prevout_n, prevout_script, prevout_value): tx = self.loadTx(tx_bytes) sig_hash = SegwitV0SignatureHash(prevout_script, tx, prevout_n, SIGHASH_ALL, prevout_value) pubkey = PublicKey(K) return pubkey.verify(sig[:-1], sig_hash, hasher=None) # Pop the hashtype byte
def test_signature_recoverable(self): private_key = PrivateKey(PRIVATE_KEY_BYTES) assert (private_key.public_key.format() == PublicKey( recover( MESSAGE, deserialize_recoverable( private_key.sign_recoverable(MESSAGE)))).format())
def verifyMessage(self, address, message, signature, message_magic=None) -> bool: if message_magic is None: message_magic = chainparams[self.coin_type()]['message_magic'] message_bytes = SerialiseNumCompact(len(message_magic)) + bytes( message_magic, 'utf-8') + SerialiseNumCompact( len(message)) + bytes(message, 'utf-8') message_hash = hashlib.sha256( hashlib.sha256(message_bytes).digest()).digest() signature_bytes = base64.b64decode(signature) rec_id = (signature_bytes[0] - 27) & 3 signature_bytes = signature_bytes[1:] + bytes((rec_id, )) try: pubkey = PublicKey.from_signature_and_message(signature_bytes, message_hash, hasher=None) except Exception as e: self._log.info('verifyMessage failed: ' + str(e)) return False address_hash = self.decodeAddress(address) pubkey_hash = hash160(pubkey.format()) return True if address_hash == pubkey_hash else False
def send_handshake(self, peer): self._sc.log.debug('send_handshake %s', peer._address) peer._mx.acquire() try: # TODO: Drain peer._recv_messages if not peer._recv_messages.empty(): self._sc.log.warning( 'send_handshake %s - Receive queue dumped.', peer._address) while not peer._recv_messages.empty(): peer._recv_messages.get(False) msg = MsgHandshake() msg._timestamp = int(time.time()) key_r = rfc6979_hmac_sha256_generate(self._csprng, 32) k = PrivateKey(key_r) msg._ephem_pk = PublicKey.from_secret(key_r).format() self.check_handshake_ephem_key(peer, msg._timestamp, msg._ephem_pk) ss = k.ecdh(peer._pubkey) hashed = hashlib.sha512( ss + struct.pack('>Q', msg._timestamp)).digest() peer._ke = hashed[:32] peer._km = hashed[32:] nonce = peer._km[24:] payload = self._sc._version nk = PrivateKey(self._network_key) sig = nk.sign_recoverable(peer._km) payload += sig aad = msg.encode_aad() aad += nonce cipher = ChaCha20_Poly1305.new(key=peer._ke, nonce=nonce) cipher.update(aad) msg._ct, msg._mac = cipher.encrypt_and_digest(payload) peer._sent_nonce = hashlib.sha256(nonce + msg._mac).digest() peer._recv_nonce = hashlib.sha256(peer._km).digest() # Init nonce peer._last_handshake_at = msg._timestamp peer._ready = False # Wait for peer to complete handshake self.send_msg(peer, msg) finally: peer._mx.release()
def __init__(self, p2p_host, p2p_port, network_key, swap_client): self._p2p_host = p2p_host self._p2p_port = p2p_port self._network_key = network_key self._network_pubkey = PublicKey.from_secret(network_key).format() self._sc = swap_client self._peers = [] self._max_connections = 10 self._running = False self._network_thread = None self._msg_thread = None self._mx = threading.Lock() self._socket = None self._read_sockets = [] self._write_sockets = [] self._error_sockets = [] # Check for error events self._seen_ephem_keys = OrderedDict()
def getPubkey(self, privkey): return PublicKey.from_secret(privkey).format()
def sumPubkeys(self, Ka, Kb): return PublicKey.combine_keys([PublicKey(Ka), PublicKey(Kb)]).format()
def test_verify(self): public_key = PublicKey(PUBLIC_KEY_COMPRESSED) assert public_key.verify(SIGNATURE, MESSAGE)
def test_format(self): assert PublicKey(PUBLIC_KEY_UNCOMPRESSED).format( compressed=True) == PUBLIC_KEY_COMPRESSED assert PublicKey(PUBLIC_KEY_COMPRESSED).format( compressed=False) == PUBLIC_KEY_UNCOMPRESSED
def test_from_signature_and_message(self): assert (PublicKey.from_secret(PRIVATE_KEY_BYTES).format() == PublicKey.from_signature_and_message(RECOVERABLE_SIGNATURE, MESSAGE).format())
def test_from_point(self): assert PublicKey.from_point( PUBLIC_KEY_X, PUBLIC_KEY_Y).format() == PUBLIC_KEY_COMPRESSED
def test_from_secret(self): assert PublicKey.from_secret( PRIVATE_KEY_BYTES).format() == PUBLIC_KEY_COMPRESSED
PRIVATE_KEY_BYTES, PRIVATE_KEY_DER, PRIVATE_KEY_HEX, PRIVATE_KEY_NUM, PRIVATE_KEY_PEM, PUBLIC_KEY_COMPRESSED, PUBLIC_KEY_UNCOMPRESSED, PUBLIC_KEY_X, PUBLIC_KEY_Y, MESSAGE, SIGNATURE, RECOVERABLE_SIGNATURE, ) G = PublicKey(b'\x04y\xbef~\xf9\xdc\xbb\xacU\xa0b\x95\xce\x87\x0b\x07\x02\x9b' b'\xfc\xdb-\xce(\xd9Y\xf2\x81[\x16\xf8\x17\x98H:\xdaw&\xa3\xc4e' b']\xa4\xfb\xfc\x0e\x11\x08\xa8\xfd\x17\xb4H\xa6\x85T\x19\x9cG' b'\xd0\x8f\xfb\x10\xd4\xb8') n = 0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEBAAEDCE6AF48A03BBFD25E8CD0364141 class TestPrivateKey: def test_public_key(self): assert PrivateKey( PRIVATE_KEY_BYTES).public_key.format() == PUBLIC_KEY_COMPRESSED def test_signature_correct(self): private_key = PrivateKey() public_key = private_key.public_key message = urandom(200) signature = private_key.sign(message)
def process_handshake(self, peer, msg_mv): self._sc.log.debug('process_handshake %s', peer._address) # TODO: Drain peer._recv_messages if not peer._recv_messages.empty(): self._sc.log.warning( 'process_handshake %s - Receive queue dumped.', peer._address) while not peer._recv_messages.empty(): peer._recv_messages.get(False) msg = MsgHandshake() msg.decode(msg_mv) try: now = int(time.time()) if now - peer._last_handshake_at < 30: raise ValueError('Too many handshakes from peer %s', peer._address) if abs(msg._timestamp - now) > TIMESTAMP_LEEWAY: raise ValueError('Bad handshake timestamp from peer %s', peer._address) self.check_handshake_ephem_key(peer, msg._timestamp, msg._ephem_pk, direction=2) nk = PrivateKey(self._network_key) ss = nk.ecdh(msg._ephem_pk) hashed = hashlib.sha512( ss + struct.pack('>Q', msg._timestamp)).digest() peer._ke = hashed[:32] peer._km = hashed[32:] nonce = peer._km[24:] aad = msg.encode_aad() aad += nonce cipher = ChaCha20_Poly1305.new(key=peer._ke, nonce=nonce) cipher.update(aad) plaintext = cipher.decrypt_and_verify( msg._ct, msg._mac) # Will raise error if mac doesn't match peer._version = plaintext[:6] sig = plaintext[6:] pk_peer = PublicKey.from_signature_and_message(sig, peer._km) # TODO: Should pk_peer be linked to public data? peer._pubkey = pk_peer.format() peer._recv_nonce = hashlib.sha256(nonce + msg._mac).digest() peer._sent_nonce = hashlib.sha256(peer._km).digest() # Init nonce peer._last_handshake_at = msg._timestamp peer._ready = True # Schedule a ping to complete the handshake, TODO: Send here? peer._last_ping_at = 0 except Exception as e: # TODO: misbehaving self._sc.log.debug('[rm] process_handshake %s', str(e))
def verifySig(self, pubkey, signed_hash, sig): pubkey = PublicKey(pubkey) return pubkey.verify(sig, signed_hash, hasher=None)
def verifyCompact(self, K, message, sig): message_hash = hashlib.sha256(bytes(message, 'utf-8')).digest() pubkey = PublicKey(K) rv = pubkey.verify_compact(sig, message_hash, hasher=None) assert (rv is True)
def test_point(self): assert PublicKey(PUBLIC_KEY_COMPRESSED).point() == (PUBLIC_KEY_X, PUBLIC_KEY_Y)