code: ServerResponse respond(ClientChallenge clientChallenge)
      throws GeneralSecurityException {
  
      SecretKeySpec authKey = generateKey(clientChallenge.kdf, clientChallenge.iterations,
        clientChallenge.nonce, clientChallenge.keyLength);
      initializeForAuth(clientChallenge.cipher, clientChallenge.nonce, authKey);
  
      byte[] challenge = validateChallenge(clientChallenge.nonce, clientChallenge.challenge);
      byte[] response = challenge(appId, clientChallenge.nonce, rawResponse(challenge));
      byte[] sessionNonce = randomBytes(conf.encryptionKeyLength() / Byte.SIZE);
      byte[] inputIv = randomBytes(conf.ivLength());
      byte[] outputIv = randomBytes(conf.ivLength());
  
      SecretKeySpec sessionKey = generateKey(clientChallenge.kdf, clientChallenge.iterations,
        sessionNonce, clientChallenge.keyLength);
      this.sessionCipher = new TransportCipher(cryptoConf, clientChallenge.cipher, sessionKey,
        inputIv, outputIv);
  
      // Note the IVs are swapped in the response.
      return new ServerResponse(response, encrypt(sessionNonce), encrypt(outputIv), encrypt(inputIv));
    }
docs: Validates the client challenge, and create the encryption backend for the channel from the
  parameters sent by the client.
  
  @param clientChallenge The challenge from the client.
  @return A response to be sent to the client.