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())
Esempio n. 2
0
class Credentials:
    def __init__(self, private_key):
        if private_key.startswith("0x"):
            private_key = private_key[2:]

        self.private_key = PrivateKey(bytes(bytearray.fromhex(private_key)))

    @property
    def address(self):
        keccak_hash = keccak.new(digest_bits=256)
        keccak_hash.update(
            self.private_key.public_key.format(compressed=False, )[1:])
        return to_checksum_address(keccak_hash.digest()[-20:])

    def sign(self, message):
        msg_hash = bytes(bytearray.fromhex(remove_0x_prefix(message)))

        signature_bytes = self.private_key.sign_recoverable(msg_hash,
                                                            hasher=None)

        assert len(signature_bytes) == 65

        r = "0x" + format(big_endian_to_int(signature_bytes[0:32]), "x")
        s = "0x" + format(big_endian_to_int(signature_bytes[32:64]), "x")
        v = hex(ord(signature_bytes[64:65]) + 27)

        return {"r": r, "s": s, "v": v}
Esempio n. 3
0
    def check_and_fill_order(self, order):
        if not order or not order.fromToken or not order.toToken or not order.tx:
            return "error"

        if not self.order_exists(order):
            return "unknown"
        
        if not self.order_ready(order):
            return None

        gas_price = self.w3.eth.generateGasPrice()
        logger.debug("Loaded raw gas price {}".format(gas_price))
        gas_price = int(gas_price * float(self.gas_multiplier))

        nonce = self.pull_nonce()

        logger.debug("Using nonce {}, gasprice {}".format(nonce, gas_price))

        secret_pk = PrivateKey(order.secret)
        keccak_hash = keccak.new(digest_bits=256)
        keccak_hash.update(bytearray.fromhex(self.account.address.replace('0x', '')))
        witnesses = secret_pk.sign_recoverable(bytes(bytearray.fromhex(keccak_hash.hexdigest())), hasher=None)

        logger.debug("Signed order {} witnesses {}".format(order.tx, witnesses.hex()))

        calc_witness = Account.privateKeyToAccount(order.secret.hex().replace('0x', '')).address
        if calc_witness != order.witness:
            logger.warn("Witness missmatch order {} witness {} order witness {}".format(order.tx, calc_witness, order.witness))
            return "error"

        logger.debug("Sending tx for order {}".format(order.tx))
        transaction = self.uniswap_ex.functions.executeOrder(
            order.fromToken,
            order.toToken,
            order.minReturn,
            order.fee,
            order.owner,
            witnesses
        ).buildTransaction({
            'gasPrice': gas_price,
            'nonce': nonce,
            'from': self.account.address
        })

        if order.fromToken.lower() not in self.whitelisted_tokens and order.toToken.lower() not in self.whitelisted_tokens and transaction['gas'] * gas_price > order.fee:
            logger.debug("Order {} fee is not enought, cost {} vs {} -> {} * {}".format(order.tx, order.fee, transaction['gas'] * gas_price, transaction['gas'], gas_price))
            return None

        signed_txn = self.w3.eth.account.signTransaction(transaction, private_key=self.account.privateKey)
        logger.debug("Signed tx for order {}".format(order.tx))
        tx = Web3.toHex(self.w3.eth.sendRawTransaction(signed_txn.rawTransaction))
        logger.info("Relayed order {} tx {}".format(order.tx, tx))
        return tx
Esempio n. 4
0
    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()
Esempio n. 5
0
    def signCompact(self, k, message):
        message_hash = hashlib.sha256(bytes(message, 'utf-8')).digest()

        privkey = PrivateKey(k)
        return privkey.sign_recoverable(message_hash, hasher=None)[:64]