コード例 #1
0
ファイル: ConvertUtils.cs プロジェクト: Eurodocs/p2abcengine
        public static IssuerParametersComposite convertIssuerParameters(IssuerParameters ip)
        {
            IssuerParametersComposite ipc = new IssuerParametersComposite();

            ipc.E = ip.E;

            byte[][] gtemp = new byte[ip.G.Length][];
            for (int i = 0; i < gtemp.Length; i++)
            {
                gtemp[i] = ip.G[i].GetEncoded();
            }

            ipc.G = gtemp;

            ipc.Gq = convertSubgroupDescription(ip.Gq);
            if (ip.Gd != null)
            {
                ipc.Gd    = ip.Gd.GetEncoded();
                ipc.Gq.Gd = ip.Gd.GetEncoded();
            }

            ipc.HashFunctionOID   = ip.HashFunctionOID;
            ipc.IsDeviceSupported = ip.IsDeviceSupported;
            ipc.S    = ip.S;
            ipc.UidH = ip.UidH;
            ipc.UidP = ip.UidP;
            ipc.UsesRecommendedParameters = ip.UsesRecommendedParameters;
            ipc.GroupName = ip.Gq.GroupName;

            return(ipc);
        }
コード例 #2
0
ファイル: ConvertUtils.cs プロジェクト: Eurodocs/p2abcengine
        public static IssuerParameters convertIssuerParametersComposite(IssuerParametersComposite ipc, SessionData sessionData)
        {
            IssuerParameters ip = new IssuerParameters();

            ip.E = ipc.E;

            if (sessionData.group == null)
            {
                GroupDescription sGroup = convertSubgroupDescription(ipc.Gq);
                ip.Gq = sGroup;
            }
            else
            {
                ip.Gq = sessionData.group;
            }

            GroupElement[] geArray = new GroupElement[ipc.G.Length];
            for (int i = 0; i < ipc.G.Length; i++)
            {
                geArray[i] = ip.Gq.CreateGroupElement(ipc.G[i]);
            }

            ip.G = geArray;
            if (ipc.UsesRecommendedParameters && ipc.Gd == null)
            {
                ip.Gd = sessionData.parameterSet.Gd;
            }
            else if (ipc.Gd != null)
            {
                ip.Gd = ip.Gq.CreateGroupElement(ipc.Gd);
            }
            else
            {
                ip.Gd = ip.Gq.CreateGroupElement(ipc.Gq.Gd); //sessionData.groupElement;// parametersSet.Gd;
            }



            ip.S    = ipc.S;
            ip.UidH = ipc.UidH;
            ip.UidP = ipc.UidP;
            ip.UsesRecommendedParameters = ipc.UsesRecommendedParameters;
            sessionData.group            = ip.Gq;
            sessionData.groupElement     = ip.Gd;
            return(ip);
        }
コード例 #3
0
 /// <summary>
 /// Verifies the issuer parameters.
 /// </summary>
 /// <param name="ipc">The issuer parameters.</param>
 /// <returns>True if the parameters are valid, false otherwise.</returns>
 public bool verifyIssuerParameters(IssuerParametersComposite ipc, string sessionID)
 {
     VerifySessionId(sessionID);
     cOut.write("Verifying Issuer parameters: ");
     try
     {
         IssuerParameters ip = ConvertUtils.convertIssuerParametersComposite(ipc, sessionDB[sessionID]);
         ip.Verify();
         return(true);
     }
     catch (Exception e)
     {
         cOut.write("Exception caught: " + e.Message);
         DebugUtils.DebugPrint(e.StackTrace.ToString());
         return(false);
     }
 }
