/// <summary>
 /// Constructs a new <code>IssuerSetupParameters</code> instance.
 /// </summary>
 public IssuerSetupParameters()
 {
     ip = new IssuerParameters();
     // set the defaults
     ip.UidH = "SHA-256";
     GroupConstruction = GroupType.Subgroup;
 }
        private static UProveKeyAndToken[] IssueUProveTokens(IssuerKeyAndParameters ikap, IssuerParameters ip, byte[][] attributes, int numOfTokens, byte[] ti = null, byte[] pi = null)
        {
            WriteLine("Issuing " + numOfTokens + " tokens");
            // setup the issuer and generate the first issuance message
            IssuerProtocolParameters ipp = new IssuerProtocolParameters(ikap);
            ipp.Attributes = attributes;
            ipp.NumberOfTokens = numOfTokens;
            ipp.TokenInformation = ti;
            Issuer issuer = ipp.CreateIssuer();
            string firstMessage = ip.Serialize<FirstIssuanceMessage>(issuer.GenerateFirstMessage());

            // setup the prover and generate the second issuance message
            ProverProtocolParameters ppp = new ProverProtocolParameters(ip);
            ppp.Attributes = attributes;
            ppp.NumberOfTokens = numOfTokens;
            ppp.TokenInformation = ti;
            ppp.ProverInformation = pi;
            Prover prover = ppp.CreateProver();
            string secondMessage = ip.Serialize<SecondIssuanceMessage>(prover.GenerateSecondMessage(ip.Deserialize<FirstIssuanceMessage>(firstMessage)));

            // generate the third issuance message
            string thirdMessage = ip.Serialize<ThirdIssuanceMessage>(issuer.GenerateThirdMessage(ip.Deserialize<SecondIssuanceMessage>(secondMessage)));

            // generate the tokens
            return prover.GenerateTokens(ip.Deserialize<ThirdIssuanceMessage>(thirdMessage));
        }
        public static void GenerateTestIssuanceParameters(string uidp, string spec, int numberOfAttributes, bool useRecommendedParameters, int numberOfTokens, out IssuerKeyAndParameters ikap, out IssuerProtocolParameters ipp, out ProverProtocolParameters ppp)
        {
            IssuerSetupParameters isp = new IssuerSetupParameters(maxNumberOfAttributes);

            isp.UidP = (uidp == null ? null : encoding.GetBytes(uidp));
            isp.E    = IssuerSetupParameters.GetDefaultEValues(numberOfAttributes);
            isp.UseRecommendedParameterSet = useRecommendedParameters;
            isp.S = (spec == null ? null : encoding.GetBytes(spec));
            ikap  = isp.Generate();
            IssuerParameters ip = ikap.IssuerParameters;

            // Issuance
            byte[][] attributes = new byte[numberOfAttributes][];
            for (int i = 0; i < numberOfAttributes; i++)
            {
                attributes[i] = encoding.GetBytes("attribute value " + (i + 1));
            }
            byte[] tokenInformation  = encoding.GetBytes("token information field");
            byte[] proverInformation = encoding.GetBytes("prover information field");

            ipp                  = new IssuerProtocolParameters(ikap);
            ipp.Attributes       = attributes;
            ipp.NumberOfTokens   = numberOfTokens;
            ipp.TokenInformation = tokenInformation;

            ppp                   = new ProverProtocolParameters(ip);
            ppp.Attributes        = attributes;
            ppp.NumberOfTokens    = numberOfTokens;
            ppp.TokenInformation  = tokenInformation;
            ppp.ProverInformation = proverInformation;
        }
        void IParametrizedDeserialization.FinishDeserialization(IssuerParameters ip)
        {
            try
            {
                if (!this.deserializationStarted)
                {
                    throw new SerializationException("deserialization not started");
                }

                this.group = ip.Gq;
                this.g     = group.G;
                this.g1    = ip.G[1];
                this.gt    = ip.G[ip.G.Length - 1];
                this.uidh  = ip.UidH;
                this.K     = _k.ToGroupElement(ip.Gq);
            }
            catch
            {
                throw;
            }
            finally
            {
                this.deserializationStarted = false;
            }
        }
        }                                           // same as in ip

        /// <summary>
        ///  Create a new IDEscrowParams instance.
        /// </summary>
        /// <param name="ip">The issuer paramters to use.</c></param>
        /// <remarks> The choice of issuer paramters defines the <c>GroupDescription</c> and
        /// <c>HashFunction</c> to use for the ID escrow scheme. </remarks>
        public IDEscrowParams(IssuerParameters ip)
        {
            this.ip = ip;
            this.G  = ip.Gq;
            this.ge = ip.Gq.G;          // g_e is set to the generator of the group
            this.H  = ip.HashFunction;
        }
Beispiel #6
0
        public void SMSerializationTest()
        {
            for (int paramIndex = 0; paramIndex < StaticHelperClass.ParameterArray.Length; ++paramIndex)
            {
                // choose parameters
                CryptoParameters crypto    = StaticHelperClass.ParameterArray[paramIndex];
                FieldZqElement[] memberSet = crypto.FieldZq.GetRandomElements(10, true);

                // create a set membership proof
                ProverSetMembershipParameters prover = new ProverSetMembershipParameters(crypto);
                prover.setProverParameters(memberSet[3], memberSet);
                SetMembershipProof originalProof = new SetMembershipProof(prover);

                // serialize the proof
                IssuerParameters ip = new IssuerParameters();
                string           serializedProof = ip.Serialize <SetMembershipProof>(originalProof);

                // deserialize the proof
                SetMembershipProof deserializedProof = ip.Deserialize <SetMembershipProof>(serializedProof);

                // make sure it verifies
                Assert.IsTrue(deserializedProof.Verify(prover), "deserialized proof does not verify.");

                // serialize the proof again
                string serializedProof2 = ip.Serialize <SetMembershipProof>(deserializedProof);

                // make sure the two serialized proofs are equal
                Assert.AreEqual(serializedProof, serializedProof2, "inconsistent proof serialization.");
            }
        }
        void IParametrizedDeserialization.FinishDeserialization(IssuerParameters ip)
        {
            try
            {
                if (!this.deserializationStarted)
                {
                    throw new SerializationException("deserialization not started");
                }

                if (!_uidp.ToByteArray().SequenceEqual(ip.UidP))
                {
                    throw new UProveSerializationException("Invalid issuer parameters in IdEscrowParams.FinishDeserializing (UIDp does not match serialized UIDp).");
                }
                this.ip = ip;
                this.H  = ip.HashFunction;
                this.G  = ip.Gq;
                this.ge = _ge.ToGroupElement(ip);
            }
            catch
            {
                throw;
            }
            finally
            {
                this.deserializationStarted = false;
            }
        }
Beispiel #8
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);
        }
        void IParametrizedDeserialization.FinishDeserialization(IssuerParameters ip)
        {
            try
            {
                if (!this.deserializationStarted)
                {
                    throw new SerializationException("deserialization not started");
                }

                this.cPrime = _cPrime.ToFieldZqElement(ip.Zq);
                this.s      = new FieldZqElement[6];
                for (int i = 0; i < 6; i++)
                {
                    this.s[i] = _s[i].ToFieldZqElement(ip.Zq);
                }
                this.X  = _X.ToGroupElement(ip.Gq);
                this.Y  = _Y.ToGroupElement(ip.Gq);
                this.Cd = _Cd.ToGroupElement(ip.Gq);
            }
            catch
            {
                throw;
            }
            finally
            {
                this.deserializationStarted = false;
            }
        }
        public static void MyClassInitialize(TestContext testContext)
        {
            //
            // generate issuer parameters
            //
            IssuerSetupParameters isp = new IssuerSetupParameters(maxNumberOfAttributes);

            isp.UidP = new byte[] { (byte)0 };
            //isp.NumberOfAttributes = 1;
            isp.E = new byte[] { (byte)0 };  // encode xid directly has an
            IssuerKeyAndParameters ikap = isp.Generate();

            ip = ikap.IssuerParameters;

            //
            // issue a token
            //
            xid = ip.Gq.FieldZq.GetRandomElement(false);
            IssuerProtocolParameters ipp = new IssuerProtocolParameters(ikap);
            ProverProtocolParameters ppp = new ProverProtocolParameters(ip);

            attributes         = new byte[][] { xid.ToByteArray() };
            ipp.Attributes     = ppp.Attributes = attributes;
            ipp.NumberOfTokens = ppp.NumberOfTokens = 1;
            Issuer issuer = ipp.CreateIssuer();
            Prover prover = ppp.CreateProver();

            upkt = prover.GenerateTokens(issuer.GenerateThirdMessage(prover.GenerateSecondMessage(issuer.GenerateFirstMessage())))[0];
        }
