Example #1
0
        public static bool Verify(UProveToken upt1, object obj)
        {
            UProveToken upt2 = GetSameType(upt1, obj);

            if (upt2 == null)
            {
                return(false);
            }

            if (Object.ReferenceEquals(upt1, upt2))
            {
                return(true);
            }

            if (CompareFields(upt2.Uidp, upt1.Uidp) == false)
            {
                return(false);
            }

            if (CompareFields(upt2.H, upt1.H) == false)
            {
                return(false);
            }

            if (CompareFields(upt2.TI, upt1.TI) == false)
            {
                return(false);
            }

            if (CompareFields(upt2.PI, upt1.PI) == false)
            {
                return(false);
            }

            if (CompareFields(upt2.SigmaZPrime, upt1.SigmaZPrime) == false)
            {
                return(false);
            }

            if (CompareFields(upt2.SigmaCPrime, upt1.SigmaCPrime) == false)
            {
                return(false);
            }

            if (CompareFields(upt2.SigmaRPrime, upt1.SigmaRPrime) == false)
            {
                return(false);
            }

            if (upt2.IsDeviceProtected != upt1.IsDeviceProtected)
            {
                return(false);
            }

            return(true);
        }
Example #2
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);
            }
        }
Example #3
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);
        }
Example #4
0
        public static UProveTokenComposite convertUProveToken(UProveToken up)
        {
            UProveTokenComposite utc = new UProveTokenComposite();

            utc.H = up.H.GetEncoded();
            utc.IsDeviceProtected = up.IsDeviceProtected;
            utc.PI          = up.PI;
            utc.SigmaCPrime = up.SigmaCPrime.ToByteArray();
            utc.SigmaRPrime = up.SigmaRPrime.ToByteArray();
            utc.SigmaZPrime = up.SigmaZPrime.GetEncoded();
            utc.TI          = up.TI;
            utc.Uidp        = up.Uidp;

            return(utc);
        }
Example #5
0
        /// <summary>
        /// Create a verifiable encryption of a pseudonym based on a U-Prove presentation proof.  This is a wrapper
        /// of <c>VerifiableEncrypt</c>.
        ///
        /// </summary>
        /// <param name="escrowParams"> Parameters of the ID escrow scheme</param>
        /// <param name="escrowPublicKey">  Public key of the Auditor (the authority who can decrypt the output ciphertex).</param>
        /// <param name="token"> The U-Prove token corresponding to the <c>proof</c>. </param>
        /// <param name="additionalInfo">See documentation of <c>VerifiableEncrypt</c></param>
        /// <param name="proof">A U-Prove prsentation proof.</param>
        /// <param name="cpv">Commitment opening information, output when generating <c>proof</c>.</param>
        /// <param name="idAttributeIndex"> Index of the attribute to use for identity escrow (1-based indexing). This attribute <b>must be</b>
        ///                                 the first commited attribute (take care if using multiple extensions). </param>
        /// <param name="attributes"> Attributes in <c>token</c>.</param>

        /// <returns></returns>
        public static IDEscrowCiphertext UProveVerifableEncrypt(IDEscrowParams escrowParams, IDEscrowPublicKey escrowPublicKey,
                                                                UProveToken token, byte[] additionalInfo, PresentationProof proof,
                                                                CommitmentPrivateValues cpv, int idAttributeIndex, byte[][] attributes)
        {
            if (token == null || escrowParams == null || proof == null || cpv == null)
            {
                throw new ArgumentNullException("null input to UProveVerifiableEncrypt");
            }

            if (proof.Commitments == null || proof.Commitments.Length < 1 ||
                attributes.Length < idAttributeIndex || cpv.TildeO == null || cpv.TildeO.Length < 1)
            {
                throw new InvalidUProveArtifactException("invalid inputs to UProveVerifiableEncrypt");
            }


            byte[]         tokenId = ProtocolHelper.ComputeTokenID(escrowParams.ip, token);
            GroupElement   Cx1     = proof.Commitments[0].TildeC;                                                                       // x1 is the first committed attribute
            FieldZqElement x1      = ProtocolHelper.ComputeXi(escrowParams.ip, idAttributeIndex - 1, attributes[idAttributeIndex - 1]); // arrays are 0-based
            FieldZqElement tildeO1 = cpv.TildeO[0];

            return(IDEscrowFunctions.VerifiableEncrypt(escrowParams, escrowPublicKey, tokenId, Cx1, x1, tildeO1, additionalInfo));
        }