コード例 #4
0
        public bool verifyTokenProof(PresentationProofComposite proof, int[] disclosedIndices, int[] committedIndices, string messageParam, string verifierScopeParam, IssuerParametersComposite ipc, UProveTokenComposite token, string sessionID)
        {
            /*
             *  token verification
             */

            cOut.write("Verifying a U-Prove token");
            VerifySessionId(sessionID);
            IssuerParameters ip = ConvertUtils.convertIssuerParametersComposite(ipc, sessionDB[sessionID]);

            // the application-specific message that the prover will sign. Typically this is a nonce combined
            // with any application-specific transaction data to be signed.
            byte[] message = encoding.GetBytes(messageParam);

            // the application-specific verifier scope from which a scope-exclusive pseudonym will be created
            // (if null, then a pseudonym will not be presented)
            byte[] scope = null;
            if (verifierScopeParam != "null")
            {
                scope = encoding.GetBytes(verifierScopeParam);
            }

            // verify the presentation proof
            try
            {
                byte[] tokenId;
                byte[] proofSession;

                UProveToken       t = ConvertUtils.convertUProveTokenComposite(ip, token);
                PresentationProof p = ConvertUtils.convertPresentationProofComposite(ip, proof, out tokenId, out proofSession);

                p.Verify(ip,
                         disclosedIndices,
                         committedIndices,
                         scope != null ? DevicePseudonymIndex : 0,
                         scope,
                         message,
                         proofSession,
                         t);
                if (proof.TokenID != null && !ProtocolHelper.ComputeTokenID(ip, t).SequenceEqual(proof.TokenID))
                {
                    cOut.write("Invalid Token ID");
                    return(false);
                }
                return(true);
            }
            catch (Exception e)
            {
                cOut.write("Exception caught: " + e.Message);
                DebugUtils.DebugPrint(e.StackTrace.ToString());
                return(false);
            }
        }
コード例 #5
0
        public PresentationProofComposite proveToken(string[] attributesParam, int[] disclosedIndices, int[] committedIndices, string messageParam, string verifierScopeParam, IssuerParametersComposite ipc, UProveTokenComposite tokenComposite, byte[] tokenPrivateKeyParam, string sessionID)
        {
            /*
             *  token presentation
             */

            cOut.write("Presenting a U-Prove token");
            VerifySessionId(sessionID);
            try
            {
                // specify the attribute values agreed to by the Issuer and Prover
                int      numberOfAttributes = attributesParam.Length;
                byte[][] attributes         = new byte[numberOfAttributes][];
                for (int i = 0; i < numberOfAttributes; i++)
                {
                    attributes[i] = encoding.GetBytes(attributesParam[i]);
                }

                IssuerParameters ip = ConvertUtils.convertIssuerParametersComposite(ipc, sessionDB[sessionID]);
                // the application-specific message that the prover will sign. Typically this is a nonce combined
                // with any application-specific transaction data to be signed.
                byte[] message = encoding.GetBytes(messageParam);

                // the application-specific verifier scope from which a scope-exclusive pseudonym will be created
                // (if null, then a pseudonym will not be presented)
                byte[] scope = null;
                if (verifierScopeParam != null && verifierScopeParam != "null")
                {
                    scope = encoding.GetBytes(verifierScopeParam);
                }

                // generate the presentation proof
                UProveToken       uProveToken = ConvertUtils.convertUProveTokenComposite(ip, tokenComposite);
                byte[]            bigInt      = tokenPrivateKeyParam;
                DeviceManager     dManager    = sessionDB[sessionID].deviceManager;
                UProveKeyAndToken keyAndToken = new UProveKeyAndToken();
                keyAndToken.PrivateKey = new BigInteger(1, bigInt);
                keyAndToken.Token      = uProveToken;
                byte[] proofSession = null;
                if (!dManager.IsVirtualDevice)
                {
                    SmartCardDevice smartDevice = (SmartCardDevice)dManager.GetDevice();
                    smartDevice.ProofSession = smartDevice.Device.BeginCommitment(1);
                    byte[] proofSessionRaw = smartDevice.ProofSession;
                    proofSession    = new byte[1 + proofSessionRaw.Length];
                    proofSession[0] = 1;
                    Buffer.BlockCopy(proofSessionRaw, 0, proofSession, 1, proofSessionRaw.Length);
                }
                BigInteger[]      commitmentValues;
                PresentationProof p =
                    PresentationProof.Generate(ip,
                                               disclosedIndices,
                                               committedIndices,
                                               scope != null ? DevicePseudonymIndex : 0,
                                               scope,
                                               message,
                                               proofSession,
                                               dManager.GetDevice().GetPresentationContext(),
                                               keyAndToken,
                                               attributes,
                                               out commitmentValues);
#if DEBUG
                dManager.pDebug = p;
#endif

                return(ConvertUtils.convertPresentationProof(p, commitmentValues, ProtocolHelper.ComputeTokenID(ip, uProveToken), proofSession));
            }
            catch (Exception e)
            {
                cOut.write(e.ToString());
                DebugUtils.DebugPrint(e.StackTrace.ToString());
            }

            return(null);
        }