Beispiel #11
0
        public void TestIssuerSetupParameters()
        {
            System.Text.UTF8Encoding encoding = new System.Text.UTF8Encoding();

            byte[][] A  = new byte[][] { encoding.GetBytes("attribute value") };
            byte[]   TI = encoding.GetBytes("TI value");
            IssuerSetupParameters isp = new IssuerSetupParameters();

            isp.GroupConstruction = GroupType.Subgroup;
            isp.UidP = encoding.GetBytes("UIDP value");
            isp.E    = new byte[] { 1 };
            IssuerKeyAndParameters ikap = isp.Generate();

            ikap.IssuerParameters.Verify();

            // invalidate the issuer parameters

            IssuerParameters     ip   = ikap.IssuerParameters;
            SubgroupGroupElement sgG0 = (SubgroupGroupElement)ip.G[0];

            byte[] g0Bytes = ip.G[0].GetEncoded();
            g0Bytes[g0Bytes.Length - 1]++;
            ip.G[0] = (SubgroupGroupElement)ip.Gq.CreateGroupElement(g0Bytes);

            try
            {
                ip.Verify();
                Assert.Fail();
            }
            catch (InvalidUProveArtifactException) { }
        }
        /// <summary>
        /// Sets up the prover parameters with the ip, attributes, numberOfTokens, ti and the given pi
        /// for this token creation
        /// </summary>
        /// <param name="firstMessageJson">first message received from issuer, contains: ip, attributes, numberOfTokens, ti
        /// and the first message itself</param>
        /// <param name="pi">prover information for the prover information field</param>
        /// <param name="attributes">attributes to insert into the tokens - chosen by the prover</param>
        /// <param name="numberOfTokens">number of tokens the prover wants to create</param>
        /// <param name="ti">token information field - given by the issuer</param>
        /// <param name="ipJson">issuer parameter - given by the issuer</param>
        public void Init(string firstMessageJson, byte[] pi, List <BasicClaim> attributes,
                         int numberOfTokens, byte[] ti, string ipJson, List <string> supportedDateAttributes)
        {
            try
            {
                LogService.Log(LogService.LogType.Info, "IssuingProver - init called");

                this.firstMessageJson = firstMessageJson;
                this.pi = pi;

                List <RangeProofProperties> rangeProofProperties;
                ci.CreateBase64ForAttributeList(attributes, supportedDateAttributes, out rangeProofProperties);

                Attributes          = attributes;
                this.numberOfTokens = numberOfTokens;
                this.ti             = ti;

                // set issuer parameters
                IP = new IssuerParameters(ipJson);
                IP.Verify();
                LogService.Log(LogService.LogType.Info, "IssuingProver - Prover successfully set up");
            }
            catch (Exception e)
            {
                LogService.Log(LogService.LogType.FatalError, "IssuingProver - Error during prover setup.", e);
                throw new CommunicationException("IssuingProver - Error during prover setup.", e);
            }
        }
        public void BDSerializationTest()
        {
            FieldZqElement     bigNum               = _parameters[0].FieldZq.GetElement(2056);
            PedersenCommitment bigNumCommit         = new PedersenCommitment(bigNum, _parameters[0]);
            int decompositionLength                 = 15;
            ProverBitDecompositionParameters prover = new ProverBitDecompositionParameters(
                bigNumCommit,
                decompositionLength,
                _parameters[0]);

            BitDecompositionProof proof = new BitDecompositionProof(prover);

            Assert.IsTrue(proof.Verify(prover), "original proof verification.");
            string jsonProof = CryptoSerializer.Serialize <BitDecompositionProof>(proof);
            // TODO: switch to using ip-based de-serialization; need to harmonize with U-Prove SDK code
            IssuerParameters ip = new IssuerParameters();

            ip.Gq = prover.Group;
            BitDecompositionProof deserializedProof = ip.Deserialize <BitDecompositionProof>(jsonProof);// CryptoSerializer.Deserialize<BitDecompositionProof>(jsonProof);

            Assert.IsTrue(deserializedProof.Verify(prover), "deserialized proof verfication");


            string jsonProver = CryptoSerializer.Serialize <ProverBitDecompositionParameters>(prover);
            ProverBitDecompositionParameters deserializedProver = CryptoSerializer.Deserialize <ProverBitDecompositionParameters>(jsonProver);

            Assert.IsTrue(deserializedProof.Verify(deserializedProver), "deserialized proof with deserialized prover.");

            BitDecompositionProof proof2 = new BitDecompositionProof(deserializedProver);

            Assert.IsTrue(proof2.Verify(deserializedProver), "proof2.verify(deserializedProver)");
            Assert.IsTrue(proof2.Verify(prover), "Proof2.verify(prover)");
        }
Beispiel #14
0
        private static CommitmentPrivateValues PresentUProveToken(IssuerParameters ip, UProveKeyAndToken upkt, byte[][] attributes, int[] disclosed, int[] committed, byte[] message, byte[] scope, IDevice device, byte[] deviceMessage)
        {
            WriteLine("Presenting one token");
            // the returned commitment randomizer (to be used by an external proof module)
            CommitmentPrivateValues cpv;

            // generate the presentation proof
            string token = ip.Serialize <UProveToken>(upkt.Token);
            ProverPresentationProtocolParameters pppp = new ProverPresentationProtocolParameters(ip, disclosed, message, upkt, attributes);

            pppp.Committed = committed;
            // if a scope is defined, we use the first attribute to derive a scope exclusive pseudonym
            pppp.PseudonymAttributeIndex = (scope == null ? 0 : 1);
            pppp.PseudonymScope          = scope;
            if (device != null)
            {
                pppp.SetDeviceData(deviceMessage, device.GetPresentationContext());
            }
            pppp.KeyAndToken = upkt;
            pppp.Attributes  = attributes;
            string proof = ip.Serialize <PresentationProof>(PresentationProof.Generate(pppp, out cpv));

            // verify the presentation proof
            VerifierPresentationProtocolParameters vppp = new VerifierPresentationProtocolParameters(ip, disclosed, message, ip.Deserialize <UProveToken>(token));

            vppp.Committed = committed;
            // if a scope is defined, we use the first attribute to derive a scope exclusive pseudonym
            vppp.PseudonymAttributeIndex = (scope == null ? 0 : 1);
            vppp.PseudonymScope          = scope;
            vppp.DeviceMessage           = deviceMessage;
            ip.Deserialize <PresentationProof>(proof).Verify(vppp);

            return(cpv);
        }
Beispiel #15
0
        /// <summary>
        /// Initialise the system for a given token by the prover
        /// </summary>
        /// <param name="ipJson">Json string of the issuer parameters which has issued the given token</param>
        /// <param name="proofJson">Json string that includes the proof to the given token and later proofs -
        /// created by the prover itself</param>
        /// <param name="tokenJson">Json of the token - created by issuer and prover</param>
        /// <param name="trustedIssuerJson">List of trusted issuers; in IP format, could be more than one Issuer
        /// in a anonymus Json-Object; { "IP..</param>
        public void Init(string ipJson, string proofJson, string tokenJson, string trustedIssuerJson)
        {
            LogService.Log(LogService.LogType.Info, "IssuingVerifier - init called");

            proofAccepted = false;
            tokenAccepted = false;
            isInitialized = false;

            // create issuer parameters
            IP = new IssuerParameters(ipJson);
            IP.Verify();

            this.trustedIssuerJson = trustedIssuerJson;
            CheckTrustedIssuer();

            Proof proof = parser.ParseJsonToObject <Proof>(proofJson);

            proofRequirements = proof.requirements;

            PresentationProof pProof = IP.Deserialize <PresentationProof>(proofJson);

            this.tokenJson = tokenJson;
            this.proofJson = IP.Serialize(pProof);

            isInitialized = true;
            LogService.Log(LogService.LogType.Info, "IssuingVerifier - successfully initialized");

            VerifyProof();
        }
Beispiel #16
0
 /// <summary>
 /// Computes the revocation value from its byte array encoding, to be added to an accumulator or used
 /// to compute the witness.
 /// </summary>
 /// <param name="ip">The issuer parameters, containing the information on how to transform the encoded value.</param>
 /// <param name="revocationIndex">The 1-based index of the revocation attribute.</param>
 /// <param name="attributeValue">The attribute value.</param>
 /// <returns>The revocation value.</returns>
 public static FieldZqElement ComputeRevocationValue(IssuerParameters ip, int revocationIndex, byte[] attributeValue)
 {
     if (revocationIndex <= 0)
     {
         throw new ArgumentException("revocationIndex must be positive: " + revocationIndex);
     }
     return(ProtocolHelper.ComputeXi(ip, revocationIndex - 1, attributeValue));
 }
Beispiel #17
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);
        }
 /// <summary>
 /// Returns all Closed Pedersen Commitments associated with a presentation proof.
 /// This is a UProve integration function that is called by the verifier.
 /// </summary>
 /// <param name="ip">Issuer Parameters</param>
 /// <param name="proof">Instance of the proof presentation protocol</param>
 /// <returns></returns>
 public static ClosedPedersenCommitment[] ArrayOfClosedPedersenCommitments(IssuerParameters ip, PresentationProof proof)
 {
     ClosedPedersenCommitment[] closedPed = new ClosedPedersenCommitment[proof.Commitments.Length];
     for (int i = 0; i < closedPed.Length; ++i)
     {
         closedPed[i] = new ClosedPedersenCommitment(ip, proof, i);
     }
     return(closedPed);
 }
Beispiel #19
0
 /// <summary>
 /// Deserializer must call this method or FinishDeserializing(Group group) after
 /// deserialization is complete.  This method is for UProve cross-compatibility.
 /// </summary>
 /// <param name="ip">ip.Gq contains the group to use if none has been serialized.
 /// Argument ip or ip.Gq may be null if the group has been serialized.</param>
 void IParametrizedDeserialization.FinishDeserialization(IssuerParameters ip)
 {
     if (ip == null)
     {
         FinishDeserializing(null);
     }
     FinishDeserializing(ip.Gq);
     this.IsDeserializingComplete = true;
 }
