'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 _ssh_KEX_ECDH_REPLY(self, packet):

    def _continue_KEX_ECDH_REPLY(ignored, hostKey, pubKey, signature):
        theirECHost = hostKey
        theirECPub = ec.EllipticCurvePublicNumbers.from_encoded_point(self.curve, pubKey).public_key(default_backend())
        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_numbers().encode_point()))
        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, 'bad    signature')
        else:
            self._keySetup(sharedSecret, exchangeHash)
    (hostKey, pubKey, signature, packet) = getNS(packet, 3)
    fingerprint = ':'.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, 'bad    host    key')))
    return d