コード例 #6
0
        public SecondIssuanceMessageComposite getSecondMessage(string[] attributesParam, IssuerParametersComposite ipc, int numberOfTokensParam, FirstIssuanceMessageComposite firstMessage, string sessionID)
        {
            /*
             *  token issuance - generate second message
             */

            cOut.write("Issuing U-Prove tokens - generate second message, prover side");
            VerifySessionId(sessionID);

            try
            {
                string tokenInformationParam  = null;
                string proverInformationParam = null;

                // specify the attribute values agreed to by the Issuer and Prover
                int      numberOfAttributes = attributesParam.Length;
                byte[][] attributes         = new byte[numberOfAttributes][];
                for (int i = 0; i < numberOfAttributes; i++)
                {
                    attributes[i] = encoding.GetBytes(attributesParam[i]);
                }

                // specify the special field values
                byte[] tokenInformation  = (tokenInformationParam == null) ? new byte[] { } : encoding.GetBytes(tokenInformationParam);
                byte[] proverInformation = (proverInformationParam == null) ? new byte[] { } : encoding.GetBytes(proverInformationParam);

                // specify the number of tokens to issue
                int numberOfTokens = numberOfTokensParam;

                IssuerParameters ip = ConvertUtils.convertIssuerParametersComposite(ipc, sessionDB[sessionID]);

                // Convert serializable FirstIssuanceMessageComposite members to FirstIssuanceMessage
                FirstIssuanceMessage fi = ConvertUtils.convertFirstIssuanceMessageComposite(firstMessage, ip);

                // setup the prover and generate the second issuance message
                Prover prover = new Prover(ip, numberOfTokens, attributes, tokenInformation, proverInformation, sessionDB[sessionID].deviceManager.GetDevice());

                // Store the prover in proversDictionary using the sessionKey as key
                sessionDB[sessionID].prover = prover;

                SecondIssuanceMessage sm = prover.GenerateSecondMessage(fi);

                // Convert SecondIssuanceMessage members to serializable SecondIssuanceMessageComposite
                SecondIssuanceMessageComposite smc = ConvertUtils.convertSecondIssuanceMessage(sm);

                // Add the sessionKey to SecondIssuanceMessageComposite
                smc.SessionKey = sessionID;

                return(smc);
            }
            catch (Exception e)
            {
                cOut.write(e.ToString());
                DebugUtils.DebugPrint(e.StackTrace.ToString());
            }

            return(null);
        }
コード例 #7
0
        // issuerPrivateKey must be set using setIssuerPrivateKey() before calling this method
        public FirstIssuanceMessageComposite getFirstMessage(string[] attributesParam, IssuerParametersComposite ipc, int numberOfTokensParam, string sessionID, byte[] hd)
        {
            /*
             *  token issuance - generate first message
             */

            cOut.write("Issuing U-Prove tokens - generate first message, issuer side");

            VerifySessionId(sessionID);
            try
            {
                // specify the attribute values agreed to by the Issuer and Prover
                int      numberOfAttributes = attributesParam.Length;
                byte[][] attributes         = new byte[numberOfAttributes][];
                for (int i = 0; i < numberOfAttributes; i++)
                {
                    attributes[i] = encoding.GetBytes(attributesParam[i]);
                }

                IssuerParameters ip = ConvertUtils.convertIssuerParametersComposite(ipc, sessionDB[sessionID]);
                byte[]           issuerPrivateKey = sessionDB[sessionID].privateKey;
                if (issuerPrivateKey == null)
                {
                    cOut.write("Issuer side, issuerPrivateKey is null. Did you forget to add the issuer private key for the given sessionKey?");
                    return(null);
                }
                BigInteger             bi   = new BigInteger(1, issuerPrivateKey);
                IssuerKeyAndParameters ikap = new IssuerKeyAndParameters(bi, ip);

                // setup the issuer and generate the first issuance message

                GroupElement hdG = ip.Gq.CreateGroupElement(hd);

                Issuer issuer = new Issuer(ikap, numberOfTokensParam, attributes, null, hdG);

                // Store the issuer in issuersDictionary using the sessionKey as key
                sessionDB[sessionID].issuer = issuer;

                FirstIssuanceMessage fi = issuer.GenerateFirstMessage();

                // Convert FirstIssuanceMessage members to serializable FirstIssuanceMessageComposite
                FirstIssuanceMessageComposite fic = ConvertUtils.convertFirstIssuanceMessage(fi);

                // Add the sessionKey to FirstIssuanceMessageComposite
                fic.SessionKey = sessionID;

                return(fic);
            }
            catch (Exception e)
            {
                cOut.write(e.ToString());
                DebugUtils.DebugPrint(e.StackTrace.ToString());
            }

            return(null);
        }