Beispiel #20
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);
        }
Beispiel #21
0
        public void CollaborativeIssuanceTest()
        {
            // Issuer setup
            IssuerSetupParameters isp = new IssuerSetupParameters();

            isp.UidP = new byte[] { 1, 2, 3, 4, 5, 6, 7, 8, 9 };
            isp.E    = new byte[] { (byte)1, (byte)1, (byte)1, (byte)1 };
            isp.UseRecommendedParameterSet = true;
            isp.S = new byte[] { 1, 2, 3, 4, 5, 6, 7, 8, 9 };
            IssuerKeyAndParameters ikap = isp.Generate();
            IssuerParameters       ip   = ikap.IssuerParameters;

            // Issuance

            byte[][] attributes        = new byte[][] { encoding.GetBytes("Attribute 1"), encoding.GetBytes("Attribute 2"), encoding.GetBytes("Attribute 3"), encoding.GetBytes("Attribute 4") };
            byte[]   tokenInformation  = new byte[] { };
            byte[]   proverInformation = new byte[] { };
            int      numberOfTokens    = 2;

            // Test cases
            // 1: CA-RA split (a party trusted by the issuer provides the gamma value)
            int numTestCases = 1;

            for (int testCase = 1; testCase <= numTestCases; testCase++)
            {
                ProverProtocolParameters ppp = new ProverProtocolParameters(ip);
                ppp.Attributes        = attributes;
                ppp.NumberOfTokens    = numberOfTokens;
                ppp.TokenInformation  = tokenInformation;
                ppp.ProverInformation = proverInformation;
                Prover prover = ppp.CreateProver();

                IssuerProtocolParameters ipp = new IssuerProtocolParameters(ikap);
                if (testCase == 1)
                {
                    ipp.Gamma = ProtocolHelper.ComputeIssuanceInput(ip, attributes, tokenInformation, null);
                }
                ipp.NumberOfTokens = numberOfTokens;
                Issuer issuer = ipp.CreateIssuer();

                FirstIssuanceMessage  msg1 = issuer.GenerateFirstMessage();
                SecondIssuanceMessage msg2 = prover.GenerateSecondMessage(msg1);
                ThirdIssuanceMessage  msg3 = issuer.GenerateThirdMessage(msg2);
                UProveKeyAndToken[]   upkt = prover.GenerateTokens(msg3);

                // use the token to make sure everything is ok
                int[]             disclosed = new int[0];
                byte[]            message   = encoding.GetBytes("this is the presentation message, this can be a very long message");
                FieldZqElement[]  unused;
                byte[]            scope = null;
                PresentationProof proof = PresentationProof.Generate(ip, disclosed, null, 1, scope, message, null, null, upkt[0], attributes, out unused);
                proof.Verify(ip, disclosed, null, 1, scope, message, null, upkt[0].Token);
            }
        }
 /// <summary>
 /// Constructor.  Initializes object from UProve IssuerParameters.
 /// Use this when integrating PolyProof proofs with UProve.
 /// </summary>
 /// <param name="ip"></param>
 public CryptoParameters(IssuerParameters ip)
 {
     this.Group         = ip.Gq;
     this.Generators    = new GroupElement[ip.G.Length];
     this.Generators[0] = ip.Gq.G;
     for (int i = 1; i < Generators.Length; ++i)
     {
         this.Generators[i] = ip.G[i];
     }
     this.HashFunctionName = ip.UidH;
 }
        /// <summary>
        /// Creates a closed commitment using default generators from the IssuerParameters.
        /// </summary>
        /// <param name="ip">Issuer parameters</param>
        /// <param name="value">Value of commitment</param>
        public ClosedPedersenCommitment(IssuerParameters ip, GroupElement value)
        {
            this.Value = value;

            CryptoParameters crypto = new CryptoParameters(ip);

            this.Group = crypto.Group;
            this.Bases = new GroupElement[2] {
                crypto.Generators[0], crypto.Generators[1]
            };
        }
        /// <summary>
        /// Creates a closed commitment from one of the commitments created by a presentation proof.
        /// This is a UProve integration method that should be called by the Verifier.
        /// </summary>
        /// <param name="ip">Issuer parameters</param>
        /// <param name="proof">token presentation proof</param>
        /// <param name="commitmentIndex">which commitment</param>
        public ClosedPedersenCommitment(IssuerParameters ip, PresentationProof proof, int commitmentIndex)
        {
            this.Value = proof.Commitments[commitmentIndex].TildeC;

            CryptoParameters crypto = new CryptoParameters(ip);

            this.Group = crypto.Group;
            this.Bases = new GroupElement[2] {
                crypto.Generators[0], crypto.Generators[1]
            };
        }
Beispiel #25
0
 public void TestError <T>(IssuerParameters issuerParameters, string json, string expectedError) where T : IParametrizedDeserialization
 {
     try
     {
         issuerParameters.Deserialize <T>(json);
         Assert.Fail("should fail");
     }
     catch (SerializationException exp)
     {
         Assert.AreEqual(expectedError, exp.Message);
     }
 }
Beispiel #26
0
        /// <summary>
        /// Computes the non-revocation proof.
        /// </summary>
        /// <param name="ip">The Issuer parameters associated with the presented U-Prove token.</param>
        /// <param name="rap">The Revocation Authority parameters.</param>
        /// <param name="witness">The user non-revocation witness.</param>
        /// <param name="commitmentIndex">The 0-based index of the revocation commitment in the attribute commitments.</param>
        /// <param name="presentationProof">The presentation proof generated with the U-Prove token.</param>
        /// <param name="cpv">The commitment private values generated when presenting the U-Prove token.</param>
        /// <param name="revocationIndex">The 1-based index of the revocation attribute in the U-Prove token.</param>
        /// <param name="attributes">The token attributes.</param>
        /// <returns>A non-revocation proof.</returns>
        public static NonRevocationProof GenerateNonRevocationProof(IssuerParameters ip, RAParameters rap, RevocationWitness witness, int commitmentIndex, PresentationProof presentationProof, CommitmentPrivateValues cpv, int revocationIndex, byte[][] attributes)
        {
            if (revocationIndex <= 0)
            {
                throw new ArgumentException("revocationIndex must be positive: " + revocationIndex);
            }
            GroupElement   tildeCid = presentationProof.Commitments[commitmentIndex].TildeC;
            FieldZqElement xid      = ProtocolHelper.ComputeXi(ip, revocationIndex - 1, attributes[revocationIndex - 1]);
            FieldZqElement tildeOid = cpv.TildeO[commitmentIndex];

            return(GenerateNonRevocationProof(rap, witness, tildeCid, xid, tildeOid));
        }
Beispiel #27
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);
            }
        }
Beispiel #28
0
        public void FreshParametersTest()
        {
            //
            // test with 1 attribute
            //

            // Issuer setup
            IssuerSetupParameters isp = new IssuerSetupParameters(maxNumberOfAttributes);

            isp.UidP = new byte[] { 1, 2, 3, 4, 5, 6, 7, 8, 9 };
            // isp.NumberOfAttributes = 1;   // extension by Fablei
            isp.UseRecommendedParameterSet = false; // use freshly generated generators
            isp.GroupConstruction          = GroupType.Subgroup;
            IssuerKeyAndParameters ikap = isp.Generate();
            IssuerParameters       ip   = ikap.IssuerParameters;

            // get the default subgroup to make sure that is _not_ what we are generating
            ParameterSet set;

            ParameterSet.TryGetNamedParameterSet("1.3.6.1.4.1.311.75.1.1.1", out set);
            Assert.AreNotEqual(ip.G[1], set.G[0]); // set's index 0 is g_1

            RunProtocol(ikap, ip);

            //
            // test with max+1 attributes
            //

            //isp.NumberOfAttributes = IssuerSetupParameters.RecommendedParametersMaxNumberOfAttributes + 1;
            isp.MaxNumberOfAttributes = maxNumberOfAttributes + 1;
            ikap = isp.Generate();
            ip   = ikap.IssuerParameters;
            //Assert.IsTrue(ip.E.Length == IssuerSetupParameters.RecommendedParametersMaxNumberOfAttributes + 1);
            Assert.IsTrue(ip.E.Length == maxNumberOfAttributes + 1);
            RunProtocol(ikap, ip);

            //
            // test invalid number of attributes
            //

            isp.UseRecommendedParameterSet = true;
            try
            {
                ikap = isp.Generate();
                //Assert.Fail();
                // extension by Fablei -> expected because if isp.MaxNumberOfAttributes changes, ip.E changes as well
            }
            catch (System.ArgumentException)
            {
                Assert.Fail();
            };
        }
