public void TestIEWithSerialized()
        {
            // Does a complete encrypt/decrypt sequence from serialized values.
            // Kind of redundant because each of the testmethods above test serialization
            // of individual data types

            //Serialize and deserialize all objects
            IDEscrowParams     ieParam2 = ip.Deserialize <IDEscrowParams>(ip.Serialize(ieParam));
            IDEscrowPublicKey  pk2      = ip.Deserialize <IDEscrowPublicKey>(ip.Serialize(pk));
            IDEscrowPrivateKey sk2      = ip.Deserialize <IDEscrowPrivateKey>(ip.Serialize(sk));

            // Encrypt
            FieldZq        F    = ip.Zq;
            FieldZqElement xb2  = F.GetRandomElement(true);
            FieldZqElement ob2  = F.GetRandomElement(true);
            GroupElement   Cxb2 = ip.Gq.G.Exponentiate(xb2);  // Cxb = g^xb

            Cxb2 = Cxb2.Multiply(ip.G[1].Exponentiate(ob2));  // Cxb = (g^xb)*(g1^ob)
            GroupElement PE2 = ieParam2.Ge.Exponentiate(xb2);

            IDEscrowCiphertext ctext2 = IDEscrowFunctions.VerifiableEncrypt(ieParam2, pk2, tokenID, Cxb2, xb2, ob2, additionalInfo);

            ctext2 = ip.Deserialize <IDEscrowCiphertext>(ip.Serialize(ctext2));

            // Verify
            bool isValid = IDEscrowFunctions.Verify(ieParam2, ctext2, tokenID, pk2, Cxb2);

            Assert.IsTrue(isValid);

            // Decrypt
            GroupElement PEPrime = IDEscrowFunctions.Decrypt(ieParam2, ctext2, sk2);

            Assert.IsTrue(PE2.Equals(PEPrime));
        }
        /// <summary> Equality check between this <c>IDEscrowParams</c> and another.</summary>
        /// <remarks> Since IssuerParameters does not implement Equals, we only
        /// compare the UIDp of the issuer params.  Same for <c>GroupDescription</c>,
        /// so we only compare the group name. </remarks>
        /// <returns> <c>true</c> if equal, <c>false</c> otherwise </returns>
        public bool Equals(IDEscrowParams iep)
        {
            if (iep == null)
            {
                return(false);
            }

            // compare the UIDp field of issuer params only
            if (!ip.UidP.SequenceEqual(iep.ip.UidP))
            {
                return(false);
            }
            if (!G.GroupName.Equals(iep.G.GroupName))
            {
                return(false);
            }
            if (!ge.Equals(iep.Ge))
            {
                return(false);
            }

            // Note: we don't have a good way to compare hash functions, but
            // if the issuer parameters are the same the hash functions should be too

            return(true);
        }
예제 #3
0
        public void NullEquality()
        {
            var one = new Scalar(1);
            var ge  = new GroupElement(EC.G) * one;

            // Kinda clunky, but otherwise CodeFactor won't be happy.
            GroupElement?n = null;

            Assert.False(ge == n);
            Assert.True(ge != n);

            Assert.False(n == ge);
            Assert.True(n != ge);

            Assert.False(ge.Equals(n));
        }
        /// <summary>
        ///  Checks that <c>sk</c> is consistent with this public key and <c>param</c>.
        /// </summary>
        /// <returns><c>true</c> if valid, <c>false</c> otherwise.</returns>
        public bool Verify(IDEscrowParams param, IDEscrowPrivateKey sk)
        {
            if (!param.ip.Zq.IsElement(sk.X))  // is x in the right field?
            {
                return(false);
            }

            GroupElement hPrime = param.Ge.Exponentiate(sk.X);

            if (!hPrime.Equals(h))                      // is h = ge^x ?
            {
                return(false);
            }

            return(true);
        }
