docs: public boolean verify(BIG sk, IdemixIssuerPublicKey ipk) {
          if (ipk == null || Attrs.length != ipk.getAttributeNames().length) {
              return false;
          }
          for (byte[] attr : Attrs) {
              if (attr == null) {
                  return false;
              }
          }
  
          ECP bPrime = new ECP();
          bPrime.copy(IdemixUtils.genG1);
          bPrime.add(ipk.getHsk().mul2(sk, ipk.getHRand(), S));
          for (int i = 0; i < Attrs.length / 2; i++) {
              bPrime.add(ipk.getHAttrs()[2 * i].mul2(BIG.fromBytes(Attrs[2 * i]), ipk.getHAttrs()[2 * i + 1], BIG.fromBytes(Attrs[2 * i + 1])));
          }
          if (Attrs.length % 2 != 0) {
              bPrime.add(ipk.getHAttrs()[Attrs.length - 1].mul(BIG.fromBytes(Attrs[Attrs.length - 1])));
          }
          if (!B.equals(bPrime)) {
              return false;
          }
  
          ECP2 a = IdemixUtils.genG2.mul(E);
          a.add(ipk.getW());
          a.affine();
          return PAIR.fexp(PAIR.ate(a, A)).equals(PAIR.fexp(PAIR.ate(IdemixUtils.genG2, B)));
      }