Beispiel #29
0
        /// <summary>
        /// This sample illustrates how to issue and present software-only U-Prove tokens.
        /// </summary>
        public static void SoftwareOnlySample()
        {
            WriteLine("U-Prove SDK Sample");

            /*
             *  issuer setup
             */
            IssuerKeyAndParameters ikap = SetupUProveIssuer("sample software-only issuer", 12);
            string privateKeyBase64     = ikap.PrivateKey.ToBase64String(); // this needs to be stored securely
            string ipJSON = ikap.IssuerParameters.Serialize();

            // the IssuerParameters instance needs to be distributed to the Prover and Verifier.
            // Each needs to verify the parameters before using them
            IssuerParameters ip = new IssuerParameters(ipJSON);

            ip.Verify();

            /*
             *  token issuance
             */
            // specify the attribute values agreed to by the Issuer and Prover
            byte[][] attributes = new byte[][] {
                encoding.GetBytes("first attribute value"),
                encoding.GetBytes("second attribute value"),
                encoding.GetBytes("third attribute value")
            };
            // specify the special field values
            byte[] tokenInformation  = encoding.GetBytes("token information value");
            byte[] proverInformation = encoding.GetBytes("prover information value");
            // specify the number of tokens to issue
            int numberOfTokens = 1;

            UProveKeyAndToken[] upkt = IssueUProveTokens(new IssuerKeyAndParameters(privateKeyBase64, ipJSON), ip, attributes, numberOfTokens, tokenInformation, proverInformation);

            /*
             *  token presentation
             */
            // the indices of disclosed attributes
            int[] disclosed = new int[] { 2 };
            // the indices of the committed attributes (used by protocol extensions)
            int[] committed = null;
            // 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 = GenerateNoncePlusTimestampMessage();
            // 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 = encoding.GetBytes("verifier scope");

            PresentUProveToken(ip, upkt[0], attributes, disclosed, committed, message, scope, null, null);

            WriteLine("Sample completed.\n*************************************************************\n");
        }
 /// <summary>
 /// Constructs an IssuerKeyAndParameters instance.
 /// </summary>
 /// <param name="privateKey">The private key.</param>
 /// <param name="issuerParameters">The Issuer parameters.</param>
 public IssuerKeyAndParameters(FieldZqElement privateKey, IssuerParameters issuerParameters)
 {
     if (privateKey == null)
     {
         throw new ArgumentNullException("privateKey");
     }
     if (issuerParameters == null)
     {
         throw new ArgumentNullException("issuerParameters");
     }
     this.privateKey = privateKey;
     this.issuerParameters = issuerParameters;
 }
 /// <summary>
 /// Generates a member set for UProve tokens.
 /// </summary>
 /// <param name="ip">Issuer parameters.</param>
 /// <param name="attributeIndexInToken">Index of attribute in the token the proof will be about (encoding of memberSet depends on this). Index is 1....n.</param>
 /// <param name="memberSet">Member set</param>
 /// <returns></returns>
 public static FieldZqElement[] GenerateMemberSet(IssuerParameters ip, int attributeIndexInToken, byte[][] memberSet)
 {
     if (attributeIndexInToken <= 0)
     {
         throw new ArgumentException("attributeIndexInToken must be a positive integer");
     }
     FieldZqElement[] output = new FieldZqElement[memberSet.Length];
     for (int i = 0; i < output.Length; ++i)
     {
         output[i] = ProtocolHelper.ComputeXi(ip, attributeIndexInToken - 1, memberSet[i]);
     }
     return(output);
 }
        /// <summary>
        /// Generates the Issuer parameters cryptographic data, <code>ip</code> will be updated with the cryptographic data.
        /// </summary>
        /// <param name="ip">An instanciated Issuer parameters; the Gq and E properties must be set.</param>
        /// <param name="gValues">The issuer generators to use, or null.</param>
        /// <param name="supportDevice">Indicates if the device generator must be generated.</param>
        /// <returns>The Issuer parameters private key.</returns>
        internal static FieldZqElement GenerateIssuerParametersCryptoData(IssuerParameters ip, GroupElement[] gValues, bool supportDevice)
        {
            if (ip == null)
            {
                throw new ArgumentNullException("ip");
            }
            if (ip.Gq == null)
            {
                throw new ArgumentException("Group description is not set");
            }
            int n = ip.E == null ? 0 : ip.E.Length;
            Group Gq = ip.Gq;
            ip.G = new GroupElement[n + 2];

            FieldZqElement privateKey;
            if (gValues == null)
            {
                FieldZqElement[] y = ip.Zq.GetRandomElements(n + 2, false);
                privateKey = y[0];

                for (int i = 0; i < (n + 2); i++)
                {
                    ip.G[i] = Gq.G.Exponentiate(y[i]);
                }
            }
            else
            {
                // g_0
                privateKey = ip.Zq.GetRandomElement(false);
                ip.G[0] = Gq.G.Exponentiate(privateKey);

                // g_1,..,g_n
                for (int i = 1; i < (n + 1); i++)
                {
                    ip.G[i] = gValues[i - 1];
                }

                // g_t
                int t = n + 1;
                ip.G[t] = gValues[gValues.Length - 1];
            }

            if (supportDevice)
            {
                if (ip.Gd == null)
                {
                    ip.Gd = Gq.G.Exponentiate(ip.Zq.GetRandomElement(false));
                }
            }
            return privateKey;
        }
Beispiel #33
0
        /// <summary>
        /// Verifies a non-revocation proof.
        /// </summary>
        /// <param name="ip">The issuer parameters associated with the proof.</param>
        /// <param name="revocationCommitmentIndex">The 0-based index corresponding to the revocation commitment in the proof.</param>
        /// <param name="proof">The presentation proof.</param>
        /// <param name="nrProof">The non-revocation proof.</param>
        /// <exception cref="InvalidUProveArtifactException">Thrown if the proof is invalid.</exception>
        public void VerifyNonRevocationProof(IssuerParameters ip, int revocationCommitmentIndex, PresentationProof proof, NonRevocationProof nrProof)
        {
            Group        Gq       = ip.Gq;
            FieldZq      Zq       = Gq.FieldZq;
            GroupElement tildeCid = proof.Commitments[revocationCommitmentIndex].TildeC;
            // T1 = (V Y^-1 Cd^-1)^c' * X^s1 * (tildeCid K)^-s2 * g1^s3
            GroupElement T1 = Gq.MultiExponentiate(
                new GroupElement[] {
                Accumulator *nrProof.Y.Exponentiate(Zq.NegativeOne) * nrProof.Cd.Exponentiate(Zq.NegativeOne),      // TODO: is there a better way to calculate this
                nrProof.X,
                tildeCid * RAParameters.K,
                RAParameters.g1
            },
                new FieldZqElement[] {
                nrProof.cPrime,
                nrProof.s[0],          // s1
                nrProof.s[1].Negate(), // s2
                nrProof.s[2]           // s3
            });
            // T2 = tildeCid^c' g^s1 g1^s4
            GroupElement T2 = Gq.MultiExponentiate(
                new GroupElement[] {
                tildeCid,
                RAParameters.g,
                RAParameters.g1
            },
                new FieldZqElement[] {
                nrProof.cPrime,
                nrProof.s[0],     // s1
                nrProof.s[3],     // s4
            });
            // T3 = gt^c' Cd^s5 g1^s6
            GroupElement T3 = Gq.MultiExponentiate(
                new GroupElement[] {
                RAParameters.gt,
                nrProof.Cd,
                RAParameters.g1
            },
                new FieldZqElement[] {
                nrProof.cPrime,
                nrProof.s[4],     // s5
                nrProof.s[5],     // s6
            });

            if (!nrProof.cPrime.Equals(Zq.GetElementFromDigest(RAParameters.ComputeChallenge(tildeCid, nrProof.X, nrProof.Y, nrProof.Cd, T1, T2, T3))) ||
                !nrProof.Y.Equals(nrProof.X.Exponentiate(PrivateKey)))
            {
                throw new InvalidUProveArtifactException("Invalid non-revocation proof");
            }
        }