コード例 #8
0
    public PresentationProofComposite proveToken(string[] attributesParam, int[] disclosedIndices, int[] committedIndices, string messageParam, string verifierScopeParam, IssuerParametersComposite ipc, UProveTokenComposite tokenComposite, byte[] tokenPrivateKeyParam, string sessionID)
    {
      /*
       *  token presentation
       */

      cOut.write("Presenting a U-Prove token");
      VerifySessionId(sessionID);
      try
      {
        // specify the attribute values agreed to by the Issuer and Prover
        int numberOfAttributes = attributesParam.Length;
        byte[][] attributes = new byte[numberOfAttributes][];
        for (int i = 0; i < numberOfAttributes; i++)
        {
          attributes[i] = encoding.GetBytes(attributesParam[i]);
        }

        IssuerParameters ip = ConvertUtils.convertIssuerParametersComposite(ipc, sessionDB[sessionID]);
        // the application-specific message that the prover will sign. Typically this is a nonce combined
        // with any application-specific transaction data to be signed.
        byte[] message = encoding.GetBytes(messageParam);

        // the application-specific verifier scope from which a scope-exclusive pseudonym will be created
        // (if null, then a pseudonym will not be presented)
        byte[] scope = null;
        if (verifierScopeParam != null && verifierScopeParam != "null")
        {
          scope = encoding.GetBytes(verifierScopeParam);
        }

        // generate the presentation proof
        UProveToken uProveToken = ConvertUtils.convertUProveTokenComposite(ip, tokenComposite);
        byte[] bigInt = tokenPrivateKeyParam;
        DeviceManager dManager = sessionDB[sessionID].deviceManager;
        UProveKeyAndToken keyAndToken = new UProveKeyAndToken();
        keyAndToken.PrivateKey = new BigInteger(1, bigInt);
        keyAndToken.Token = uProveToken;
        byte[] proofSession = null;
        if (!dManager.IsVirtualDevice)
        {
          SmartCardDevice smartDevice = (SmartCardDevice)dManager.GetDevice();
          smartDevice.ProofSession = smartDevice.Device.BeginCommitment(1);
          byte[] proofSessionRaw = smartDevice.ProofSession;
          proofSession = new byte[1 + proofSessionRaw.Length];
          proofSession[0] = 1;
          Buffer.BlockCopy(proofSessionRaw, 0, proofSession, 1, proofSessionRaw.Length);
        }
        BigInteger[] commitmentValues;
        PresentationProof p =
          PresentationProof.Generate(ip,
                                     disclosedIndices,
                                     committedIndices,
                                     scope != null ? DevicePseudonymIndex : 0,
                                     scope,
                                     message,
                                     proofSession,
                                     dManager.GetDevice().GetPresentationContext(),
                                     keyAndToken,
                                     attributes,
                                     out commitmentValues);
#if DEBUG
        dManager.pDebug = p;
#endif

        return ConvertUtils.convertPresentationProof(p, commitmentValues, ProtocolHelper.ComputeTokenID(ip, uProveToken), proofSession);
      }
      catch (Exception e)
      {
        cOut.write(e.ToString());
        DebugUtils.DebugPrint(e.StackTrace.ToString());
      }

      return null;
    }
コード例 #9
0
    public bool verifyTokenProof(PresentationProofComposite proof, int[] disclosedIndices, int[] committedIndices, string messageParam, string verifierScopeParam, IssuerParametersComposite ipc, UProveTokenComposite token, string sessionID)
    {
      /*
             *  token verification
            */

      cOut.write("Verifying a U-Prove token");
      VerifySessionId(sessionID);
      IssuerParameters ip = ConvertUtils.convertIssuerParametersComposite(ipc, sessionDB[sessionID]);

      // the application-specific message that the prover will sign. Typically this is a nonce combined
      // with any application-specific transaction data to be signed.
      byte[] message = encoding.GetBytes(messageParam);

      // the application-specific verifier scope from which a scope-exclusive pseudonym will be created
      // (if null, then a pseudonym will not be presented)
      byte[] scope = null;
      if (verifierScopeParam != "null")
      {
        scope = encoding.GetBytes(verifierScopeParam);
      }

      // verify the presentation proof
      try
      {
        byte[] tokenId;
        byte[] proofSession;

        UProveToken t = ConvertUtils.convertUProveTokenComposite(ip, token);
        PresentationProof p = ConvertUtils.convertPresentationProofComposite(ip, proof, out tokenId, out proofSession);

        p.Verify(ip,
                 disclosedIndices,
                 committedIndices,
                 scope != null ? DevicePseudonymIndex : 0,
                 scope,
                 message,
                 proofSession,
                 t);
        if (proof.TokenID != null && !ProtocolHelper.ComputeTokenID(ip, t).SequenceEqual(proof.TokenID))
        {
          cOut.write("Invalid Token ID");
          return false;
        }
        return true;
      }
      catch (Exception e)
      {
        cOut.write("Exception caught: " + e.Message);
        DebugUtils.DebugPrint(e.StackTrace.ToString());
        return false;
      }
    }
