public function authenticate() {
        $currentStage = $this->_multiFactorStages['current'];
        
        //set stage as inactive
        if ($currentStage == 1) {
            $this->_multiFactorStages[1]['statuss'] = parent::authenticate();
            
            //stage one sucessfull, bootstrap stage 2
            if ($this->_multiFactorStages[1]['statuss'] === true ) {
                $this->_multiFactorStages[2] = array (
                    'enc_key' => \openssl_random_pseudo_bytes($this->getEncKeyLength()),
                    'statuss' => false
                );                
            }

            return $this->_multiFactorStages;
        } elseif ($currentStage != 2) {
            throw new UserCredentialException('The current stage of the multi factor auth process is in an unknown state', 2101);
        }
        
        //authenticate stage 2
        $totpTimestamp = $this->userTotpProfile['totp_timestamp'];
        $totpTimelimit = $this->userTotpProfile['totp_timelimit'];
        $currDateTime = new \DateTime();
        $totpTimeElapsed = $currDateTime->getTimestamp() - $totpTimestamp->getTimestamp();
        $encKey = $this->userTotpProfile['enc_key'];
        $verificationHash = $this->getVerificationHash();
        $comparisonHash = \crypt($this->getCurrentPassword(), $encKey);
        $currentOneTimeToken = $this->getCurrentOneTimeToken();
        $oneTimeToken = $this->oneTimeToken;
        
        //initialize verification - comparison
        $verificationEqualsComparison = false;
        
        //verify if verification hash equals comparison hash. Use hash_equals function if exists
        if (!\function_exists('hash_equals')) {
            if ($verificationHash === $comparisonHash) {
                $verificationEqualsComparison = true;
            }
        } else {
            if (\hash_equals($verificationHash, $comparisonHash)) {
                $verificationEqualsComparison = true;
            }
        }

        if (
            !($totpTimeElapsed < $totpTimelimit)
            || !($verificationEqualsComparison === true)
            || !(\password_verify($oneTimeToken,$currentOneTimeToken))
        ) {
            return false;
        } else {
            return true;
        }
    }