public String createChallangeNAClaims(String req, String claimDefs, int size) throws Exception {
    ObjectMapper mapper = new ObjectMapper();
    ArrayNode claimDefNodes = (ArrayNode) mapper.readTree(claimDefs);

    req = req.replaceAll("\"", "");
    byte[] reqElemBytes = Base64.decode(req);

    Element reqElem = null;
    ArrayList<IdentityClaimDefinition> icds = new ArrayList<IdentityClaimDefinition>();

    for (int i = 0; i < size; i++) {
      String onVal = claimDefNodes.get(i).getTextValue();

      ObjectNode claimDefOn = (ObjectNode) mapper.readTree(onVal);
      IdentityClaimDefinition idClaimDef = new IdentityClaimDefinition(claimDefOn);
      icds.add(idClaimDef);

      if (reqElem == null) {
        Pairing pairing = idClaimDef.getParams().getPairing();
        reqElem = pairing.getG1().newElement();
        reqElem.setFromBytes(reqElemBytes);
        //				System.out.println(reqElem);
      }
    }

    Pairing pairing = icds.get(0).getParams().getPairing();
    Field gt = pairing.getGT();
    Element sessionKey = gt.newRandomElement().getImmutable();
    Element sessionKeyOrig = sessionKey.getImmutable();
    // System.out.println("Key: " + sessionKey);

    JsonNode rootNode = mapper.createObjectNode();
    ObjectNode on = (ObjectNode) rootNode;
    Encrypt encrypt = new Encrypt();

    for (int i = 0; i < size; i++) {
      IdentityClaimDefinition claimDef = icds.get(i);

      Element share = null;
      if (i < (size - 1)) {
        share = gt.newRandomElement().getImmutable();
        sessionKey = sessionKey.sub(share).getImmutable();
      } else {
        // Last one should be the remaining part of session key
        share = sessionKey;
      }

      encrypt.init(claimDef.getParams());
      // System.out.println("Part : " + i + " : " + share);
      AECipherTextBlock ct = encrypt.doEncrypt(share, reqElem);

      on.put(claimDef.getName(), ct.serializeJSON());
    }

    //		System.out.println(sessionKeyOrig);
    String sk = new String(Base64.encode(sessionKeyOrig.toBytes()));
    sk = sk.replaceAll(" ", "");
    on.put("SessionKey", sk);
    return on.toString();
  }
  private void initialize(CurveParameters cp) {
    random = new Random(0);
    // e = PairingFactory.getPairing(cp);

    e = new TypeAPairing(random, cp);

    // Groups G1 and G2 of prime order q
    G1 = e.getG1();
    G2 = e.getGT();

    // Field Zq
    Zq = e.getZr();

    // Global system parameters: g \in G1, Z = e(g,g) \in G2
    g = ((CurveField) G1).getGen().getImmutable();
    //        if(g.isZero()){
    //            System.out.println("g es 0!! :(");
    //            System.exit(-1);
    //        }
    //        g = G1.newRandomElement().getImmutable();
    // System.out.println("g = " + ProxyMain.elementToString(g));

    Z = e.pairing(g, g).getImmutable();

    Z_ppp = Z.pow();
    g_ppp = g.pow();

    /*
    System.out.println(G1.getClass());
    System.out.println(G2.getClass());
    System.out.println(Zq.getClass());
    System.out.println(e.getClass());
    System.out.println(g.getClass());
    System.out.println(g.toBytes()[0]);
    System.out.println(Z.getClass());*/

  }
  /**
   * @param request
   * @param claimDefs Array of claim defs
   * @return
   * @throws Exception
   */
  public String createChallangeNClaimsThreads(String requests, String claimDefs) throws Exception {
    ObjectMapper mapper = new ObjectMapper();

    // System.out.println(requests);
    String[] split = requests.split(",");
    ArrayNode claimDefNodes = (ArrayNode) mapper.readTree(claimDefs);

    ArrayList<IdentityClaimDefinition> icds = new ArrayList<IdentityClaimDefinition>();
    ArrayList<Element> reqs = new ArrayList<Element>();

    for (int i = 0; i < split.length; i++) {
      String onVal = claimDefNodes.get(i).getTextValue();
      ObjectNode claimDefOn = (ObjectNode) mapper.readTree(onVal);
      IdentityClaimDefinition idClaimDef = new IdentityClaimDefinition(claimDefOn);
      icds.add(idClaimDef);

      Pairing pairing = idClaimDef.getParams().getPairing();
      // System.out.println(idClaimDef.serializeJSON());
      String tmpReq = split[i].replaceAll("\"", "");

      byte[] reqElemBytes = Base64.decode(tmpReq);
      // System.out.println(reqElemBytes.length);
      Element reqElem = pairing.getG1().newElement();
      reqElem.setFromBytes(reqElemBytes);
      // System.out.println(reqElem.getImmutable());

      reqs.add(reqElem);
    }

    Pairing pairing = icds.get(0).getParams().getPairing();
    Field gt = pairing.getGT();
    Element sessionKey = gt.newRandomElement().getImmutable();
    Element sessionKeyOrig = sessionKey.getImmutable();
    // System.out.println("Key: " + sessionKey);

    JsonNode rootNode = mapper.createObjectNode();
    ObjectNode on = (ObjectNode) rootNode;

    ArrayList<EncrypterThread> ets = new ArrayList<ServiceProvider.EncrypterThread>();

    for (int i = 0; i < split.length; i++) {
      IdentityClaimDefinition claimDef = icds.get(i);

      Element share = null;
      if (i < (split.length - 1)) {
        share = gt.newRandomElement().getImmutable();
        sessionKey = sessionKey.sub(share).getImmutable();
      } else {
        // Last one should be the remaining part of session key
        share = sessionKey;
      }

      EncrypterThread t =
          new EncrypterThread(claimDef.getName(), claimDef.getParams(), share, reqs.get(i), on);
      t.start();
      ets.add(t);
    }

    for (EncrypterThread t : ets) {
      t.join();
    }

    String sk = new String(Base64.encode(sessionKeyOrig.toBytes()));
    sk = sk.replaceAll(" ", "");
    on.put("SessionKey", sk);
    return on.toString();
  }