예제 #5
0
        public void TestRecommendedParameters()
        {
            ParameterSet set;
            const string ECCNamePrefix = "U-Prove Recommended Parameters Profile";
            var          encoder       = System.Text.UnicodeEncoding.UTF8;
            Dictionary <string, byte[]> oidContextDictionary = new Dictionary <string, byte[]>();

            // Subgroup (OID, NIST domain params seed)

            oidContextDictionary.Add("1.3.6.1.4.1.311.75.1.1.0",
                                     new byte[] {
                0x42, 0xf3, 0x05, 0xc4, 0x7a, 0xfa, 0xa3, 0x3b,
                0x97, 0xd7, 0x25, 0x77, 0x5c, 0xc2, 0xfe, 0x61,
                0xa8, 0xa1, 0xae, 0xe7
            });

            oidContextDictionary.Add("1.3.6.1.4.1.311.75.1.1.1",
                                     new byte[] {
                0x22, 0x7c, 0xc8, 0x30, 0x35, 0xac, 0x2c, 0x68,
                0xe6, 0xb4, 0xe5, 0xfe, 0x4b, 0x59, 0xc0, 0xa8,
                0x4a, 0xe8, 0x03, 0x30, 0xf3, 0x80, 0xde, 0x03,
                0x22, 0x3e, 0x37, 0x81, 0x36, 0xd7, 0x6f, 0xc0
            });

            oidContextDictionary.Add("1.3.6.1.4.1.311.75.1.1.2",
                                     new byte[] {
                0x31, 0xf2, 0xd6, 0xcf, 0xcd, 0x65, 0x2b, 0x7d,
                0xb8, 0x18, 0x6e, 0x84, 0x9d, 0xf1, 0x4b, 0x75,
                0x60, 0x40, 0x7b, 0xca, 0x0f, 0x03, 0x04, 0xe0,
                0x9e, 0x0d, 0x9d, 0x2c, 0x03, 0xd4, 0xfa, 0x4c
            });


            // Elliptic Curve (OID, ECC Prefix + curve name)
            oidContextDictionary.Add("1.3.6.1.4.1.311.75.1.2.1", encoder.GetBytes(ECCNamePrefix + "P-256"));  // NIST P-256
            oidContextDictionary.Add("1.3.6.1.4.1.311.75.1.2.2", encoder.GetBytes(ECCNamePrefix + "P-384"));  // NIST P-384
            oidContextDictionary.Add("1.3.6.1.4.1.311.75.1.2.3", encoder.GetBytes(ECCNamePrefix + "P-521"));  // NIST P-521
            oidContextDictionary.Add("1.3.6.1.4.1.311.75.1.3.1", encoder.GetBytes(ECCNamePrefix + "BN254"));  // BN

            foreach (string oid in oidContextDictionary.Keys)
            {
                ParameterSet.TryGetNamedParameterSet(oid, out set);
                Assert.AreEqual <string>(oid, set.Name);
                Assert.AreEqual <int>(ParameterSet.NumberOfIssuerGenerators + 1, set.G.Length); // g_t is also in the list
                Group Gq = set.Group;
                Gq.Verify();
                int    counter;
                byte[] context = oidContextDictionary[oid];
                if (Gq.Type == GroupType.Subgroup)
                {
                    // g is only generated for the subgroup construction
                    Assert.AreEqual <GroupElement>(Gq.G, Gq.DeriveElement(context, (byte)0, out counter));
                }

                // tests gi
                for (int i = 1; i < set.G.Length; i++)
                {
                    GroupElement gi = set.G[i - 1];
                    Gq.ValidateGroupElement(gi);
                    GroupElement derived = Gq.DeriveElement(context, (byte)i, out counter);
                    Gq.ValidateGroupElement(derived);
                    if (!gi.Equals(derived))
                    {
                        Debugger.Break();
                    }

                    Assert.AreEqual <GroupElement>(gi, derived);
                }
                // gt uses index = 255
                Assert.AreEqual <GroupElement>(set.G[set.G.Length - 1], Gq.DeriveElement(context, (byte)255, out counter));
                Gq.ValidateGroupElement(set.Gd);

                // gd uses index = 254
                Assert.AreEqual <GroupElement>(set.Gd, Gq.DeriveElement(context, (byte)254, out counter));
                Gq.ValidateGroupElement(set.Gd);

                // Issuer setup
                IssuerSetupParameters isp = new IssuerSetupParameters(maxNumberOfAttributes);
                isp.UidP = new byte[] { 1, 2, 3, 4, 5, 6, 7, 8, 9 };
                if (oid == "1.3.6.1.4.1.311.75.1.2.3") // P-521
                {
                    isp.UidH = "SHA-512";
                }
                isp.E            = new byte[ParameterSet.NumberOfIssuerGenerators];
                isp.ParameterSet = set;
                for (int i = 0; i < ParameterSet.NumberOfIssuerGenerators; i++)
                {
                    isp.E[i] = (byte)0;
                }
                isp.S = new byte[] { 1, 2, 3, 4, 5, 6, 7, 8, 9 };
                IssuerKeyAndParameters ikap = isp.Generate();
                IssuerParameters       ip   = ikap.IssuerParameters;

                RunProtocol(ikap, ip);
            }
        }