Example #6
0
        public PresentationProofComposite proveToken(string[] attributesParam, int[] disclosedIndices, int[] committedIndices, string messageParam, string verifierScopeParam, IssuerParametersComposite ipc, UProveTokenComposite tokenComposite, byte[] tokenPrivateKeyParam, string sessionID)
        {
            /*
             *  token presentation
             */

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

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

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

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

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

            return(null);
        }
Example #7
0
        /// <summary>
        ///  Verifies that an <c>IECiphertext</c> was computed correctly.
        ///  This is a wrapper around <c>IEFunctions.Verify</c> for use with U-Prove.
        /// </summary>
        /// <param name="escrowParams">Parameters of the ID escrow scheme</param>
        /// <param name="ctext">A ciphertext created with <c>param</c> and <c>pk</c>. </param>
        /// <param name="proof">The associated U-Prove presentation proof.</param>
        /// <param name="token">The associated U-Prove token.</param>
        /// <param name="pk">The auditor's public key</param>
        /// <returns> True if the ciphertext is valid, false if it is invalid.</returns>
        /// <remarks>The identity <b>must be</b> the first committed attribute in the proof (as
        /// in <c>UProveVerifiableEncrypt</c>).</remarks>
        public static bool UProveVerify(IDEscrowParams escrowParams, IDEscrowCiphertext ctext, PresentationProof proof, UProveToken token, IDEscrowPublicKey pk)
        {
            if (escrowParams == null || ctext == null || proof == null || token == null || pk == null)
            {
                throw new ArgumentException("null input to UProveVerify");
            }

            if (proof.Commitments == null || proof.Commitments.Length < 1)
            {
                throw new InvalidUProveArtifactException("invalid inputs to UProveVerifiableEncrypt");
            }

            GroupElement Cx1 = proof.Commitments[0].TildeC;

            byte[] tokenId = ProtocolHelper.ComputeTokenID(escrowParams.ip, token);
            return(IDEscrowFunctions.Verify(escrowParams, ctext, tokenId, pk, Cx1));
        }
        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)
                {
                    foreach (int DSize in new int[] { 0, 2, 5 })
                    {
                        foreach (bool isLite in bools)
                        {
                            string filename = "TestVectorData\\testvectors_";
                            if (isSubgroupConstruction)
                            {
                                filename += "SG";
                            }
                            else
                            {
                                filename += "EC";
                            }
                            if (supportDevice)
                            {
                                filename += "_Device";
                            }
                            filename += ("_D" + DSize);
                            if (isLite)
                            {
                                filename += "_lite";
                            }
                            filename += "_doc.txt";
                            var vectors = GetTestVectors(filename);

                            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["cp"]), 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 = new int[] { };
                            if (vectors.ContainsKey("D") && vectors["D"].Length > 0)
                            {
                                disclosed = Array.ConvertAll <string, int>(vectors["D"].Split(','), new Converter <string, int>(stringToInt));
                            }
                            int[] undisclosed = new int[5 - disclosed.Length];
                            int   dIndex = 0, uIndex = 0;
                            for (int i = 1; i <= 5; i++)
                            {
                                if (disclosed.Length > 0 && disclosed[dIndex] == i)
                                {
                                    dIndex++;
                                }
                                else
                                {
                                    undisclosed[uIndex++] = i;
                                }
                            }
                            int[] committed = new int[] { };
                            if (vectors.ContainsKey("C") && vectors["C"].Length > 0)
                            {
                                committed = Array.ConvertAll <string, int>(vectors["C"].Split(','), new Converter <string, int>(stringToInt));
                            }
                            byte[] m  = HexToBytes(vectors["m"]);
                            byte[] md = HexToBytes(vectors["md"]);
                            IDevicePresentationContext deviceContext = null;
                            if (supportDevice)
                            {
                                deviceContext = device.GetPresentationContext();
                            }
                            int p = 0;
                            if (vectors.ContainsKey("p") && !int.TryParse(vectors["p"], out p))
                            {
                                p = PresentationProof.DeviceAttributeIndex;
                            }
                            byte[] s = vectors.ContainsKey("s") ? HexToBytes(vectors["s"]) : null;
                            int    commitmentIndex = committed.Length > 0 ? committed[0] : 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;
                            FieldZqElement[] w = new FieldZqElement[undisclosed.Length];
                            for (int i = 0; i < undisclosed.Length; i++)
                            {
                                w[i] = Zq.GetElement(HexToBytes(vectors["w" + undisclosed[i]]));
                            }
                            FieldZqElement[] tildeO = new FieldZqElement[committed.Length];
                            FieldZqElement[] tildeW = new FieldZqElement[committed.Length];
                            for (int i = 0; i < committed.Length; i++)
                            {
                                tildeO[i] = Zq.GetElement(HexToBytes(vectors["tildeO" + committed[i]]));
                                tildeW[i] = Zq.GetElement(HexToBytes(vectors["tildeW" + committed[i]]));
                            }
                            pppp.RandomData = new ProofGenerationRandomData(
                                Zq.GetElement(HexToBytes(vectors["w0"])),
                                w,
                                supportDevice ? Zq.GetElement(HexToBytes(vectors["wd"])) : null,
                                tildeO,
                                tildeW);
                            CommitmentPrivateValues cpv;
                            PresentationProof       proof = PresentationProof.Generate(pppp, out cpv);
                            Assert.IsTrue(HexToBytes(vectors["a"]).SequenceEqual(proof.A), "a");
                            if (vectors.ContainsKey("gs"))
                            {
                                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");
                            }
                            for (int i = 0; i < disclosed.Length; i++)
                            {
                                Assert.IsTrue(HexToBytes(vectors["A" + disclosed[i]]).SequenceEqual(proof.DisclosedAttributes[i]), "A" + disclosed[i]);
                            }
                            Assert.AreEqual(proof.R[0], Zq.GetElement(HexToBytes(vectors["r0"])), "r0");
                            for (int i = 0; i < undisclosed.Length; i++)
                            {
                                Assert.AreEqual(proof.R[i + 1], Zq.GetElement(HexToBytes(vectors["r" + undisclosed[i]])), "r" + undisclosed[i]);
                            }
                            if (supportDevice)
                            {
                                Assert.AreEqual(proof.R[proof.R.Length - 1], Zq.GetElement(HexToBytes(vectors["rd"])), "rd");
                            }
                            for (int i = 0; i < committed.Length; i++)
                            {
                                Assert.AreEqual(proof.Commitments[i].TildeR, Zq.GetElement(HexToBytes(vectors["tildeR" + committed[i]])), "tildeR" + committed[i]);
                                Assert.IsTrue(cpv.TildeO.Length == committed.Length);
                                Assert.AreEqual(cpv.TildeO[i], Zq.GetElement(HexToBytes(vectors["tildeO" + committed[i]])), "tildeO" + committed[i]);
                            }
                            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);
#if TEST_ID_ESCROW
                            if (committed.Length > 0)
                            {
                                IDEscrowParams     escrowParams     = new IDEscrowParams(ip);
                                IDEscrowPrivateKey escrowPrivateKey = new IDEscrowPrivateKey(Zq.GetElement(HexToBytes(vectors["ie_x"])));
                                IDEscrowPublicKey  escrowPublicKey  = new IDEscrowPublicKey(escrowParams, escrowPrivateKey);
                                Assert.AreEqual(escrowPublicKey.H, CreateGroupElement(ip.Gq, vectors["ie_H"]), "ie_H");
                                byte[] additionalInfo = HexToBytes(vectors["ie_additionalInfo"]);
                                int    ie_bIndex      = int.Parse(vectors["ie_b"]);

                                IDEscrowCiphertext ctext = IDEscrowFunctions.VerifiableEncrypt(
                                    escrowParams,
                                    escrowPublicKey,
                                    HexToBytes(vectors["UIDt"]),
                                    proof.Commitments[0].TildeC,
                                    ProtocolHelper.ComputeXi(ip, ie_bIndex - 1, A[ie_bIndex - 1]),
                                    cpv.TildeO[0],
                                    additionalInfo,
                                    new IDEscrowFunctions.IDEscrowProofGenerationRandomData(
                                        Zq.GetElement(HexToBytes(vectors["ie_r"])),
                                        Zq.GetElement(HexToBytes(vectors["ie_xbPrime"])),
                                        Zq.GetElement(HexToBytes(vectors["ie_rPrime"])),
                                        Zq.GetElement(HexToBytes(vectors["ie_obPrime"]))));
                                Assert.IsTrue(IDEscrowFunctions.UProveVerify(escrowParams, ctext, proof, upkt[0].Token, escrowPublicKey));
                                Assert.AreEqual(ctext.E1, CreateGroupElement(ip.Gq, vectors["ie_E1"]), "ie_E1");
                                Assert.AreEqual(ctext.E2, CreateGroupElement(ip.Gq, vectors["ie_E2"]), "ie_E2");
                                Assert.AreEqual(ctext.proof.c, Zq.GetElement(HexToBytes(vectors["ie_c"])), "ie_c");
                                Assert.AreEqual(ctext.proof.rR, Zq.GetElement(HexToBytes(vectors["ie_rr"])), "ie_rr");
                                Assert.AreEqual(ctext.proof.rXb, Zq.GetElement(HexToBytes(vectors["ie_rxb"])), "ie_rxb");
                                Assert.AreEqual(ctext.proof.rOb, Zq.GetElement(HexToBytes(vectors["ie_rob"])), "ie_rob");
                                GroupElement PE = IDEscrowFunctions.Decrypt(escrowParams, ctext, escrowPrivateKey);
                            }
#endif

#if TEST_DVA_REVOCATION
                            if (committed.Length > 0)
                            {
                                RAParameters             raParams = new RAParameters(ip.Gq.GroupName, CreateGroupElement(ip.Gq, vectors["r_K"]), ip.UidH);
                                FieldZqElement           delta    = Zq.GetElement(HexToBytes(vectors["r_delta"]));
                                RevocationAuthority      RA       = new RevocationAuthority(raParams, delta);
                                HashSet <FieldZqElement> revoked  = new HashSet <FieldZqElement>();
                                for (int i = 1; i <= 4; i++)
                                {
                                    revoked.Add(Zq.GetElement(HexToBytes(vectors["r_R" + i])));
                                }
                                RA.UpdateAccumulator(revoked, null);
                                Assert.AreEqual(RA.Accumulator, CreateGroupElement(ip.Gq, vectors["r_V"]), "r_V");
                                int r_id = 0;
                                int.TryParse(vectors["r_id"], out r_id);
                                RevocationWitness witness = RA.ComputeRevocationWitness(revoked, Zq.GetElement(HexToBytes(vectors["x" + r_id])));
                                Assert.AreEqual(witness.d, Zq.GetElement(HexToBytes(vectors["r_d"])), "r_d");
                                Assert.AreEqual(witness.W, CreateGroupElement(ip.Gq, vectors["r_W"]), "r_W");
                                Assert.AreEqual(witness.Q, CreateGroupElement(ip.Gq, vectors["r_Q"]), "r_Q");

                                NonRevocationProof nrProof = RevocationUser.GenerateNonRevocationProof(
                                    raParams,
                                    witness,
                                    proof.Commitments[0].TildeC, ProtocolHelper.ComputeXi(ip, r_id - 1, A[r_id - 1]),
                                    cpv.TildeO[0],
                                    new NonRevocationProofGenerationRandomData(new FieldZqElement[] {
                                    Zq.GetElement(HexToBytes(vectors["r_t1"])),
                                    Zq.GetElement(HexToBytes(vectors["r_t2"])),
                                    Zq.GetElement(HexToBytes(vectors["r_k1"])),
                                    Zq.GetElement(HexToBytes(vectors["r_k2"])),
                                    Zq.GetElement(HexToBytes(vectors["r_k3"])),
                                    Zq.GetElement(HexToBytes(vectors["r_k4"])),
                                    Zq.GetElement(HexToBytes(vectors["r_k5"])),
                                    Zq.GetElement(HexToBytes(vectors["r_k6"]))
                                }));
                                Assert.AreEqual(nrProof.X, CreateGroupElement(ip.Gq, vectors["r_X"]), "r_X");
                                Assert.AreEqual(nrProof.Y, CreateGroupElement(ip.Gq, vectors["r_Y"]), "r_Y");
                                Assert.AreEqual(nrProof.Cd, CreateGroupElement(ip.Gq, vectors["r_Cd"]), "r_Cd");
                                Assert.AreEqual(nrProof.cPrime, Zq.GetElement(HexToBytes(vectors["r_cPrime"])), "r_cPrime");
                                Assert.AreEqual(nrProof.s[0], Zq.GetElement(HexToBytes(vectors["r_s1"])), "r_s1");
                                Assert.AreEqual(nrProof.s[1], Zq.GetElement(HexToBytes(vectors["r_s2"])), "r_s2");
                                Assert.AreEqual(nrProof.s[2], Zq.GetElement(HexToBytes(vectors["r_s3"])), "r_s3");
                                Assert.AreEqual(nrProof.s[3], Zq.GetElement(HexToBytes(vectors["r_s4"])), "r_s4");
                                Assert.AreEqual(nrProof.s[4], Zq.GetElement(HexToBytes(vectors["r_s5"])), "r_s5");
                                Assert.AreEqual(nrProof.s[5], Zq.GetElement(HexToBytes(vectors["r_s6"])), "r_s6");

                                // validate proof
                                RA.VerifyNonRevocationProof(ip, 0, proof, nrProof);
                            }
#endif

#if TEST_SET_MEMBERSHIP
                            if (committed.Length > 0)
                            {
                                int sm_x_index = 0;
                                int.TryParse(vectors["sm_x_index"], out sm_x_index);
                                int sm_n = 0;
                                int.TryParse(vectors["sm_n"], out sm_n);
                                int sm_i = 0;
                                int.TryParse(vectors["sm_i"], out sm_i);
                                byte[][]         setValues = new byte[sm_n][];
                                FieldZqElement[] sm_c      = new FieldZqElement[sm_n - 1];
                                FieldZqElement[] sm_r      = new FieldZqElement[sm_n - 1];
                                int randomIndex            = 0;
                                for (int i = 1; i <= sm_n; i++)
                                {
                                    if (i == sm_i)
                                    {
                                        setValues[i - 1] = HexToBytes(vectors["A" + sm_x_index]);
                                    }
                                    else
                                    {
                                        setValues[i - 1]  = HexToBytes(vectors["sm_s" + i]);
                                        sm_c[randomIndex] = Zq.GetElement(HexToBytes(vectors["sm_c" + i]));
                                        sm_r[randomIndex] = Zq.GetElement(HexToBytes(vectors["sm_r" + i]));
                                        randomIndex++;
                                    }
                                }
                                SetMembershipProofGenerationRandomData smRandom = new SetMembershipProofGenerationRandomData(sm_c, sm_r, Zq.GetElement(HexToBytes(vectors["sm_w"])));
                                SetMembershipProof setMembershipProof           = SetMembershipProof.Generate(pppp, proof, cpv, sm_x_index, setValues, smRandom);
                                for (int i = 1; i <= sm_n; i++)
                                {
                                    Assert.AreEqual(setMembershipProof.a[i - 1], CreateGroupElement(ip.Gq, vectors["sm_a" + i]), "sm_a" + i);
                                    if (i < sm_n) // no c_n in the proof
                                    {
                                        Assert.AreEqual(setMembershipProof.c[i - 1], Zq.GetElement(HexToBytes(vectors["sm_c" + i])), "sm_c" + i);
                                    }
                                    Assert.AreEqual(setMembershipProof.r[i - 1], Zq.GetElement(HexToBytes(vectors["sm_r" + i])), "sm_r" + i);
                                }

                                if (!SetMembershipProof.Verify(vppp, proof, setMembershipProof, sm_x_index, setValues))
                                {
                                    throw new InvalidUProveArtifactException("Invalid set membership proof");
                                }
                            }
#endif
                        }
                    }
                }
            }
            sw.Stop();
            Debug.WriteLine("Protocol Test Elapsed Time: " + sw.ElapsedMilliseconds + "ms");
        }