コード例 #10
0
    public SecondIssuanceMessageComposite getSecondMessage(string[] attributesParam, IssuerParametersComposite ipc, int numberOfTokensParam, FirstIssuanceMessageComposite firstMessage, string sessionID)
    {
      /*
       *  token issuance - generate second message
       */

      cOut.write("Issuing U-Prove tokens - generate second message, prover side");
      VerifySessionId(sessionID);

      try
      {
        string tokenInformationParam = null;
        string proverInformationParam = null;

        // specify the attribute values agreed to by the Issuer and Prover
        int numberOfAttributes = attributesParam.Length;
        byte[][] attributes = new byte[numberOfAttributes][];
        for (int i = 0; i < numberOfAttributes; i++)
        {
          attributes[i] = encoding.GetBytes(attributesParam[i]);
        }

        // specify the special field values
        byte[] tokenInformation = (tokenInformationParam == null) ? new byte[] { } : encoding.GetBytes(tokenInformationParam);
        byte[] proverInformation = (proverInformationParam == null) ? new byte[] { } : encoding.GetBytes(proverInformationParam);

        // specify the number of tokens to issue
        int numberOfTokens = numberOfTokensParam;

        IssuerParameters ip = ConvertUtils.convertIssuerParametersComposite(ipc, sessionDB[sessionID]);

        // Convert serializable FirstIssuanceMessageComposite members to FirstIssuanceMessage
        FirstIssuanceMessage fi = ConvertUtils.convertFirstIssuanceMessageComposite(firstMessage, ip);

        // setup the prover and generate the second issuance message
        Prover prover = new Prover(ip, numberOfTokens, attributes, tokenInformation, proverInformation, sessionDB[sessionID].deviceManager.GetDevice());

        // Store the prover in proversDictionary using the sessionKey as key
        sessionDB[sessionID].prover = prover;

        SecondIssuanceMessage sm = prover.GenerateSecondMessage(fi);

        // Convert SecondIssuanceMessage members to serializable SecondIssuanceMessageComposite
        SecondIssuanceMessageComposite smc = ConvertUtils.convertSecondIssuanceMessage(sm);

        // Add the sessionKey to SecondIssuanceMessageComposite
        smc.SessionKey = sessionID;

        return smc;

      }
      catch (Exception e)
      {
        cOut.write(e.ToString());
        DebugUtils.DebugPrint(e.StackTrace.ToString());
      }

      return null;
    }
コード例 #11
0
    // issuerPrivateKey must be set using setIssuerPrivateKey() before calling this method
    public FirstIssuanceMessageComposite getFirstMessage(string[] attributesParam, IssuerParametersComposite ipc, int numberOfTokensParam, string sessionID, byte[] hd)
    {
      /*
       *  token issuance - generate first message
       */

      cOut.write("Issuing U-Prove tokens - generate first message, issuer side");

      VerifySessionId(sessionID);
      try
      {

        // specify the attribute values agreed to by the Issuer and Prover
        int numberOfAttributes = attributesParam.Length;
        byte[][] attributes = new byte[numberOfAttributes][];
        for (int i = 0; i < numberOfAttributes; i++)
        {
          attributes[i] = encoding.GetBytes(attributesParam[i]);
        }

        IssuerParameters ip = ConvertUtils.convertIssuerParametersComposite(ipc, sessionDB[sessionID]);
        byte[] issuerPrivateKey = sessionDB[sessionID].privateKey;
        if (issuerPrivateKey == null)
        {
          cOut.write("Issuer side, issuerPrivateKey is null. Did you forget to add the issuer private key for the given sessionKey?");
          return null;
        }
        BigInteger bi = new BigInteger(1, issuerPrivateKey);
        IssuerKeyAndParameters ikap = new IssuerKeyAndParameters(bi, ip);

        // setup the issuer and generate the first issuance message

        GroupElement hdG = ip.Gq.CreateGroupElement(hd);

        Issuer issuer = new Issuer(ikap, numberOfTokensParam, attributes, null, hdG);

        // Store the issuer in issuersDictionary using the sessionKey as key
        sessionDB[sessionID].issuer = issuer;

        FirstIssuanceMessage fi = issuer.GenerateFirstMessage();

        // Convert FirstIssuanceMessage members to serializable FirstIssuanceMessageComposite
        FirstIssuanceMessageComposite fic = ConvertUtils.convertFirstIssuanceMessage(fi);

        // Add the sessionKey to FirstIssuanceMessageComposite
        fic.SessionKey = sessionID;

        return fic;
      }
      catch (Exception e)
      {
        cOut.write(e.ToString());
        DebugUtils.DebugPrint(e.StackTrace.ToString());
      }

      return null;
    }
