public function verifyAuthentication(Registration $registration, SignRequest $request, SignResponse $response)
    {
        if (!$this->appId->equals(new AppId($request->appId))) {
            return AuthenticationVerificationResult::appIdMismatch();
        }

        if ($response->errorCode > 0) {
            return AuthenticationVerificationResult::deviceReportedError($response->errorCode);
        }

        $yubicoRegistration = new YubicoRegistration();
        $yubicoRegistration->keyHandle = $registration->keyHandle;
        $yubicoRegistration->publicKey = $registration->publicKey;
        $yubicoRegistration->counter   = $registration->signCounter;

        $yubicoRequest = new YubicoSignRequest();
        $yubicoRequest->version   = $request->version;
        $yubicoRequest->challenge = $request->challenge;
        $yubicoRequest->appId     = $request->appId;
        $yubicoRequest->keyHandle = $request->keyHandle;

        $yubicoResponse = new \stdClass;
        $yubicoResponse->keyHandle     = $response->keyHandle;
        $yubicoResponse->signatureData = $response->signatureData;
        $yubicoResponse->clientData    = $response->clientData;

        try {
            $yubicoRegistration = $this->u2fService->doAuthenticate(
                [$yubicoRequest],
                [$yubicoRegistration],
                $yubicoResponse
            );
        } catch (Error $error) {
            switch ($error->getCode()) {
                case \u2flib_server\ERR_NO_MATCHING_REQUEST:
                    return AuthenticationVerificationResult::requestResponseMismatch();
                case \u2flib_server\ERR_NO_MATCHING_REGISTRATION:
                    return AuthenticationVerificationResult::responseRegistrationMismatch();
                case \u2flib_server\ERR_PUBKEY_DECODE:
                    return AuthenticationVerificationResult::publicKeyDecodingFailed();
                case \u2flib_server\ERR_AUTHENTICATION_FAILURE:
                    return AuthenticationVerificationResult::responseWasNotSignedByDevice();
                case \u2flib_server\ERR_COUNTER_TOO_LOW:
                    return AuthenticationVerificationResult::signCounterTooLow();
                default:
                    throw new LogicException(
                        sprintf(
                            'The Yubico U2F service threw an exception with error code %d that should not occur ("%s")',
                            $error->getCode(),
                            $error->getMessage()
                        ),
                        $error
                    );
            }
        }

        $registration = new Registration();
        $registration->keyHandle   = $yubicoRegistration->keyHandle;
        $registration->publicKey   = $yubicoRegistration->publicKey;
        $registration->signCounter = $yubicoRegistration->counter;

        return AuthenticationVerificationResult::success($registration);
    }