Example #9
0
        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");
        }
Example #10
0
        public void TestSerializationReference()
        {
            // Create IssuerSetupParameters
            System.Text.UTF8Encoding encoding = new System.Text.UTF8Encoding();
            foreach (string fileName in Directory.GetFiles("SerializationReference"))
            {
                FileStream      f          = File.OpenRead(fileName);
                BinaryFormatter bf         = new BinaryFormatter();
                object[]        parameters = (object[])bf.Deserialize(f);
                f.Close();

                bool   useCustomGroup          = (bool)parameters[0];
                bool   useSubgroupConstruction = (bool)parameters[1];
                string typeName = (string)parameters[2];
                string json     = (string)parameters[3];

                IssuerSetupParameters isp = new IssuerSetupParameters();
                if (useSubgroupConstruction)
                {
                    isp.GroupConstruction = GroupType.Subgroup;
                    if (useCustomGroup)
                    {
                        byte[] p = HexToBytes("d21ae8d66e6c6b3ced0eb3df1a26c91bdeed013c17d849d30ec309813e4d3799f26db0d494e82ec61ea9fdc70bb5cbcaf2e5f18a836494f58e67c6d616480c37a7f2306101fc9f0f4768f9c9793c2be176b0b7c979b4065d3e835686a3f0b8420c6834cb17930386dedab2b07dd473449a48baab316286b421052475d134cd3b");
                        byte[] q = HexToBytes("fff80ae19daebc61f46356af0935dc0e81148eb1");
                        byte[] g = HexToBytes("abcec972e9a9dd8d133270cfeac26f726e567d964757630d6bd43460d0923a46aec0ace255ebf3ddd4b1c4264f53e68b361afb777a13cf0067dae364a34d55a0965a6cccf78852782923813cf8708834d91f6557d783ec75b5f37cd9185f027b042c1c72e121b1266a408be0bb7270d65917b69083633e1f3cd60624612fc8c1");
                        isp.Gq = SubgroupGroup.CreateSubgroupGroup(
                            p,
                            q,
                            g,
                            null,
                            null);
                        isp.UidH = "SHA1";
                    }
                }
                else
                {
                    isp.GroupConstruction = GroupType.ECC;
                    if (useCustomGroup)
                    {
                        continue;
                    }
                }

                isp.UidP = encoding.GetBytes("http://issuer/uprove/issuerparams/software");
                isp.E    = IssuerSetupParameters.GetDefaultEValues(3);
                isp.S    = encoding.GetBytes("application-specific specification");

                // Generate IssuerKeyAndParameters
                IssuerKeyAndParameters ikap = isp.Generate();

                // Create an IssuerParameters
                IssuerParameters ip = ikap.IssuerParameters;

                // check that we didn't send any null fields
                Assert.IsFalse(json.Contains(":null"));

                string roundTrip = "";
                if (typeName == "UProveCrypto.IssuerParameters")
                {
                    IssuerParameters obj = ip.Deserialize <IssuerParameters>(json);
                    roundTrip = ip.Serialize <IssuerParameters>(obj);
                }
                else if (typeName == "UProveCrypto.IssuerKeyAndParameters")
                {
                    IssuerKeyAndParameters obj = ip.Deserialize <IssuerKeyAndParameters>(json);
                    roundTrip = ip.Serialize <IssuerKeyAndParameters>(obj);
                }
                else if (typeName == "UProveCrypto.FirstIssuanceMessage")
                {
                    FirstIssuanceMessage obj = ip.Deserialize <FirstIssuanceMessage>(json);
                    roundTrip = ip.Serialize <FirstIssuanceMessage>(obj);
                }
                else if (typeName == "UProveCrypto.SecondIssuanceMessage")
                {
                    SecondIssuanceMessage obj = ip.Deserialize <SecondIssuanceMessage>(json);
                    roundTrip = ip.Serialize <SecondIssuanceMessage>(obj);
                }
                else if (typeName == "UProveCrypto.ThirdIssuanceMessage")
                {
                    ThirdIssuanceMessage obj = ip.Deserialize <ThirdIssuanceMessage>(json);
                    roundTrip = ip.Serialize <ThirdIssuanceMessage>(obj);
                }
                else if (typeName == "UProveCrypto.UProveKeyAndToken")
                {
                    UProveKeyAndToken obj = ip.Deserialize <UProveKeyAndToken>(json);
                    roundTrip = ip.Serialize <UProveKeyAndToken>(obj);
                }
                else if (typeName == "UProveCrypto.UProveToken")
                {
                    UProveToken obj = ip.Deserialize <UProveToken>(json);
                    roundTrip = ip.Serialize <UProveToken>(obj);
                }
                else if (typeName == "UProveCrypto.PresentationProof")
                {
                    PresentationProof obj = ip.Deserialize <PresentationProof>(json);
                    roundTrip = ip.Serialize <PresentationProof>(obj);
                }
                else
                {
                    Assert.Fail("Unrecognized type " + typeName + " in SerializationReference files");
                }

                Assert.AreEqual(json, roundTrip);
            }
        }