def _ssh_KEX_ECDH_REPLY(self, packet):
        """
        Called to handle a reply to a ECDH exchange message(KEX_ECDH_INIT).

        Like the handler for I{KEXDH_INIT}, this message type has an
        overlapping value.  This method is called from C{ssh_KEX_DH_GEX_GROUP}
        if that method detects a non-group key exchange is in progress.

        Payload::

            string serverHostKey
            string server Elliptic Curve Diffie-Hellman public key
            string signature

        We verify the host key and continue if it passes verificiation.
        Otherwise raise an exception and return.

        @type packet: L{bytes}
        @param packet: The message data.

        @return: A deferred firing when key exchange is complete.
        """
        def _continue_KEX_ECDH_REPLY(ignored, hostKey, pubKey, signature):
            # Save off the host public key.
            theirECHost = hostKey

            # Take the provided public key and transform it into a format
            # for the cryptography module
            theirECPub = ec.EllipticCurvePublicKey.from_encoded_point(
                self.curve, pubKey
            )

            # We need to convert to hex,
            # so we can convert to an int
            # so we can make a multiple precision int.
            sharedSecret = MP(
                           int(
                           binascii.hexlify(
                             self.ecPriv.exchange(ec.ECDH(), theirECPub)), 16))

            h = _kex.getHashProcessor(self.kexAlg)()
            h.update(NS(self.ourVersionString))
            h.update(NS(self.otherVersionString))
            h.update(NS(self.ourKexInitPayload))
            h.update(NS(self.otherKexInitPayload))
            h.update(NS(theirECHost))
            h.update(NS(self.ecPub.public_bytes(
                serialization.Encoding.X962,
                serialization.PublicFormat.UncompressedPoint
            )))
            h.update(NS(pubKey))
            h.update(sharedSecret)

            exchangeHash = h.digest()

            if not keys.Key.fromString(theirECHost).verify(
                                                      signature, exchangeHash):
                self.sendDisconnect(DISCONNECT_KEY_EXCHANGE_FAILED,
                                    b'bad signature')
            else:
                self._keySetup(sharedSecret, exchangeHash)

        # Get the host public key,
        # the raw ECDH public key bytes and the signature
        hostKey, pubKey, signature, packet = getNS(packet, 3)

        # Easier to comment this out for now than to update all of the tests.
        #fingerprint = nativeString(base64.b64encode(
        #        sha256(hostKey).digest()))

        fingerprint = b':'.join(
             [binascii.hexlify(ch) for ch in iterbytes(md5(hostKey).digest())])
        d = self.verifyHostKey(hostKey, fingerprint)
        d.addCallback(_continue_KEX_ECDH_REPLY, hostKey, pubKey, signature)
        d.addErrback(
            lambda unused: self.sendDisconnect(
                DISCONNECT_HOST_KEY_NOT_VERIFIABLE, b'bad host key'))
        return d

        Called to handle a reply to a ECDH exchange message(KEX_ECDH_INIT).

        Like the handler for I{KEXDH_INIT}, this message type has an
        overlapping value.  This method is called from C{ssh_KEX_DH_GEX_GROUP}
        if that method detects a non-group key exchange is in progress.

        Payload::

            string serverHostKey
            string server Elliptic Curve Diffie-Hellman public key
            string signature

        We verify the host key and continue if it passes verificiation.
        Otherwise raise an exception and return.

        @type packet: L{bytes}
        @param packet: The message data.

        @return: A deferred firing when key exchange is complete.
        
stackoverflow/venv/lib/python3.6/site-packages/twisted/conch/ssh/transport.py