/// <summary> /// Generates a presentation proof. /// </summary> /// <param name="pppp">The Prover presentation parameters.</param> /// <returns>A presentation proof.</returns> public static PresentationProof Generate(ProverPresentationProtocolParameters pppp) { CommitmentPrivateValues unused; if (pppp.Committed != null && pppp.Committed.Length > 0) { throw new ArgumentException("The ProverPresentationProtocolParameters's Committed attribute cannot be used with this method. Use Generate(ProverPresentationProtocolParameters pppp, out CommitmentPrivateValues cpv) instead."); } return(Generate(pppp, out unused)); }
private static CommitmentPrivateValues PresentUProveToken(IssuerParameters ip, UProveKeyAndToken upkt, byte[][] attributes, int[] disclosed, int[] committed, byte[] message, byte[] scope, IDevice device, byte[] deviceMessage) { WriteLine("Presenting one token"); // the returned commitment randomizer (to be used by an external proof module) CommitmentPrivateValues cpv; // generate the presentation proof string token = ip.Serialize<UProveToken>(upkt.Token); ProverPresentationProtocolParameters pppp = new ProverPresentationProtocolParameters(ip, disclosed, message, upkt, attributes); pppp.Committed = committed; // if a scope is defined, we use the first attribute to derive a scope exclusive pseudonym pppp.PseudonymAttributeIndex = (scope == null ? 0 : 1); pppp.PseudonymScope = scope; if (device != null) { pppp.SetDeviceData(deviceMessage, device.GetPresentationContext()); } pppp.KeyAndToken = upkt; pppp.Attributes = attributes; string proof = ip.Serialize<PresentationProof>(PresentationProof.Generate(pppp, out cpv)); // verify the presentation proof VerifierPresentationProtocolParameters vppp = new VerifierPresentationProtocolParameters(ip, disclosed, message, ip.Deserialize<UProveToken>(token)); vppp.Committed = committed; // if a scope is defined, we use the first attribute to derive a scope exclusive pseudonym vppp.PseudonymAttributeIndex = (scope == null ? 0 : 1); vppp.PseudonymScope = scope; vppp.DeviceMessage = deviceMessage; ip.Deserialize<PresentationProof>(proof).Verify(vppp); return cpv; }
/// <summary> /// Generates a presentation proof. /// </summary> /// <param name="pppp">The Prover presentation parameters.</param> /// <returns>A presentation proof.</returns> public static PresentationProof Generate(ProverPresentationProtocolParameters pppp) { CommitmentPrivateValues unused; if (pppp.Committed != null && pppp.Committed.Length > 0) { throw new ArgumentException("The ProverPresentationProtocolParameters's Committed attribute cannot be used with this method. Use Generate(ProverPresentationProtocolParameters pppp, out CommitmentPrivateValues cpv) instead."); } return Generate(pppp, out unused); }
/// <summary> /// Generates a presentation proof. /// </summary> /// <param name="pppp">The Prover presentation parameters.</param> /// <param name="cpv">Returned commitment private values if commitments are computed.</param> /// <returns>A presentation proof.</returns> public static PresentationProof Generate(ProverPresentationProtocolParameters pppp, out CommitmentPrivateValues cpv) { return Generate(pppp.IP, pppp.Disclosed, pppp.Committed, pppp.PseudonymAttributeIndex, pppp.PseudonymScopeElement, pppp.Message, pppp.DeviceMessage, pppp.DeviceContext, pppp.KeyAndToken, pppp.Attributes, pppp.RandomData, out cpv); }
/// <summary> /// Generates a presentation proof. /// </summary> /// <param name="pppp">The Prover presentation parameters.</param> /// <param name="cpv">Returned commitment private values if commitments are computed.</param> /// <returns>A presentation proof.</returns> public static PresentationProof Generate(ProverPresentationProtocolParameters pppp, out CommitmentPrivateValues cpv) { return(Generate(pppp.IP, pppp.Disclosed, pppp.Committed, pppp.PseudonymAttributeIndex, pppp.PseudonymScopeElement, pppp.Message, pppp.DeviceMessage, pppp.DeviceContext, pppp.KeyAndToken, pppp.Attributes, pppp.RandomData, out cpv)); }
/// <summary> /// Create a new pre-issuance proof. /// </summary> /// <param name="pipp">The prover parameters.</param> /// <param name="beta0">The random blinding value used to create the proof, output so that the prover can use it during the issuance protocol</param> /// <param name="message">An optional message to sign while creating the proof.</param> /// <returns></returns> public static PreIssuanceProof CreateProof(ProverPreIssuanceParameters pipp, out FieldZqElement beta0, byte[] message) { // validate paramters first pipp.Validate(); bool supportDevice = (pipp.DevicePublicKey == null) ? false : true; IssuerParameters ip = pipp.IP; FieldZq Zq = ip.Zq; Group Gq = ip.Gq; Dictionary <string, FieldZqElement> responses = new Dictionary <string, FieldZqElement>(); // these will be used if there is a carry-over attribute CommitmentPrivateValues cpv = null; PresentationProof presProof = null; GroupElement[] C = null; GroupElement[] tildeC = null; FieldZqElement[] tildeR = null; // extension by Fablei -> needs to calculate the ip.G.Length -> pipp.Attributes.Length + 2 int ipGLength = pipp.Attributes.Length + 2; // Generate random values beta0 = Zq.GetRandomElement(true); FieldZqElement tildeBeta0 = Zq.GetRandomElement(true); FieldZqElement rho = Zq.GetRandomElement(true); FieldZqElement tildeRho = Zq.GetRandomElement(true); FieldZqElement tilde_d = Zq.GetRandomElement(true); FieldZqElement[] tildeX = new FieldZqElement[ipGLength - 1]; for (int i = 1; i < ipGLength - 1; i++) { if (!pipp.K.Contains(i)) { tildeX[i] = Zq.GetRandomElement(true); } } // Compute the U-Prove presentation proof, if there are carry-over attributes if (pipp.HasCarryOverAttributes) { // generate the presentation proof int[] disclosed = new int[] { }; ProverPresentationProtocolParameters pppp = new ProverPresentationProtocolParameters(pipp.SourceIP, disclosed, message, pipp.KeyAndToken, pipp.SourceAttributes); pppp.Committed = pipp.Corig; // TODO: What if the source token is device protected? need to handle this as well. (a pointer to the device should be included in pipp //if (device != null) //{ // pppp.SetDeviceData(deviceMessage, device.GetPresentationContext()); //}- // For now just fail: if (pipp.KeyAndToken.Token.IsDeviceProtected) { throw new NotImplementedException("Device protected tokens may not be used for carry-over attributes"); } presProof = PresentationProof.Generate(pppp, out cpv); //set C C = new GroupElement[pipp.C.Length]; // Generate random values for the commitment randomizers tildeR = Zq.GetRandomElements(pipp.C.Length, true); tildeC = new GroupElement[C.Length]; for (int i = 0; i < C.Length; i++) { C[i] = presProof.Commitments[i].TildeC; tildeC[i] = Gq.MultiExponentiate(Gq.G, ip.G[1], tildeX[pipp.C[i]], tildeR[i]); } } // end if cary-over attributes // Compute gamma GroupElement gamma = ProtocolHelper.ComputeIssuanceInput(ip, pipp.Attributes, pipp.TI, pipp.DevicePublicKey); // Compute h0, Cgamma, Ch0, tildeD, tildeT: GroupElement h0 = gamma.Exponentiate(beta0); GroupElement Cgamma = gamma.Multiply(Gq.G.Exponentiate(rho)); // Cgamma = gamma*(g^rho) GroupElement Ch0 = Cgamma.Exponentiate(beta0); GroupElement tildeD = Gq.G.Exponentiate(tilde_d); GroupElement tildeT = Cgamma.Exponentiate(tildeBeta0); // Compute tildeCgamma: List <GroupElement> bases = new List <GroupElement>(); List <FieldZqElement> exponents = new List <FieldZqElement>(); bases.Add(Gq.G); exponents.Add(tildeRho); for (int i = 1; i < ipGLength - 1; i++) { if (!pipp.K.Contains(i)) // i \not\in K { bases.Add(ip.G[i]); exponents.Add(tildeX[i]); } } GroupElement tildeCgamma = Gq.MultiExponentiate(bases.ToArray(), exponents.ToArray()); // TODO: if device protected, then multiply tildeCgamma by the public key // Note: We leave TI out, (i.e., (g_t)^(x_t) because t \in K implicitly. // Compute the challenge byte[] c = ComputeChallenge(ip, h0, Cgamma, Ch0, C, tildeD, tildeCgamma, tildeT, tildeC, message); FieldZqElement negc = Zq.GetElementFromDigest(c).Negate(); // Compute the responses responses.Add("sBeta0", tildeBeta0.Add(beta0.Multiply(negc))); // sBeta0 = tildeBeta0 - beta0*c responses.Add("sD", tilde_d.Add(beta0.Multiply(rho).Multiply(negc))); // sD = tilde_d - beta0*rho*c responses.Add("sRho", tildeRho.Add(rho.Multiply(negc))); // sRho = tildeRho - rho*c for (int i = 1; i < ipGLength - 1; i++) { if (!pipp.K.Contains(i)) // in \not\in K { FieldZqElement xi = ProtocolHelper.ComputeXi(ip, i - 1, pipp.Attributes[i - 1]); responses.Add("sx" + i, tildeX[i].Add(xi.Multiply(negc))); // sxi = tildeX[i] - xi*c } } if (pipp.HasCarryOverAttributes) { for (int i = 0; i < C.Length; i++) { responses.Add("sR" + i, tildeR[i].Add(cpv.TildeO[i].Multiply(negc))); // sRi = tildeR[i] - tildeO[i]*c } } return(new PreIssuanceProof(h0, Cgamma, Ch0, c, responses, pipp.HasCarryOverAttributes ? presProof : null, pipp.Attributes.Length)); }
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"); }