public static final PolynomialMembershipProofSystem getInstance(
      final SigmaChallengeGenerator challengeGenerator,
      final Subset members,
      final PedersenCommitmentScheme pedersenCS) {

    if (challengeGenerator == null || members == null || pedersenCS == null) {
      throw new IllegalArgumentException();
    }
    if (!(members.getSuperset() instanceof ZModPrime)
        || pedersenCS.getCyclicGroup().getOrder() != members.getSuperset().getOrder()) {
      throw new IllegalArgumentException();
    }
    if (!challengeGenerator.getChallengeSpace().isEquivalent(pedersenCS.getMessageSpace())) {
      throw new IllegalArgumentException();
    }

    return new PolynomialMembershipProofSystem(challengeGenerator, members, pedersenCS);
  }
  private PolynomialMembershipProofSystem(
      final SigmaChallengeGenerator challengeGenerator,
      final Subset members,
      final PedersenCommitmentScheme pedersenCS) {
    super(challengeGenerator);

    this.members = members;
    final Element[] roots = new Element[this.members.getOrder().intValue()];
    int i = 0;
    for (Element member : this.members.getElements()) {
      roots[i++] = member;
    }

    PolynomialElement polynomial =
        PolynomialSemiRing.getInstance((ZModPrime) members.getSuperset())
            .getElementByRoots(Tuple.getInstance(roots));
    this.pepsi =
        PolynomialEvaluationProofSystem.getInstance(challengeGenerator, polynomial, pedersenCS);
  }