/**
   * Verifies the proof.
   *
   * @param z second message from prover
   * @param input MUST be an instance of SigmaDJEncryptedValueCommonInput.
   * @return true if the proof has been verified; false, otherwise.
   * @throws IllegalArgumentException if input is not an instance of
   *     SigmaDJEncryptedValueCommonInput.
   * @throws IllegalArgumentException if the messages of the prover are not an instance of
   *     SigmaBIMsg
   */
  public boolean verify(SigmaCommonInput in, SigmaProtocolMsg a, SigmaProtocolMsg z) {
    /*
     * Converts the input (n, c, x) to (n, c') where c' = c*(1+n)^(-x) mod N'.
     */
    if (!(in instanceof SigmaDJEncryptedValueCommonInput)) {
      throw new IllegalArgumentException(
          "the given input must be an instance of SigmaDJEncryptedValueCommonInput");
    }
    SigmaDJEncryptedValueCommonInput input = (SigmaDJEncryptedValueCommonInput) in;

    // Get public key, cipher and plaintext.
    DamgardJurikPublicKey pubKey = input.getPublicKey();
    BigIntegerPlainText plaintext = input.getPlaintext();
    BigIntegerCiphertext cipher = input.getCiphertext();

    // Convert the cipher c to c' = c*(1+n)^(-x)
    BigInteger n = pubKey.getModulus();
    BigInteger nPlusOne = n.add(BigInteger.ONE);

    // calculate N' = n^(s+1).
    BigInteger NTag = n.pow(lengthParameter + 1);

    // Calculate (n+1)^(-x)
    BigInteger minusX = plaintext.getX().negate();
    BigInteger multVal = nPlusOne.modPow(minusX, NTag);

    // Calculate the ciphertext for DamgardJurikEncryptedZero - c*(n+1)^(-x).
    BigInteger newCipher = cipher.getCipher().multiply(multVal).mod(NTag);
    BigIntegerCiphertext cipherTag = new BigIntegerCiphertext(newCipher);

    // Create an input object to the underlying sigmaDamgardJurik verifier.
    SigmaDJEncryptedZeroCommonInput underlyingInput =
        new SigmaDJEncryptedZeroCommonInput(pubKey, cipherTag);

    // Delegates to the underlying sigmaDamgardJurik verifier.
    return sigmaDamgardJurik.verify(underlyingInput, a, z);
  }
 /**
  * Returns the sampled challenge.
  *
  * @return the challenge.
  */
 public byte[] getChallenge() {
   // Delegates to the underlying sigmaDamgardJurik verifier.
   return sigmaDamgardJurik.getChallenge();
 }
 /** Samples the challenge e <- {0,1}^t. */
 public void sampleChallenge() {
   // Delegates to the underlying sigmaDamgardJurik verifier.
   sigmaDamgardJurik.sampleChallenge();
 }
 /**
  * Sets the given challenge.
  *
  * @param challenge
  */
 public void setChallenge(byte[] challenge) {
   // Delegates to the underlying sigmaDamgardJurik verifier.
   sigmaDamgardJurik.setChallenge(challenge);
 }
 /**
  * Returns the soundness parameter for this Sigma protocol.
  *
  * @return t soundness parameter
  */
 public int getSoundnessParam() {
   // Delegates to the underlying sigmaDamgardJurik verifier.
   return sigmaDamgardJurik.getSoundnessParam();
 }