Beispiel #34
0
        public static UProveToken convertUProveTokenComposite(IssuerParameters ip, UProveTokenComposite utc)
        {
            UProveToken up = new UProveToken();

            up.H = ip.Gq.CreateGroupElement(utc.H);
            up.IsDeviceProtected = utc.IsDeviceProtected;
            up.PI          = utc.PI;
            up.SigmaCPrime = new BigInteger(1, utc.SigmaCPrime);
            up.SigmaRPrime = new BigInteger(1, utc.SigmaRPrime);
            up.SigmaZPrime = ip.Gq.CreateGroupElement(utc.SigmaZPrime);
            up.TI          = utc.TI;
            up.Uidp        = utc.Uidp;

            return(up);
        }
    public static FirstIssuanceMessage convertFirstIssuanceMessageComposite(FirstIssuanceMessageComposite fic, IssuerParameters ip)
    {
      GroupElement[] geArray1 = new GroupElement[fic.SigmaA.Length];
      for (int i = 0; i < fic.SigmaA.Length; i++)
      {
        geArray1[i] = ip.Gq.CreateGroupElement(fic.SigmaA[i]);
      }

      GroupElement[] geArray2 = new GroupElement[fic.SigmaB.Length];
      for (int i = 0; i < fic.SigmaB.Length; i++)
      {
        geArray2[i] = ip.Gq.CreateGroupElement(fic.SigmaB[i]);
      }

      FirstIssuanceMessage fi = new FirstIssuanceMessage(ip.Gq.CreateGroupElement(fic.SigmaZ), geArray1, geArray2);
      return fi;
    }
        private void RunProtocol(IssuerKeyAndParameters ikap, IssuerParameters ip)
        {
            ip.Verify(); // sanity check

            // Issuance
            int numberOfAttribs = ip.G.Length - 2; // minus g_0 and g_t
            byte[][] attributes = new byte[numberOfAttribs][];
            for (int i = 0; i < numberOfAttribs; i++)
            {
                attributes[i] = new byte[] { (byte)i };
            }
            byte[] tokenInformation = new byte[] { 0x01 };
            byte[] proverInformation = new byte[] { 0x01 };
            int numberOfTokens = 1;

            IssuerProtocolParameters ipp = new IssuerProtocolParameters(ikap);
            ipp.Attributes = attributes;
            ipp.NumberOfTokens = numberOfTokens;
            ipp.TokenInformation = tokenInformation;
            Issuer issuer = ipp.CreateIssuer();
            FirstIssuanceMessage msg1 = issuer.GenerateFirstMessage();
            ProverProtocolParameters ppp = new ProverProtocolParameters(ip);
            ppp.NumberOfTokens = numberOfTokens;
            ppp.Attributes = attributes;
            ppp.TokenInformation = tokenInformation;
            ppp.ProverInformation = proverInformation;
            Prover prover = ppp.CreateProver();
            SecondIssuanceMessage msg2 = prover.GenerateSecondMessage(msg1);
            ThirdIssuanceMessage msg3 = issuer.GenerateThirdMessage(msg2);
            // issue token
            UProveKeyAndToken[] upkt = prover.GenerateTokens(msg3);

            // Presentation
            int[] disclosed = new int[] { 1 };
            byte[] message = new byte[] { 1, 2, 3, 4, 5, 6, 7, 8, 9 };

            // generate the presentation proof
            PresentationProof proof = PresentationProof.Generate(new ProverPresentationProtocolParameters(ip, disclosed, message, upkt[0], attributes));

            // verify the presentation proof
            proof.Verify(new VerifierPresentationProtocolParameters(ip, disclosed, message, upkt[0].Token));
        }
 public static PresentationProof Generate(IssuerParameters ip, int[] disclosed, int[] committed, int pseudonymAttribIndex, byte[] pseudonymScope, byte[] message, byte[] messageD, IDevicePresentationContext deviceContext, UProveKeyAndToken upkt, byte[][] attributes, out FieldZqElement[] tildeO)
 {
     return Generate(ip, disclosed, committed, pseudonymAttribIndex, pseudonymScope, message, messageD, deviceContext, upkt, attributes, null, out tildeO);
 }
 public static PresentationProof Generate(IssuerParameters ip, int[] disclosed, int[] committed, int pseudonymAttribIndex, byte[] pseudonymScope, byte[] message, byte[] messageD, IDevicePresentationContext deviceContext, UProveKeyAndToken upkt, byte[][] attributes, ProofGenerationRandomData preGenW, out FieldZqElement[] tildeO)
 {
     GroupElement gs = ProtocolHelper.GenerateScopeElement(ip.Gq, pseudonymScope);
     return Generate(ip, disclosed, committed, pseudonymAttribIndex, gs, message, messageD, deviceContext, upkt, attributes, preGenW, out tildeO); 
 }
 public static PresentationProof Generate(IssuerParameters ip, int[] disclosed, int[] committed, int pseudonymAttribIndex, GroupElement gs, byte[] message, byte[] messageD, IDevicePresentationContext deviceContext, UProveKeyAndToken upkt, byte[][] attributes, ProofGenerationRandomData preGenW, out FieldZqElement[] tildeO)
 {
     CommitmentPrivateValues cpv;
     PresentationProof proof = Generate(ip, disclosed, committed, pseudonymAttribIndex, gs, message, messageD, deviceContext, upkt, attributes, preGenW, out cpv);
     tildeO = cpv.TildeO;
     return proof;
 }
        /// <summary>
        /// Computes the value <c>gamma</c>, an input to the issuance protocol. 
        /// </summary>
        /// <param name="ip">The issuer parameters</param>
        /// <param name="A"> The attribute values, or null if the token contains no attributes </param>
        /// <param name="TI">The token information field</param>
        /// <param name="hd">The device public key, or <c>null</c> if device binding is not supported by the issuer paramters.</param>
        /// <returns>The group element gamma </returns>
        public static GroupElement ComputeIssuanceInput(IssuerParameters ip, byte[][] A, byte[] TI, GroupElement hd)
        {
            if (ip == null)
            {
                throw new ArgumentNullException("Issuer parameters are null");
            }
            int n = 0;
            bool supportDevice = (hd != null);
            if (supportDevice && !ip.IsDeviceSupported)
            {
                throw new InvalidOperationException("Issuer parameters does not support devices");
            }
            if (A != null)
            {
                n = A.Length;
            }
            Group Gq = ip.Gq;
            GroupElement gamma = ip.G[0];
            for (int i = 0; i < n; i++)
            {
                FieldZqElement xi = ComputeXi(ip, i, A[i]);
                gamma = gamma * ip.G[i+1].Exponentiate(xi);
            }
            FieldZqElement xt = ComputeXt(ip, TI, supportDevice);
            gamma = gamma * ip.G[n+1].Exponentiate(xt);

            // Multiply-in the device public key for device-protected tokens
            if (supportDevice)
            {
                gamma = gamma * hd;
            }
            return gamma;
        }
        public void Verify(IssuerParameters ip, int[] disclosed, int[] committed, int pseudonymAttribIndex, GroupElement gs, byte[] message, byte[] messageD, UProveToken upt)
        {
            try
            {
                // make sure disclosed list is sorted
                if (disclosed == null)
                {
                    // can't be null later, so make it an empty array
                    disclosed = new int[] { };
                }
                Array.Sort(disclosed);
                Group Gq = ip.Gq;
                int n = ip.E.Length;

                bool presentPseudonym = false;
                if (gs != null && pseudonymAttribIndex != 0)
                {
                    if (pseudonymAttribIndex < 1 || (pseudonymAttribIndex > n && pseudonymAttribIndex != DeviceAttributeIndex))
                    {
                        throw new ArgumentException("pseudonymAttribIndex must be between 1 and " + n + " (inclusive)");
                    }
                    if (disclosed.Contains(pseudonymAttribIndex))
                    {
                        throw new ArgumentException("pseudonymAttribIndex cannot be in the disclosed attribute array");
                    }
                    presentPseudonym = true;
                }
                else // no nym
                {
                    pseudonymAttribIndex = 0;
                }
                bool verifyCommitments = (committed != null && committed.Length > 0);
                if (verifyCommitments)
                {
                    Array.Sort(committed);
                }

                ProtocolHelper.VerifyTokenSignature(ip, upt);
                FieldZqElement[] disclosedX = new FieldZqElement[disclosedAttributes.Length];
                GroupElement dAccumulator = ip.G[0] * ip.G[n + 1].Exponentiate(ProtocolHelper.ComputeXt(ip, upt.TI, upt.IsDeviceProtected));     // g0 * gt^xt
                GroupElement uAccumulator = upt.H.Exponentiate(this.r[0]);
                int dIndex = 0;
                int uIndex = 1;
                int cIndex = 0;
                int pseudonymResponseIndex = 0;
                int[] commitmentResponseIndices = verifyCommitments ? new int[committed.Length] : null;
                for (int i = 1; i <= n; i++)
                {
                    if (disclosed.Contains(i))
                    {
                        disclosedX[dIndex] = ProtocolHelper.ComputeXi(ip, i - 1, disclosedAttributes[dIndex]);
                        dAccumulator = dAccumulator * ip.G[i].Exponentiate(disclosedX[dIndex]);
                        dIndex++;
                    }
                    else
                    {
                        uAccumulator = uAccumulator * ip.G[i].Exponentiate(this.r[uIndex]);
                        if (presentPseudonym)
                        {
                            if (pseudonymAttribIndex == i)
                            {
                                pseudonymResponseIndex = uIndex;
                            }
                        }
                        if (verifyCommitments)
                        {
                            if (committed.Contains(i))
                            {
                                // remember which response correspond to which commitment
                                commitmentResponseIndices[cIndex] = uIndex;
                                cIndex++;
                            }
                        }
                        uIndex++;
                    }
                }
                if (pseudonymAttribIndex == DeviceAttributeIndex)
                {
                    pseudonymResponseIndex = this.r.Length - 1; // r_d is the last response in the array
                }

                byte[] unused; // verifier doesn't use the returned message for device
                FieldZqElement c = ProtocolHelper.GenerateChallenge(ip, upt, this.a, pseudonymAttribIndex, this.ap, this.ps, message, messageD, disclosed, disclosedX, committed, this.Commitments, out unused);

                HashFunction hash = ip.HashFunction;
                hash.Hash((dAccumulator.Exponentiate(c.Negate()) * uAccumulator * (upt.IsDeviceProtected ? ip.Gd.Exponentiate(this.r[this.r.Length -1]) : Gq.Identity)));
                if (!this.a.SequenceEqual(hash.Digest))
                {
                    throw new InvalidUProveArtifactException("Invalid presentation proof");
                }

                if (presentPseudonym)
                {
                    hash.Hash(this.ps.Exponentiate(c).Multiply(gs.Exponentiate(this.r[pseudonymResponseIndex])));
                    if (!this.ap.SequenceEqual(hash.Digest))
                    {
                        throw new InvalidUProveArtifactException("Invalid pseudonym");
                    }
                }

                if (verifyCommitments)
                {
                    for (int i = 0; i < commitmentResponseIndices.Length; i++)
                    {
                        CommitmentValues commitment = this.Commitments[i];
                        hash.Hash(commitment.TildeC.Exponentiate(c).Multiply(ip.Gq.G.Exponentiate(this.r[commitmentResponseIndices[i]])).Multiply(ip.G[1].Exponentiate(commitment.TildeR)));
                        if (!commitment.TildeA.SequenceEqual(hash.Digest))
                        {
                            throw new InvalidUProveArtifactException("Invalid commitment " + committed[i]);
                        }
                    }
                }
            }
            catch (ArgumentException)
            {
                throw new InvalidUProveArtifactException("Invalid presentation proof");
            }
            catch (IndexOutOfRangeException)
            {
                throw new InvalidUProveArtifactException("Invalid presentation proof");
            }
        }
    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;
    }
 internal static FieldZqElement GenerateChallenge(IssuerParameters ip, UProveToken upt, byte[] a, int pseudonymIndex, byte[] ap, GroupElement Ps, byte[] m, byte[] md, int[] disclosed, FieldZqElement[] disclosedX, int[] committed, CommitmentValues[] commitments, out byte[] mdPrime)
 {
     bool hasCommitments = (committed != null && committed.Length > 0);
     if (hasCommitments)
     {
         if (committed.Length != commitments.Length)
         {
             throw new ArgumentException("Inconsistent committed indices and commitment values");
         }
     }
 
     HashFunction hash = ip.HashFunction;
     hash.Hash(ComputeTokenID(ip, upt));
     hash.Hash(a);
     hash.Hash(disclosed);
     hash.Hash(disclosedX);
     if (!hasCommitments)
     {
         hash.HashNull(); // C
         hash.HashNull(); // < {tildeC} >
         hash.HashNull(); // < {tildeA} >
     }
     else
     {
         hash.Hash(committed);
         hash.Hash(commitments.Length); // length of < {tildeC} >
         for (int i = 0; i < commitments.Length; i++)
         {
             hash.Hash(commitments[i].TildeC);
         }
         hash.Hash(commitments.Length); // length of < {tildeA} >
         for (int i = 0; i < commitments.Length; i++)
         {
             hash.Hash(commitments[i].TildeA);
         }
     }
     hash.Hash(pseudonymIndex == PresentationProof.DeviceAttributeIndex ? 0 : pseudonymIndex);
     hash.Hash(ap);
     hash.Hash(Ps);
     hash.Hash(m);
     mdPrime = hash.Digest;
     if (upt.IsDeviceProtected)
     {
         hash = ip.HashFunction;
         hash.Hash(md);
         hash.Hash(mdPrime);
         return ip.Zq.GetElementFromDigest(hash.Digest);
     }
     else
     {
         return ip.Zq.GetElementFromDigest(mdPrime);
     }
 }
    public static PresentationProof convertPresentationProofComposite(IssuerParameters ip, PresentationProofComposite pc, out byte[] tokenID, out byte[] proofSession)
    {
      PresentationProof p = new PresentationProof();

      p.A = (pc.A == null ? null : pc.A);
      p.Ap = (pc.Ap == null ? null : pc.Ap);
      p.DisclosedAttributes = pc.DisclosedAttributes;
      p.Ps = (pc.Ps == null ? null : ip.Gq.CreateGroupElement(pc.Ps));

      BigInteger[] biArray = new BigInteger[pc.R.Length];
      for (int i = 0; i < biArray.Length; i++)
      {
        biArray[i] = new BigInteger(1, pc.R[i]);
      }
      p.R = biArray;
      if (pc.TildeValues != null)
      {
        int numCommitments = pc.TildeValues.Length / 3;
        p.Commitments = new CommitmentValues[numCommitments];
        for (int i = 0; i < numCommitments; i++)
        {
          p.Commitments[i] = new CommitmentValues(
              ip.Gq.CreateGroupElement(pc.TildeValues[(i * 3)]), // tildeC
              pc.TildeValues[(i * 3) + 1], // tildaA
              new BigInteger(1, pc.TildeValues[(i * 3) + 2]) // tildeR
              );
        }

        // we ignore the tildeO values. This method is called by the verifier, and 
        // the tildeO values should never be sent to the verifier.
      }

      tokenID = pc.TokenID;

      proofSession = (pc.MessageD == null ? null : pc.MessageD);

      return p;
    }
 public static PresentationProof Generate(IssuerParameters ip, int[] disclosed, byte[] message, byte[] messageD, IDevicePresentationContext deviceContext, UProveKeyAndToken upkt, byte[][] attributes)
 {
     GroupElement gs = null;
     FieldZqElement[] unused;
     return Generate(ip, disclosed, null, 0, gs, message, messageD, deviceContext, upkt, attributes, null, out unused);
 }
        /// <summary>
        /// This sample illustrates how to issue and present device-protected U-Prove tokens.
        /// </summary>
        public static void DeviceSample()
        {

            WriteLine("U-Prove SDK Device Sample");

            /*
             *  issuer setup
             */

            IssuerKeyAndParameters ikap = SetupUProveIssuer("sample device-protected issuer", 3, GroupType.ECC, true);
            string ipJSON = ikap.IssuerParameters.Serialize();

            // the IssuerParameters instance needs to be distributed to the Prover, Device, and Verifier.
            // Each needs to verify the parameters before using them
            IssuerParameters ip = new IssuerParameters(ipJSON);
            ip.Verify();


            /*
             * device provisioning
             */

            // generate a new device
            IDevice device = new VirtualDevice(ip);
            // get the device public key
            GroupElement hd = device.GetDevicePublicKey();


            /*
             *  token issuance
             */

            // specify the attribute values
            byte[][] attributes = new byte[][] {
                    encoding.GetBytes("first attribute value"),
                    encoding.GetBytes("second attribute value"),
                    encoding.GetBytes("third attribute value"),
            };
            // specify the special field values
            byte[] tokenInformation = encoding.GetBytes("token information value");
            byte[] proverInformation = encoding.GetBytes("prover information value");
            // specify the number of tokens to issue
            int numberOfTokens = 5;

            UProveKeyAndToken[] upkt = IssueUProveTokens(ikap, ip, attributes, numberOfTokens, tokenInformation, proverInformation);


            /*
             *  token presentation
             */

            // the indices of disclosed attributes
            int[] disclosed = new int[] { 2 };
            // the application-specific messages that the prover and device will sign, respectively. Typically this 
            // is a nonce combined with any application-specific transaction data to be signed.
            byte[] message = encoding.GetBytes("message");
            byte[] deviceMessage = encoding.GetBytes("message for device");

            PresentUProveToken(ip, upkt[0], attributes, disclosed, null, message, null, device, deviceMessage);

            WriteLine("Sample completed.\n*************************************************************\n");
        }
 public void Verify(IssuerParameters ip, int[] disclosed, byte[] message, byte[] messageD, UProveToken upt)
 {
     GroupElement gs = null;
     Verify(ip, disclosed, null, 0, gs, message, messageD, upt);
 }
        private static CommitmentPrivateValues PresentUProveToken(IssuerParameters ip, UProveKeyAndToken upkt, byte[][] attributes, int[] disclosed, int[] committed, byte[] message, byte[] scope, IDevice device, byte[] deviceMessage)
        {
            WriteLine("Presenting one token");
            // the returned commitment randomizer (to be used by an external proof module)
            CommitmentPrivateValues cpv;

            // generate the presentation proof
            string token = ip.Serialize<UProveToken>(upkt.Token);
            ProverPresentationProtocolParameters pppp = new ProverPresentationProtocolParameters(ip, disclosed, message, upkt, attributes);
            pppp.Committed = committed;
            // if a scope is defined, we use the first attribute to derive a scope exclusive pseudonym            
            pppp.PseudonymAttributeIndex = (scope == null ? 0 : 1);
            pppp.PseudonymScope = scope;
            if (device != null)
            {
                pppp.SetDeviceData(deviceMessage, device.GetPresentationContext());
            }
            pppp.KeyAndToken = upkt;
            pppp.Attributes = attributes;
            string proof = ip.Serialize<PresentationProof>(PresentationProof.Generate(pppp, out cpv));

            // verify the presentation proof
            VerifierPresentationProtocolParameters vppp = new VerifierPresentationProtocolParameters(ip, disclosed, message, ip.Deserialize<UProveToken>(token));
            vppp.Committed = committed;
            // if a scope is defined, we use the first attribute to derive a scope exclusive pseudonym            
            vppp.PseudonymAttributeIndex = (scope == null ? 0 : 1);
            vppp.PseudonymScope = scope;
            vppp.DeviceMessage = deviceMessage;
            ip.Deserialize<PresentationProof>(proof).Verify(vppp);

            return cpv;
        }
 public void Verify(IssuerParameters ip, int[] disclosed, int[] committed, int pseudonymAttribIndex, byte[] pseudonymScope, byte[] message, byte[] messageD, UProveToken upt)
 {
     GroupElement gs = ProtocolHelper.GenerateScopeElement(ip.Gq, pseudonymScope);
     Verify(ip, disclosed, committed, pseudonymAttribIndex, gs, message, messageD, upt);
 }
    public static UProveToken convertUProveTokenComposite(IssuerParameters ip, UProveTokenComposite utc)
    {
      UProveToken up = new UProveToken();

      up.H = ip.Gq.CreateGroupElement(utc.H);
      up.IsDeviceProtected = utc.IsDeviceProtected;
      up.PI = utc.PI;
      up.SigmaCPrime = new BigInteger(1, utc.SigmaCPrime);
      up.SigmaRPrime = new BigInteger(1, utc.SigmaRPrime);
      up.SigmaZPrime = ip.Gq.CreateGroupElement(utc.SigmaZPrime);
      up.TI = utc.TI;
      up.Uidp = utc.Uidp;

      return up;
    }
    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;
    }
        /// <summary>
        /// Generates a presentation proof including optionally presenting a pseudonym, creating attribute commitments, and passing pre-generated random values.
        /// </summary>
        /// <param name="ip">The issuer parameters corresponding to <code>upkt</code>.</param>
        /// <param name="disclosed">An ordered array of disclosed attribute indices.</param>
        /// <param name="committed">An ordered array of committed attribute indices.</param>
        /// <param name="pseudonymAttribIndex">Index of the attribute used to create a scope-exclusive pseudonym, or 0 if no pseudonym is to be presented. The index must not be part of the disclosed attributes.</param>
        /// <param name="gs">The pseudonym scope element, or null if no pseudonym is to be presented.</param>
        /// <param name="message">The presentation message.</param>
        /// <param name="messageD">The message for the Device, or null.</param>
        /// <param name="deviceContext">The active device context, if token is device-protected, or null.</param>
        /// <param name="upkt">The U-Proke key and token.</param>
        /// <param name="attributes">The token attributes.</param>
        /// <param name="preGenW">Optional pregenerated random data for the proof generation.</param>
        /// <param name="cpv">Returned commitment private values if commitments are computed.</param>
        /// <returns>A presentation proof.</returns>
        internal static PresentationProof Generate(IssuerParameters ip, int[] disclosed, int[] committed, int pseudonymAttribIndex, GroupElement gs, byte[] message, byte[] messageD, IDevicePresentationContext deviceContext, UProveKeyAndToken upkt, byte[][] attributes, ProofGenerationRandomData preGenW, out CommitmentPrivateValues cpv)
        {
            if (upkt.Token.IsDeviceProtected && deviceContext == null)
            {
                throw new ArgumentNullException("Device context is not initialized");
            }
            bool generateCommitments = (committed != null && committed.Length > 0);
            FieldZqElement[] tildeO = null;

            // make sure disclosed and committed lists are sorted
            if (disclosed == null)
            {
                // can't be null later, so make it an empty array
                disclosed = new int[] { };
            }
            Array.Sort(disclosed);
            if (generateCommitments)
            {
                Array.Sort(committed);
            }

            int n = 0;
            if (ip.E != null)
                n = ip.E.Length;

            bool presentPseudonym = false;

            if (gs != null)
            {
                if (pseudonymAttribIndex < 1 || (pseudonymAttribIndex > n && pseudonymAttribIndex != DeviceAttributeIndex))
                {
                    throw new ArgumentException("pseudonymAttribIndex must be between 1 and " + n + " (inclusive)");
                }
                if (disclosed.Contains(pseudonymAttribIndex))
                {
                    throw new ArgumentException("pseudonymAttribIndex cannot be in the disclosed attribute array");
                }
                presentPseudonym = true;
            }
            else if (pseudonymAttribIndex > 0)
            {
                throw new ArgumentNullException("gs is null");
            }
            else
            {
                pseudonymAttribIndex = 0;
            }

            Group Gq = ip.Gq;
            FieldZq Zq = ip.Zq;

            FieldZqElement xt = ProtocolHelper.ComputeXt(ip, upkt.Token.TI, upkt.Token.IsDeviceProtected);
            ProofGenerationRandomData random;
            if (preGenW == null)
            {
                random = ProofGenerationRandomData.Generate(n - disclosed.Length, generateCommitments ? committed.Length : 0, Zq, upkt.Token.IsDeviceProtected);
            }
            else
            {
                random = preGenW;
            }

            FieldZqElement[] x = new FieldZqElement[n];
            GroupElement temp = upkt.Token.H.Exponentiate(random.W0);
            int uIndex = 0;
            int dIndex = 0;
            int cIndex = 0;
            PresentationProof proof = new PresentationProof();
            proof.DisclosedAttributes = new byte[disclosed.Length][];
            int pseudonymRandomizerIndex = 0;
            if (generateCommitments)
            {
                proof.Commitments = new CommitmentValues[committed.Length];
                tildeO = new FieldZqElement[committed.Length];
            }
            HashFunction hash = ip.HashFunction;
            for (int i = 0; i < n; i++)
            {
                x[i] = ProtocolHelper.ComputeXi(ip, i, attributes[i]);
                if (!disclosed.Contains(i + 1))
                {
                    temp = temp * ip.G[i + 1].Exponentiate(random.W[uIndex]);
                    if (presentPseudonym)
                    {
                        if (pseudonymAttribIndex == (i + 1))
                        {
                            pseudonymRandomizerIndex = uIndex;
                        }
                    }

                    if (generateCommitments && committed.Contains(i + 1))
                    {
                        GroupElement tildeC = ip.Gq.G.Exponentiate(x[i]) * ip.G[1].Exponentiate(random.TildeO[cIndex]);
                        tildeO[cIndex] = random.TildeO[cIndex];
                        GroupElement temp2 = ip.Gq.G.Exponentiate(random.W[uIndex]) * ip.G[1].Exponentiate(random.TildeW[cIndex]);
                        hash.Hash(temp2);
                        byte[] tildeA = hash.Digest;
                        proof.Commitments[cIndex] = new CommitmentValues(tildeC, tildeA, null);

                        cIndex++;
                    }

                    uIndex++;
                }
                else if (generateCommitments && committed.Contains(i + 1))
                {
                    throw new ArgumentException("attribute " + (i + 1) + " cannot be both disclosed and committed");
                }
                else
                {
                    proof.DisclosedAttributes[dIndex] = attributes[i];
                    dIndex++;
                }
            }
            if (upkt.Token.IsDeviceProtected)
            {
                GroupElement ad;
                // pseudonym computed by device
                if (presentPseudonym && pseudonymAttribIndex == DeviceAttributeIndex)
                {
                    GroupElement apPrime;
                    GroupElement Ps;
                    ad = deviceContext.GetInitialWitnessesAndPseudonym(gs, out apPrime, out Ps);
                    hash.Hash(apPrime * gs.Exponentiate(random.Wd));
                    proof.Ap = hash.Digest;
                    proof.Ps = Ps;
                }
                else
                {
                    ad = deviceContext.GetInitialWitness();
                }
                temp = temp * ip.Gd.Exponentiate(random.Wd) * ad;
            }
            hash.Hash(temp);
            proof.a = hash.Digest;

            // pseudonym derived from one token attribute
            if (presentPseudonym && pseudonymAttribIndex != DeviceAttributeIndex)
            {
                hash.Hash(gs.Exponentiate(random.W[pseudonymRandomizerIndex]));
                proof.Ap = hash.Digest;
                proof.Ps = gs.Exponentiate(x[pseudonymAttribIndex - 1]);
            }

            byte[] mdPrime;
            FieldZqElement c = ProtocolHelper.GenerateChallenge(ip, upkt.Token, proof.a, pseudonymAttribIndex, proof.ap, proof.Ps, message, messageD, disclosed, GetDisclosedX(disclosed, x), committed, proof.Commitments, out mdPrime);
            proof.r = new FieldZqElement[1 + n - disclosed.Length + (upkt.Token.IsDeviceProtected ? 1 : 0)]; // r_0, {r_i} for undisclosed i, r_d
            proof.r[0] = c * upkt.PrivateKey + random.W0;
            uIndex = 1;
            for (int i = 1; i <= n; i++)
            {
                if (!disclosed.Contains(i))
                {
                    proof.r[uIndex] = c.Negate() * x[i - 1] + random.W[uIndex - 1];
                    uIndex++;
                }
            }
            if (upkt.Token.IsDeviceProtected)
            {
                proof.r[proof.r.Length - 1] = deviceContext.GetDeviceResponse(messageD, mdPrime, ip.HashFunctionOID) + random.Wd;
            }
            if (generateCommitments)
            {
                for (int i = 0; i < committed.Length; i++)
                {
                    proof.Commitments[i].TildeR = c.Negate() * random.TildeO[i] + random.TildeW[i];
                }
            }

            random.Clear();
            cpv = new CommitmentPrivateValues(tildeO);
            return proof;
        }
 /// <summary>
 /// Computes the U-Prove token identifier.
 /// </summary>
 /// <param name="ip">The issuer parameters associated with <code>upt</code>.</param>
 /// <param name="upt">The U-Prove token from which to compute the identifier.</param>
 /// <returns></returns>
 public static byte[] ComputeTokenID(IssuerParameters ip, UProveToken upt)
 {
     HashFunction hash = ip.HashFunction;
     hash.Hash(upt.H);
     hash.Hash(upt.SigmaZPrime);
     hash.Hash(upt.SigmaCPrime);
     hash.Hash(upt.SigmaRPrime);
     return hash.Digest;
 }
 /// <summary>
 /// Convert a base64 string to a FieldElement using FieldZq from a particular IssuerParameters object.
 /// </summary>
 /// <param name="encodedString">The encoded string to convert.</param>
 /// <param name="issuerParameters">The IssuerParameters object.</param>
 /// <returns>The converted object.</returns>
 public static FieldZqElement ToFieldElement(this String encodedString, IssuerParameters issuerParameters)
 {
     if (encodedString == null) return null;
     if (issuerParameters == null) throw new ArgumentNullException("issuerParameters");
     return issuerParameters.Zq.GetElement(Convert.FromBase64String(encodedString));
 }
        /// <summary>
        /// This sample illustrates how to issue and present software-only U-Prove tokens.
        /// </summary>
        public static void SoftwareOnlySample()
        {
            WriteLine("U-Prove SDK Sample");
            
            /*
             *  issuer setup
             */
            IssuerKeyAndParameters ikap = SetupUProveIssuer("sample software-only issuer", 3);
            string privateKeyBase64 = ikap.PrivateKey.ToBase64String(); // this needs to be stored securely
            string ipJSON = ikap.IssuerParameters.Serialize();

            // the IssuerParameters instance needs to be distributed to the Prover and Verifier.
            // Each needs to verify the parameters before using them
            IssuerParameters ip = new IssuerParameters(ipJSON);
            ip.Verify();

            /*
             *  token issuance
             */
            // specify the attribute values agreed to by the Issuer and Prover
            byte[][] attributes = new byte[][] {
                    encoding.GetBytes("first attribute value"),
                    encoding.GetBytes("second attribute value"),
                    encoding.GetBytes("third attribute value")
            };
            // specify the special field values
            byte[] tokenInformation = encoding.GetBytes("token information value");
            byte[] proverInformation = encoding.GetBytes("prover information value");
            // specify the number of tokens to issue
            int numberOfTokens = 5;

            UProveKeyAndToken[] upkt = IssueUProveTokens(new IssuerKeyAndParameters(privateKeyBase64, ipJSON), ip, attributes, numberOfTokens, tokenInformation, proverInformation);           

            /*
             *  token presentation
             */
            // the indices of disclosed attributes
            int[] disclosed = new int[] { 2 };
            // the indices of the committed attributes (used by protocol extensions)
            int[] committed = null;
            // 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("message");
            // 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 = encoding.GetBytes("verifier scope");

            PresentUProveToken(ip, upkt[0], attributes, disclosed, committed, message, scope, null, null);

            WriteLine("Sample completed.\n*************************************************************\n");
        }
 /// <summary>
 /// Constructs a new VirtualDevice instance.
 /// </summary>
 /// <param name="ip">The Issuer parameters.</param>
 public VirtualDevice(IssuerParameters ip) : this(ip, null, null)
 {}
 /// <summary>
 /// Constructs a new VirtualDevice instance.
 /// </summary>
 /// <param name="ip">The Issuer parameters.</param>
 /// <param name="xd">The device private key.</param>
 public VirtualDevice(IssuerParameters ip, FieldZqElement xd)
     : this(ip, xd, null)
 {}
 /// <summary>
 /// Constructs a new VirtualDevice instance.
 /// </summary>
 /// <param name="ip">The Issuer parameters.</param>
 /// <param name="xd">The device private key.</param>
 /// <param name="preGenWdPrime">The pregenerated w_d prime value (for one presentation)</param>
 public VirtualDevice(IssuerParameters ip, FieldZqElement xd, FieldZqElement preGenWdPrime)
     : this(ip.Gq, ip.Gd, ip.Zq, xd, preGenWdPrime)
 {
 }
        public void TestEndToEnd()
        {
            Random random = new Random();
            int attributeLength = 10;
            foreach (GroupType groupConstruction in groupConstructions)
            {
                foreach (string hashFunction in supportedHashFunctions)
                {
                    //Console.WriteLine("Hash = " + hashFunction);
                    for (int numberOfAttribs = 0; numberOfAttribs <= 3; numberOfAttribs++)
                    {
                        //Console.WriteLine("NumberOfAttribs = " + numberOfAttribs);
                        for (int e = 0; e <= 1; e++)
                        {
                            foreach (bool supportDevice in new bool[] { false, true })
                            {
                                // Issuer setup
                                IssuerSetupParameters isp = new IssuerSetupParameters();
                                isp.GroupConstruction = groupConstruction;
                                isp.UidP = encoding.GetBytes("unique UID");
                                isp.UidH = hashFunction;
                                isp.E = new byte[numberOfAttribs];
                                for (int i = 0; i < numberOfAttribs; i++)
                                {
                                    isp.E[i] = (byte)e;
                                }
                                isp.S = encoding.GetBytes("specification");
                                IssuerKeyAndParameters ikap = isp.Generate(supportDevice);
                                IssuerParameters ip = ikap.IssuerParameters;
                                ip.Verify();

                                IDevice device = null;
                                GroupElement hd = null;
                                if (supportDevice)
                                {
                                    device = new VirtualDevice(ip);
                                    hd = device.GetDevicePublicKey();
                                }

                                // Issuance
                                byte[][] attributes = new byte[numberOfAttribs][];
                                for (int index = 0; index < numberOfAttribs; index++)
                                {
                                    attributes[index] = new byte[attributeLength];
                                    random.NextBytes(attributes[index]);
                                }
                                byte[] tokenInformation = encoding.GetBytes("token information");
                                byte[] proverInformation = encoding.GetBytes("prover information");
                                int numberOfTokens = (int)Math.Pow(2, numberOfAttribs);

                                IssuerProtocolParameters ipp = new IssuerProtocolParameters(ikap);
                                ipp.Attributes = attributes;
                                ipp.NumberOfTokens = numberOfTokens;
                                ipp.TokenInformation = tokenInformation;
                                ipp.DevicePublicKey = hd;
                                Issuer issuer = ipp.CreateIssuer();
                                FirstIssuanceMessage msg1 = issuer.GenerateFirstMessage();
                                ProverProtocolParameters ppp = new ProverProtocolParameters(ip);
                                ppp.Attributes = attributes;
                                ppp.NumberOfTokens = numberOfTokens;
                                ppp.TokenInformation = tokenInformation;
                                ppp.ProverInformation = proverInformation;
                                ppp.DevicePublicKey = hd;
                                Prover prover = ppp.CreateProver();
                                SecondIssuanceMessage msg2 = prover.GenerateSecondMessage(msg1);
                                ThirdIssuanceMessage msg3 = issuer.GenerateThirdMessage(msg2);
                                // issue token
                                UProveKeyAndToken[] upkt = prover.GenerateTokens(msg3);

                                // Presentation
                                for (int i = 0; i < numberOfTokens; i++)
                                {
                                    List<int> disclosedList = new List<int>();
                                    //Console.Write("Disclosed list = ");
                                    for (int index = 0; index < numberOfAttribs; index++)
                                    {
                                        if ((((int)Math.Pow(2, index)) & i) != 0)
                                        {
                                            //Console.Write((index + 1) + ", ");
                                            disclosedList.Add(index + 1);
                                        }
                                    }
                                    //Console.WriteLine();

                                    int[] disclosed = disclosedList.ToArray();
                                    byte[] message = encoding.GetBytes("message");
                                    byte[] deviceMessage = null;
                                    IDevicePresentationContext deviceContext = null;
                                    if (supportDevice)
                                    {
                                        deviceMessage = encoding.GetBytes("message");
                                        deviceContext = device.GetPresentationContext();
                                    }

                                    // generate the presentation proof
                                    PresentationProof proof = PresentationProof.Generate(ip, disclosed, message, deviceMessage, deviceContext, upkt[i], attributes);

                                    // verify the presentation proof
                                    proof.Verify(ip, disclosed, message, deviceMessage, upkt[i].Token);

                                    //
                                    // negative cases
                                    //
                                    if (numberOfAttribs > 0)
                                    {
                                        // modify issuer params (change specification);
                                        IssuerParameters ip2 = new IssuerParameters(ip.UidP, ip.Gq, ip.UidH, ip.G, ip.Gd, ip.E, ip.S, ip.UsesRecommendedParameters);
                                        ip2.S = encoding.GetBytes("wrong issuer params");
                                        try { proof.Verify(ip2, disclosed, message, null, upkt[i].Token); Assert.Fail(); }
                                        catch (InvalidUProveArtifactException) { }

                                        // modify disclosed list
                                        int[] disclosed2;
                                        if (disclosed.Length == 0)
                                        {
                                            disclosed2 = new int[] { 1 };
                                        }
                                        else
                                        {
                                            disclosed2 = new int[] { };
                                        }
                                        try { proof.Verify(ip, disclosed2, message, deviceMessage, upkt[i].Token); Assert.Fail(); }
                                        catch (InvalidUProveArtifactException) { }

                                        // modify message
                                        try { proof.Verify(ip, disclosed, encoding.GetBytes("wrong message"), deviceMessage, upkt[i].Token); Assert.Fail(); }
                                        catch (InvalidUProveArtifactException) { }

                                        // modify token
                                        try { proof.Verify(ip, disclosed, message, deviceMessage, upkt[(i + 1) % numberOfTokens].Token); Assert.Fail(); }
                                        catch (InvalidUProveArtifactException) { }

                                        // modify proof
                                        proof.A = encoding.GetBytes("wrong proof");
                                        try { proof.Verify(ip, disclosed, message, deviceMessage, upkt[i].Token); Assert.Fail(); }
                                        catch (InvalidUProveArtifactException) { }
                                    }
                                }
                            }
                        }
                    }
                }
            }
        }
 /// <summary>
 /// Convert a base64 string to a GroupElement using Gq from an IssuerParameters object.
 /// </summary>
 /// <param name="encodedString">The encoded string to convert.</param>
 /// <param name="issuerParameters">The issuer parameters object to use for conversion.</param>
 /// <returns>The converted object.</returns>
 public static GroupElement ToGroupElement(this String encodedString, IssuerParameters issuerParameters)
 {
     if (encodedString == null) return null;
     if (issuerParameters == null) throw new ArgumentNullException("issuerParameters");
     return issuerParameters.Gq.CreateGroupElement(encodedString.ToByteArray());
 }