Example #1
0
        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();
            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;
        }
    public SecondIssuanceMessageInfo SecondMessage(SecondIssuanceMessageSpec spec)
    {
      if (spec.IssuerParameter == null)
      {
        ApiArgumentFault fault = new ApiArgumentFault();
        fault.Details = "Issuer with unique ID was found";
        fault.Argument = "IssuerSetupParametersSpec.ID";
        fault.ArgumentValue = spec.IssuerParameter.Serialize();
        throw new FaultException<ApiArgumentFault>(fault);
      }
      ProverProtocolParameters pProtoParam = new ProverProtocolParameters(spec.IssuerParameter);
      pProtoParam.NumberOfTokens = spec.NumberOfTokens;
      if (!String.IsNullOrWhiteSpace(spec.TokenInfomation))
      {
        pProtoParam.TokenInformation = ExtensionMethods.ToByteArray(spec.TokenInfomation);
      }

      if (!String.IsNullOrWhiteSpace(spec.Gamma))
      {

        pProtoParam.Gamma = ExtensionMethods.ToGroupElement(spec.Gamma, spec.IssuerParameter);
      }

      if (!String.IsNullOrWhiteSpace(spec.DevicePublicKey))
      {
        pProtoParam.DevicePublicKey = ExtensionMethods.ToGroupElement(spec.DevicePublicKey, spec.IssuerParameter);
      }

      if (!String.IsNullOrWhiteSpace(spec.ProverInfomation))
      {
        pProtoParam.ProverInformation = ExtensionMethods.ToByteArray(spec.ProverInfomation);
      }

      if (spec.RandomData != null)
      {
        pProtoParam.ProverRandomData = spec.RandomData;
      }
      if (spec.BatchSecurityLevel > 0)
      {
        pProtoParam.BatchValidationSecurityLevel = spec.BatchSecurityLevel;
      }
      pProtoParam.Validate();
      Prover prover = pProtoParam.CreateProver();

      SecondIssuanceMessage secondMessage = prover.GenerateSecondMessage(spec.FirstMessage);
      PostSecondMessageState postSecondMessageState = prover.ExportPostSecondMessageState();

      SecondIssuanceMessageInfo simInfo = new SecondIssuanceMessageInfo();
      simInfo.PostSecondMessageState = postSecondMessageState;
      simInfo.SecondMessage = secondMessage;

      Guid issuerInstance = Guid.NewGuid();
      simInfo.ProverInstanceID = issuerInstance;
      proverInstanceDB.TryAdd(issuerInstance, new ProverInstanceData(prover));

      return simInfo;
    }
        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 void PseudonymAndCommitmentsTest()
        {
            // 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 = 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.Attributes = attributes;
            ppp.NumberOfTokens = numberOfTokens;
            ppp.TokenInformation = tokenInformation;
            ppp.ProverInformation = proverInformation;
            Prover prover = ppp.CreateProver();
            SecondIssuanceMessage msg2 = prover.GenerateSecondMessage(msg1);
            ThirdIssuanceMessage msg3 = issuer.GenerateThirdMessage(msg2);
            UProveKeyAndToken[] upkt = prover.GenerateTokens(msg3);

            // Pseudonym
            int[] disclosed = new int[0];
            int[] committed = new int[] { 2, 4 };
            byte[] message = encoding.GetBytes("this is the presentation message, this can be a very long message");
            byte[] scope = encoding.GetBytes("scope");
            PresentationProof proof;
            FieldZqElement[] tildeO;

            // Valid presentation
            proof = PresentationProof.Generate(ip, disclosed, committed, 1, scope, message, null, null, upkt[0], attributes, out tildeO);
            proof.Verify(ip, disclosed, committed, 1, scope, message, null, upkt[0].Token);

            // Invalid pseudonym (wrong scope)
            proof = PresentationProof.Generate(ip, disclosed, committed, 1, scope, message, null, null, upkt[0], attributes, out tildeO);
            try { proof.Verify(ip, disclosed, committed, 1, encoding.GetBytes("bad scope"), message, null, upkt[0].Token); Assert.Fail(); }
            catch (InvalidUProveArtifactException) { }

            // Invalid pseudonym (wrong attribute)
            try { proof.Verify(ip, disclosed, committed, 2, scope, message, null, upkt[0].Token); Assert.Fail(); }
            catch (InvalidUProveArtifactException) { }

            // Invalid commitment (null list)
            try { proof.Verify(ip, disclosed, null, 2, scope, message, null, upkt[0].Token); Assert.Fail(); }
            catch (InvalidUProveArtifactException) { }

            // Invalid commitment (wrong committed values)
            try { proof.Verify(ip, disclosed, new int[] { 1, 4 }, 2, scope, message, null, upkt[0].Token); Assert.Fail(); }
            catch (InvalidUProveArtifactException) { }

            // Invalid commitment (wront number of committed values)
            try { proof.Verify(ip, disclosed, new int[] { 1 }, 2, scope, message, null, upkt[0].Token); Assert.Fail(); }
            catch (InvalidUProveArtifactException) { }

            // Invalid commitment (value)
            proof.Commitments[0].TildeA[0]++;
            try { proof.Verify(ip, disclosed, committed, 2, scope, message, null, upkt[0].Token); Assert.Fail(); }
            catch (InvalidUProveArtifactException) { }

            // Ensure tildeO is correct
            GroupElement Cx2 = proof.Commitments[0].TildeC;         // x2 is the first committed attribute
            FieldZqElement x2 = ProtocolHelper.ComputeXi(ip, 1, attributes[1]);       // attributes[] is zero indexed.
            FieldZqElement tildeO2 = tildeO[0];
                    // double check that Cx2 is computed correctly.
            GroupElement Cx2Prime = ip.Gq.G.Exponentiate(x2);
            Cx2Prime = Cx2Prime.Multiply(ip.G[1].Exponentiate(tildeO2));
            Assert.IsTrue(Cx2Prime.Equals(Cx2));

        }
        private void RunFuzzedTest(bool useSubgroupConstruction, string hashFunction, int numberOfAttributes, bool supportDevice, int numberOfTokens, int[] dArray, int[] cArray, int pseudonymIndex)
        {
            // Issuer setup
            IssuerSetupParameters isp = new IssuerSetupParameters();
            isp.GroupConstruction = useSubgroupConstruction ? GroupType.Subgroup : GroupType.ECC;
            isp.UidP = GetRandomBytes(MaxByteArrayLength);
            isp.UidH = hashFunction;
            isp.E = IssuerSetupParameters.GetDefaultEValues(numberOfAttributes);
            isp.S = GetRandomBytes(MaxByteArrayLength);
            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[numberOfAttributes][];
            for (int index = 0; index < numberOfAttributes; index++)
            {
                attributes[index] = GetRandomBytes(MaxByteArrayLength);
            }
            byte[] tokenInformation = GetRandomBytes(MaxByteArrayLength);
            byte[] proverInformation = GetRandomBytes(MaxByteArrayLength);

            IssuerProtocolParameters ipp = new IssuerProtocolParameters(ikap);
            ipp.Attributes = attributes;
            ipp.NumberOfTokens = numberOfTokens;
            ipp.TokenInformation = tokenInformation;
            ipp.DevicePublicKey = hd;
            Issuer issuer = ipp.CreateIssuer();

            string msg1 = ip.Serialize(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();
            string msg2 = ip.Serialize(prover.GenerateSecondMessage(ip.Deserialize<FirstIssuanceMessage>(msg1)));
            string msg3 = ip.Serialize(issuer.GenerateThirdMessage(ip.Deserialize<SecondIssuanceMessage>(msg2)));
            // issue token
            UProveKeyAndToken[] upkt = prover.GenerateTokens(ip.Deserialize<ThirdIssuanceMessage>(msg3));

            // Presentation
            byte[] message = GetRandomBytes(MaxByteArrayLength);
            byte[] deviceMessage = null;
            IDevicePresentationContext deviceContext = null;
            if (supportDevice)
            {
                deviceMessage = GetRandomBytes(MaxByteArrayLength);
                deviceContext = device.GetPresentationContext();
            }
            int tokenIndex = random.Next(upkt.Length);

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

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

        }
        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);
            }
        }
        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) { }
                                    }
                                }
                            }
                        }
                    }
                }
            }
        }
        public void LongTest()
        {
            int numberOfAttribs = 25;
            // Issuer setup
            IssuerSetupParameters isp = new IssuerSetupParameters();
            isp.UidP = new byte[] { 1, 2, 3, 4, 5, 6, 7, 8, 9 };
            isp.E = new byte[numberOfAttribs];
            isp.UseRecommendedParameterSet = true;
            for (int i = 0; i < numberOfAttribs; i++)
            {
                isp.E[i] = (byte) (i%2); // alternate between 0 (direct encoding) and 1 (hash)
            }

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

            // Issuance
            byte[][] attributes = new byte[numberOfAttribs][];
            attributes[0] = new byte[] { 0x00 };
            attributes[1] = null;
            attributes[2] = new byte[] { 0x00 };
            attributes[3] = encoding.GetBytes("This is a very long value that doesn't fit in one attribute, but this is ok since we hash this value");
            for (int index = 4; index < numberOfAttribs; index++)
            {
                // for the rest, we just encode random Zq values
                attributes[index] = ip.Zq.GetRandomElement(false).ToByteArray();
            }
            byte[] tokenInformation = new byte[] { 0x01 };
            byte[] proverInformation = new byte[] { 0x01 };
            int numberOfTokens = 10;

            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.Attributes = attributes;
            ppp.NumberOfTokens = numberOfTokens;
            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
            for (int i = 1; i <= numberOfAttribs; i++)
            {
                // disclose each attribute one by one
                int[] disclosed = new int[] { i };
                byte[] message = encoding.GetBytes("this is the presentation message, this can be a very long message");

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

                // verify the presentation proof
                proof.Verify(ip, disclosed, message, null, upkt[0].Token);
            }


            // Pseudonym
            for (int i = 1; i <= numberOfAttribs; i++)
            {
                // present each attribute as a pseudonym
                int[] disclosed = new int[0];
                byte[] message = encoding.GetBytes("this is the presentation message, this can be a very long message");
                byte[] scope = encoding.GetBytes("scope" + i);
                FieldZqElement[] unused;

                // generate the presentation proof
                PresentationProof proof = PresentationProof.Generate(ip, disclosed, null, i, scope, message, null, null, upkt[0], attributes, out unused);

                // verify the presentation proof
                proof.Verify(ip, disclosed, null, i, scope, message, null, upkt[0].Token);
            }

        }
        public void DevicePseudonymTest()
        {
            // 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(true);
            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 = 1;

            IDevice device = new VirtualDevice(ip);
            GroupElement hd = device.GetDevicePublicKey();

            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);
            UProveKeyAndToken[] upkt = prover.GenerateTokens(msg3);

            // Pseudonym
            int[] disclosed = new int[0];
            byte[] message = encoding.GetBytes("this is the presentation message, this can be a very long message");
            byte[] messageForDevice = encoding.GetBytes("message for Device");
            byte[] scope = encoding.GetBytes("scope");
            PresentationProof proof;
            FieldZqElement[] tildeO;

            // Valid presentation
            IDevicePresentationContext deviceCtx = device.GetPresentationContext();
            proof = PresentationProof.Generate(ip, disclosed, null, PresentationProof.DeviceAttributeIndex, scope, message, messageForDevice, deviceCtx, upkt[0], attributes, out tildeO); 
            proof.Verify(ip, disclosed, null, PresentationProof.DeviceAttributeIndex, scope, message, messageForDevice, upkt[0].Token);

            // Invalid pseudonym (wrong scope)
            deviceCtx = device.GetPresentationContext();
            proof = PresentationProof.Generate(ip, disclosed, null, PresentationProof.DeviceAttributeIndex, scope, message, messageForDevice, deviceCtx, upkt[0], attributes, out tildeO);
            try { proof.Verify(ip, disclosed, null, PresentationProof.DeviceAttributeIndex, encoding.GetBytes("bad scope"), message, messageForDevice, upkt[0].Token); Assert.Fail(); }
            catch (InvalidUProveArtifactException) { }

            // Ensure tildeO is correct, in this case it should be empty because there are no comitted attributes
            Assert.IsTrue(tildeO == null || tildeO.Length == 0);
        }
