'Extract and return a UniformDH public key out of `data\'.
Before the public key is touched, the HMAC is verified.  If the HMAC is
invalid or some other error occurs, `False\' is returned.  Otherwise,
the public key is returned.  The extracted data is finally drained from
the given `data\' object.'

def extractPublicKey(self, data, srvState=None):

    assert (self.sharedSecret is not None)
    if (len(data) < ((const.PUBLIC_KEY_LENGTH + const.MARK_LENGTH) + const.HMAC_SHA256_128_LENGTH)):
        return False
    log.debug(("Attempting    to    extract    the    remote    machine's    UniformDH    public    key    out    of    %d    bytes    of    data." % len(data)))
    handshake = data.peek()
    publicKey = handshake[:const.PUBLIC_KEY_LENGTH]
    mark = mycrypto.HMAC_SHA256_128(self.sharedSecret, publicKey)
    index = util.locateMark(mark, handshake)
    if (not index):
        return False
    hmacStart = (index + const.MARK_LENGTH)
    existingHMAC = handshake[hmacStart:(hmacStart + const.HMAC_SHA256_128_LENGTH)]
    authenticated = False
    for epoch in util.expandedEpoch():
        myHMAC = mycrypto.HMAC_SHA256_128(self.sharedSecret, (handshake[0:hmacStart] + epoch))
        if util.isValidHMAC(myHMAC, existingHMAC, self.sharedSecret):
            self.echoEpoch = epoch
            authenticated = True
            break
        log.debug('HMAC    invalid.        Trying    next    epoch    value.')
    if (not authenticated):
        log.warning("Could    not    verify    the    authentication    message's    HMAC.")
        return False
    if ((srvState is not None) and srvState.isReplayed(existingHMAC)):
        log.warning('The    HMAC    was    already    present    in    the    replay    table.')
        return False
    data.drain(((index + const.MARK_LENGTH) + const.HMAC_SHA256_128_LENGTH))
    if (srvState is not None):
        log.debug(('Adding    the    HMAC    authenticating    the    UniformDH    message    to    the    replay    table:    %s.' % existingHMAC.encode('hex')))
        srvState.registerKey(existingHMAC)
    return handshake[:const.PUBLIC_KEY_LENGTH]