コード例 #12
0
    /// <summary>
    /// Verifies the issuer parameters.
    /// </summary>
    /// <param name="ipc">The issuer parameters.</param>
    /// <returns>True if the parameters are valid, false otherwise.</returns>
    public bool verifyIssuerParameters(IssuerParametersComposite ipc, string sessionID)
    {
      VerifySessionId(sessionID);
      cOut.write("Verifying Issuer parameters: ");
      try
      {
        IssuerParameters ip = ConvertUtils.convertIssuerParametersComposite(ipc,  sessionDB[sessionID]);
        ip.Verify();
        return true;
      }
      catch (Exception e)
      {
        cOut.write("Exception caught: " + e.Message);
        DebugUtils.DebugPrint(e.StackTrace.ToString());
        return false;
      }

    }
コード例 #13
0
    public static IssuerParameters convertIssuerParametersComposite(IssuerParametersComposite ipc, SessionData sessionData)
    {

      IssuerParameters ip = new IssuerParameters();

      ip.E = ipc.E;

      if (sessionData.group == null)
      {
        GroupDescription sGroup = convertSubgroupDescription(ipc.Gq);
        ip.Gq = sGroup;
      }
      else
      {
        ip.Gq = sessionData.group;
      }

      GroupElement[] geArray = new GroupElement[ipc.G.Length];
      for (int i = 0; i < ipc.G.Length; i++)
      {
        geArray[i] = ip.Gq.CreateGroupElement(ipc.G[i]);
      }

      ip.G = geArray;
      if (ipc.UsesRecommendedParameters && ipc.Gd == null)
      {
        ip.Gd = sessionData.parameterSet.Gd;
      }
      else if (ipc.Gd != null)
      {
        ip.Gd = ip.Gq.CreateGroupElement(ipc.Gd);
      }
      else
      {
        ip.Gd = ip.Gq.CreateGroupElement(ipc.Gq.Gd); //sessionData.groupElement;// parametersSet.Gd;
      }
      

      

      ip.S = ipc.S;
      ip.UidH = ipc.UidH;
      ip.UidP = ipc.UidP;
      ip.UsesRecommendedParameters = ipc.UsesRecommendedParameters;
      sessionData.group = ip.Gq;
      sessionData.groupElement = ip.Gd;
      return ip;
    }
コード例 #14
0
    public static IssuerParametersComposite convertIssuerParameters(IssuerParameters ip)
    {
      IssuerParametersComposite ipc = new IssuerParametersComposite();
      ipc.E = ip.E;

      byte[][] gtemp = new byte[ip.G.Length][];
      for (int i = 0; i < gtemp.Length; i++)
      {
        gtemp[i] = ip.G[i].GetEncoded();
      }

      ipc.G = gtemp;

      ipc.Gq = convertSubgroupDescription(ip.Gq);
      if (ip.Gd != null)
      {
        ipc.Gd = ip.Gd.GetEncoded();
        ipc.Gq.Gd = ip.Gd.GetEncoded();
      }
      
      ipc.HashFunctionOID = ip.HashFunctionOID;
      ipc.IsDeviceSupported = ip.IsDeviceSupported;
      ipc.S = ip.S;
      ipc.UidH = ip.UidH;
      ipc.UidP = ip.UidP;
      ipc.UsesRecommendedParameters = ip.UsesRecommendedParameters;
      ipc.GroupName = ip.Gq.GroupName;

      return ipc;
    }