Example #11
0
        public void TestIssuer()
        {
            byte[][] A = new byte[][] {};
            byte[] TI = null;
            IssuerSetupParameters isp = new IssuerSetupParameters();
            isp.UidP = new byte[] { 0 };
            isp.E = new byte[] { 0 };
            IssuerKeyAndParameters ikap = isp.Generate();
            IssuerProtocolParameters ipp;

            try { ipp = new IssuerProtocolParameters(null); Assert.Fail(); } catch (ArgumentNullException) { }
            try 
            {
                ipp = new IssuerProtocolParameters(ikap);
                ipp.Attributes = A;
                ipp.NumberOfTokens = -1;
                ipp.TokenInformation = TI;
                ipp.Validate();
                Assert.Fail();
            } catch (ArgumentException) { }
            try
            {
                ipp = new IssuerProtocolParameters(ikap);
                ipp.Attributes = A;
                ipp.NumberOfTokens = 0;
                ipp.TokenInformation = TI;
                ipp.Validate();
                Assert.Fail(); 
            } catch (ArgumentException) { }
            ipp = new IssuerProtocolParameters(ikap);
            ipp.Attributes = A;
            ipp.NumberOfTokens = 1;
            ipp.TokenInformation = TI;
            ipp.Validate();
            Issuer issuer = ipp.CreateIssuer();

            FirstIssuanceMessage msg1 = null;
            SecondIssuanceMessage msg2 = null;
            ThirdIssuanceMessage msg3 = null;
            
            try { msg3 = issuer.GenerateThirdMessage(msg2); Assert.Fail(); } catch (InvalidOperationException) { }
            msg1 = issuer.GenerateFirstMessage();
            try { msg1 = issuer.GenerateFirstMessage(); Assert.Fail(); } catch (InvalidOperationException) { }
            msg2 = new ProverProtocolParameters(ikap.IssuerParameters).CreateProver().GenerateSecondMessage(msg1);
            msg3 = issuer.GenerateThirdMessage(msg2);
            try { msg3 = issuer.GenerateThirdMessage(msg2); Assert.Fail(); } catch (InvalidOperationException) { }
        }
        public void ProtocolTest()
        {
            Stopwatch sw = new Stopwatch();
            sw.Start();
            bool[] bools = new bool[] { true, false };
            foreach (bool isSubgroupConstruction in bools)
            {
                foreach (bool supportDevice in bools)
                {
                    var vectors =
                        supportDevice ?
                        (isSubgroupConstruction ?
                            GetTestVectors("testvectorssubgroup_Device_doc.txt")
                            :
                            GetTestVectors("testvectorsEC_Device_doc.txt"))
                        :
                        (isSubgroupConstruction ?
                            GetTestVectors("testvectorssubgroup_doc.txt")
                            :
                            GetTestVectors("testvectorsEC_doc.txt"));

                    IssuerKeyAndParameters ikap = LoadIssuerKeyAndParameters(isSubgroupConstruction, vectors["GroupName"], supportDevice, vectors);
                    FieldZq Zq = ikap.IssuerParameters.Zq;
                    // replace random y0/g0 with test vector values
                    ikap.PrivateKey = Zq.GetElement(HexToBytes(vectors["y0"]));
                    ikap.IssuerParameters.G[0] = CreateGroupElement(ikap.IssuerParameters.Gq, vectors["g0"]);
                    Assert.AreEqual(ikap.IssuerParameters.G[0], ikap.IssuerParameters.Gq.G.Exponentiate(ikap.PrivateKey), "g0 computation");
                    IssuerParameters ip = ikap.IssuerParameters;
                    ip.Verify();

                    /*
                     * issuance
                     */

                    byte[][] A = new byte[][] {
                        HexToBytes(vectors["A1"]), 
                        HexToBytes(vectors["A2"]),
                        HexToBytes(vectors["A3"]),
                        HexToBytes(vectors["A4"]),
                        HexToBytes(vectors["A5"])
                        };

                    Assert.AreEqual(Zq.GetElement(HexToBytes(vectors["x1"])), ProtocolHelper.ComputeXi(ip, 0, A[0]), "x1");
                    Assert.AreEqual(Zq.GetElement(HexToBytes(vectors["x2"])), ProtocolHelper.ComputeXi(ip, 1, A[1]), "x2");
                    Assert.AreEqual(Zq.GetElement(HexToBytes(vectors["x3"])), ProtocolHelper.ComputeXi(ip, 2, A[2]), "x3");
                    Assert.AreEqual(Zq.GetElement(HexToBytes(vectors["x4"])), ProtocolHelper.ComputeXi(ip, 3, A[3]), "x4");
                    Assert.AreEqual(Zq.GetElement(HexToBytes(vectors["x5"])), ProtocolHelper.ComputeXi(ip, 4, A[4]), "x5");

                    byte[] TI = HexToBytes(vectors["TI"]);
                    Assert.IsTrue(HexToBytes(vectors["P"]).SequenceEqual(ip.Digest(supportDevice)), "P");
                    Assert.AreEqual(Zq.GetElement(HexToBytes(vectors["xt"])), ProtocolHelper.ComputeXt(ip, TI, supportDevice), "xt");

                    IDevice device = null;
                    GroupElement hd = null;
                    if (supportDevice)
                    {
                        device = new VirtualDevice(ip, Zq.GetElement(HexToBytes(vectors["xd"])), Zq.GetElement(HexToBytes(vectors["wdPrime"])));
                        IDevicePresentationContext context = device.GetPresentationContext();
                        // Test device responses
                        Assert.AreEqual(CreateGroupElement(ip.Gq, vectors["hd"]), device.GetDevicePublicKey(), "hd");
                        Assert.AreEqual(CreateGroupElement(ip.Gq, vectors["ad"]), context.GetInitialWitness(), "ad");
                        Assert.AreEqual(Zq.GetElement(HexToBytes(vectors["rdPrime"])), context.GetDeviceResponse(HexToBytes(vectors["md"]), HexToBytes(vectors["mdPrime"]), ip.HashFunctionOID), "rdPrime");
                        hd = CreateGroupElement(ip.Gq, vectors["hd"]);
                    }

                    IssuerProtocolParameters ipp = new IssuerProtocolParameters(ikap);
                    ipp.Attributes = A;
                    ipp.NumberOfTokens = 1;
                    ipp.TokenInformation = TI;
                    ipp.DevicePublicKey = hd;
                    ipp.PreGeneratedW = new FieldZqElement[] { Zq.GetElement(HexToBytes(vectors["w"])) };
                    Issuer issuer = ipp.CreateIssuer();
                    byte[] PI = HexToBytes(vectors["PI"]);

                    ProverProtocolParameters ppp = new ProverProtocolParameters(ip);
                    ppp.Attributes = A;
                    ppp.NumberOfTokens = 1;
                    ppp.TokenInformation = TI;
                    ppp.ProverInformation = PI;
                    ppp.DevicePublicKey = hd;
                    ppp.ProverRandomData = new ProverRandomData(
                        new FieldZqElement[] { Zq.GetElement(HexToBytes(vectors["alpha"])) },
                        new FieldZqElement[] { Zq.GetElement(HexToBytes(vectors["beta1"])) },
                        new FieldZqElement[] { Zq.GetElement(HexToBytes(vectors["beta2"])) });
                    Prover prover = ppp.CreateProver();

                    FirstIssuanceMessage msg1 = issuer.GenerateFirstMessage();
                    Assert.AreEqual(msg1.sigmaZ, CreateGroupElement(ip.Gq, vectors["sigmaZ"]), "sigmaZ");
                    Assert.AreEqual(msg1.sigmaA[0], CreateGroupElement(ip.Gq, vectors["sigmaA"]), "sigmaA");
                    Assert.AreEqual(msg1.sigmaB[0], CreateGroupElement(ip.Gq, vectors["sigmaB"]), "sigmaB");

                    SecondIssuanceMessage msg2 = prover.GenerateSecondMessage(msg1);
                    Assert.AreEqual(msg2.sigmaC[0], Zq.GetElement(HexToBytes(vectors["sigmaC"])), "sigmaC");

                    ThirdIssuanceMessage msg3 = issuer.GenerateThirdMessage(msg2);
                    Assert.AreEqual(msg3.sigmaR[0], Zq.GetElement(HexToBytes(vectors["sigmaR"])), "sigmaR");

                    UProveKeyAndToken[] upkt = prover.GenerateTokens(msg3);
                    Assert.AreEqual(upkt[0].PrivateKey, Zq.GetElement(HexToBytes(vectors["alphaInverse"])), "alphaInverse");
                    UProveToken token = upkt[0].Token;
                    Assert.AreEqual(token.H, CreateGroupElement(ip.Gq, vectors["h"]), "h");
                    Assert.AreEqual(token.SigmaZPrime, CreateGroupElement(ip.Gq, vectors["sigmaZPrime"]), "sigmaZPrime");
                    Assert.AreEqual(token.SigmaCPrime, Zq.GetElement(HexToBytes(vectors["sigmaCPrime"])), "sigmaCPrime");
                    Assert.AreEqual(token.SigmaRPrime, Zq.GetElement(HexToBytes(vectors["sigmaRPrime"])), "sigmaRPrime");
                    Assert.IsTrue(HexToBytes(vectors["UIDt"]).SequenceEqual(ProtocolHelper.ComputeTokenID(ip, token)), "UIDt");
                    Assert.IsTrue(supportDevice == token.IsDeviceProtected);

                    /*
                     * presentation
                     */

                    int[] disclosed = Array.ConvertAll<string, int>(vectors["D"].Split(','), new Converter<string, int>(stringToInt));
                    int[] committed = Array.ConvertAll<string, int>(vectors["C"].Split(','), new Converter<string, int>(stringToInt));
                    byte[] m = HexToBytes(vectors["m"]);
                    byte[] md = null;
                    IDevicePresentationContext deviceContext = null;
                    if (supportDevice)
                    {
                        md = HexToBytes(vectors["md"]);
                        deviceContext = device.GetPresentationContext();
                    }
                    int p;
                    if (!int.TryParse(vectors["p"], out p))
                    {
                        p = PresentationProof.DeviceAttributeIndex;
                    }
                    byte[] s = HexToBytes(vectors["s"]);
                    int commitmentIndex = committed[0];
                    ProverPresentationProtocolParameters pppp = new ProverPresentationProtocolParameters(ip, disclosed, m, upkt[0], A);
                    pppp.Committed = committed;
                    pppp.PseudonymAttributeIndex = p;
                    pppp.PseudonymScope = s;
                    pppp.DeviceMessage = md;
                    pppp.DeviceContext = deviceContext;
                    pppp.RandomData = new ProofGenerationRandomData(
                            Zq.GetElement(HexToBytes(vectors["w0"])),
                            new FieldZqElement[] { 
                                Zq.GetElement(HexToBytes(vectors["w1"])), 
                                Zq.GetElement(HexToBytes(vectors["w3"])),
                                Zq.GetElement(HexToBytes(vectors["w4"]))
                            },
                            supportDevice ? Zq.GetElement(HexToBytes(vectors["wd"])) : null,
                            new FieldZqElement[] { 
                                Zq.GetElement(HexToBytes(vectors["tildeO" + commitmentIndex])), 
                            },
                            new FieldZqElement[] { 
                                Zq.GetElement(HexToBytes(vectors["tildeW" + commitmentIndex]))
                            });
                    CommitmentPrivateValues cpv;
                    PresentationProof proof = PresentationProof.Generate(pppp, out cpv);
                    Assert.IsTrue(HexToBytes(vectors["a"]).SequenceEqual(proof.A), "a");
                    Assert.AreEqual(ProtocolHelper.GenerateScopeElement(ip.Gq, s), CreateGroupElement(ip.Gq, vectors["gs"]));
                    Assert.IsTrue(HexToBytes(vectors["ap"]).SequenceEqual(proof.Ap), "ap");
                    Assert.AreEqual(proof.Ps, CreateGroupElement(ip.Gq, vectors["Ps"]), "Ps");
                    Assert.IsTrue(HexToBytes(vectors["A2"]).SequenceEqual(proof.DisclosedAttributes[0]), "A2");
                    Assert.IsTrue(HexToBytes(vectors["A5"]).SequenceEqual(proof.DisclosedAttributes[1]), "A5");
                    Assert.AreEqual(proof.R[0], Zq.GetElement(HexToBytes(vectors["r0"])), "r0");
                    Assert.AreEqual(proof.R[1], Zq.GetElement(HexToBytes(vectors["r1"])), "r1");
                    Assert.AreEqual(proof.R[2], Zq.GetElement(HexToBytes(vectors["r3"])), "r3");
                    Assert.AreEqual(proof.R[3], Zq.GetElement(HexToBytes(vectors["r4"])), "r4");
                    if (supportDevice)
                    {
                        Assert.AreEqual(proof.R[4], Zq.GetElement(HexToBytes(vectors["rd"])), "rd");
                    }
                    Assert.AreEqual(proof.Commitments[0].TildeR, Zq.GetElement(HexToBytes(vectors["tildeR" + commitmentIndex])), "tildeR" + commitmentIndex);
                    Assert.IsTrue(cpv.TildeO.Length == 1);
                    Assert.AreEqual(cpv.TildeO[0], Zq.GetElement(HexToBytes(vectors["tildeO" + commitmentIndex])), "tildeO" + commitmentIndex);
                    VerifierPresentationProtocolParameters vppp = new VerifierPresentationProtocolParameters(ip, disclosed, m, upkt[0].Token);
                    vppp.Committed = committed;
                    vppp.PseudonymAttributeIndex = p;
                    vppp.PseudonymScope = s;
                    vppp.DeviceMessage = md;
                    proof.Verify(vppp);

                }
            }

            sw.Stop();
            Debug.WriteLine("Protocol Test Elapsed Time: " + sw.ElapsedMilliseconds + "ms");
        }