예제 #6
0
        public void PseudonymAndCommitmentsTest()
        {
            // Issuer setup
            IssuerSetupParameters isp = new IssuerSetupParameters(maxNumberOfAttributes);

            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.MultiExponentiate(new GroupElement[] { ip.Gq.G, ip.G[1] }, new FieldZqElement[] { x2, tildeO2 });

            Assert.IsTrue(Cx2Prime.Equals(Cx2));
        }
        public void TestIEWithRealToken()
        {
            /********** begin: this section of code taken from EndToEndTest.cs, TestMethod PseudonymAndCommitmentsTest *****/
            System.Text.UTF8Encoding encoding = new System.Text.UTF8Encoding();

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

            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       ip2  = 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(ip2);

            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(ip2, disclosed, committed, 1, scope, message, null, null, upkt[0], attributes, out tildeO);
            try { proof.Verify(ip2, disclosed, committed, 1, scope, message, null, upkt[0].Token); }
            catch { Assert.Fail("Proof failed to verify"); }
            /******** end code from EndToEndTest.cs ***********/

            // Use the commitment to attribute x_2 for ID escrow
            GroupElement   Cx2     = proof.Commitments[0].TildeC;                     // x2 is the first committed attribute
            FieldZqElement x2      = ProtocolHelper.ComputeXi(ip2, 1, attributes[1]); // attributes[] is zero indexed.
            FieldZqElement tildeO2 = tildeO[0];

            // double check that Cx2 is computed as we expect.
            GroupElement Cx2Prime = ip2.Gq.G.Exponentiate(x2);

            Cx2Prime = Cx2Prime.Multiply(ip2.G[1].Exponentiate(tildeO2));
            Assert.IsTrue(Cx2Prime.Equals(Cx2));

            // Setup
            IDEscrowParams     ieParam3 = new IDEscrowParams(ip2);
            IDEscrowPrivateKey priv     = new IDEscrowPrivateKey(ieParam3);                  // we can't re-use the keypair above, it was created with different issuer params
            IDEscrowPublicKey  pub      = new IDEscrowPublicKey(ieParam3, priv);

            byte[] tokenID = ProtocolHelper.ComputeTokenID(ip2, upkt[0].Token);
            // additionalInfo is defined above.

            // Encrypt
            IDEscrowCiphertext ctext = IDEscrowFunctions.VerifiableEncrypt(ieParam3, pub, tokenID, Cx2, x2, tildeO2, additionalInfo);

            // Verify
            Assert.IsTrue(IDEscrowFunctions.Verify(ieParam3, ctext, tokenID, pub, Cx2));
            // Decrypt
            GroupElement PE = IDEscrowFunctions.Decrypt(ieParam3, ctext, priv);

            Assert.IsTrue(PE.Equals(ieParam3.Ge.Exponentiate(x2)));   // Ensure PE == (ge)^x2
        }