public void CollaborativeIssuanceTrustedGamma() { // Issuance byte[][] attributes = new byte[][] { encoding.GetBytes("Attribute 1"), encoding.GetBytes("Attribute 2"), encoding.GetBytes("Attribute 3") }; ProverProtocolParameters ppp = new ProverProtocolParameters(ip); ppp.Attributes = attributes; Prover prover = ppp.CreateProver(); IssuerProtocolParameters ipp = new IssuerProtocolParameters(ikap); ipp.Gamma = ProtocolHelper.ComputeIssuanceInput(ip, attributes, null, null); // computed by some other party. 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"); UProveCrypto.Math.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); }
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> /// Initialise the system for a given token by the prover /// </summary> /// <param name="ipJson">Json string of the issuer parameters which has issued the given token</param> /// <param name="proofJson">Json string that includes the proof to the given token and later proofs - /// created by the prover itself</param> /// <param name="tokenJson">Json of the token - created by issuer and prover</param> /// <param name="trustedIssuerJson">List of trusted issuers; in IP format, could be more than one Issuer /// in a anonymus Json-Object; { "IP..</param> public void Init(string ipJson, string proofJson, string tokenJson, string trustedIssuerJson) { LogService.Log(LogService.LogType.Info, "IssuingVerifier - init called"); proofAccepted = false; tokenAccepted = false; isInitialized = false; // create issuer parameters IP = new IssuerParameters(ipJson); IP.Verify(); this.trustedIssuerJson = trustedIssuerJson; CheckTrustedIssuer(); Proof proof = parser.ParseJsonToObject <Proof>(proofJson); proofRequirements = proof.requirements; PresentationProof pProof = IP.Deserialize <PresentationProof>(proofJson); this.tokenJson = tokenJson; this.proofJson = IP.Serialize(pProof); isInitialized = true; LogService.Log(LogService.LogType.Info, "IssuingVerifier - successfully initialized"); VerifyProof(); }
public static bool Verify(PresentationProof pp1, object obj) { PresentationProof pp2 = GetSameType(pp1, obj); if (pp2 == null) { return(false); } if (Object.ReferenceEquals(pp1, pp2)) { return(true); } if (pp1.DisclosedAttributes.Length != pp2.DisclosedAttributes.Length) { return(false); } for (int i = 0; i < pp1.DisclosedAttributes.Length; i++) { if (CompareFields(pp1.DisclosedAttributes[i], pp2.DisclosedAttributes[i]) == false) { return(false); } } //if (CompareFields(pp1.DisclosedAttributes, pp2.DisclosedAttributes) == false) // return false; if (CompareFields(pp2.A, pp1.A) == false) { return(false); } if (CompareFields(pp2.Ap, pp1.Ap) == false) { return(false); } if (CompareFields(pp2.Ps, pp1.Ps) == false) { return(false); } if (CompareFields(pp2.R, pp1.R) == false) { return(false); } if (CompareFields(pp2.Commitments, pp1.Commitments) == false) { return(false); } return(true); }
/// <summary> /// Creates a closed commitment from one of the commitments created by a presentation proof. /// This is a UProve integration method that should be called by the Verifier. /// </summary> /// <param name="ip">Issuer parameters</param> /// <param name="proof">token presentation proof</param> /// <param name="commitmentIndex">which commitment</param> public ClosedPedersenCommitment(IssuerParameters ip, PresentationProof proof, int commitmentIndex) { this.Value = proof.Commitments[commitmentIndex].TildeC; CryptoParameters crypto = new CryptoParameters(ip); this.Group = crypto.Group; this.Bases = new GroupElement[2] { crypto.Generators[0], crypto.Generators[1] }; }
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 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); } }
/// <summary> /// Verifies a set membership proof from U-Prove parameters. /// </summary> /// <param name="vppp">The verifier presentation protocol parameters.</param> /// <param name="pProof">A presentation proof.</param> /// <param name="smProof">A set presentation proof.</param> /// <param name="committedIndex">Index of the committed attribute used to generate the set membership proof.</param> /// <param name="setValues">Set values to verify against.</param> /// <returns>True if the proof is valid, false otherwise.</returns> public static bool Verify(VerifierPresentationProtocolParameters vppp, PresentationProof pProof, SetMembershipProof smProof, int committedIndex, byte[][] setValues) { // get the index of the commitment to use, given the underlying attribute's index int commitmentIndex = ClosedPedersenCommitment.GetCommitmentIndex(vppp.Committed, committedIndex); // verify the membership proof ClosedDLRepOfGroupElement closedCommittedClearance = new ClosedPedersenCommitment(vppp.IP, pProof, commitmentIndex); VerifierSetMembershipParameters setVerifier = new VerifierSetMembershipParameters( closedCommittedClearance.Value, VerifierSetMembershipParameters.GenerateMemberSet(vppp.IP, committedIndex, setValues), new CryptoParameters(vppp.IP)); return(smProof.Verify(setVerifier)); }
/// <summary> /// Creates a Pedersen Commitment for one of the attributes using the commitment /// from the PresentationProof. /// </summary> /// <param name="pppp">Parameters used by Prover</param> /// <param name="pp">The presentation proof generated by the Prover</param> /// <param name="cpv">Output of PresentationProof.Generate()</param> /// <param name="commitmentIndex">Which commitment to use: index into cpv.TildeO array. /// DO NOT use the attribute index, the Constructor will compute it from /// the commitmentIndex.</param> public PedersenCommitment(ProverPresentationProtocolParameters pppp, PresentationProof pp, CommitmentPrivateValues cpv, int commitmentIndex) { int attributeIndex = pppp.Committed[commitmentIndex] - 1; FieldZqElement committedValue = ProtocolHelper.ComputeXi(pppp.IP, attributeIndex, pppp.Attributes[attributeIndex]); FieldZqElement opening = cpv.TildeO[commitmentIndex]; CryptoParameters crypto = new CryptoParameters(pppp.IP); this.Group = crypto.Group; this.Bases = new GroupElement[2] { crypto.Generators[0], crypto.Generators[1] }; this.Exponents = new FieldZqElement[2] { committedValue, opening }; this.Value = pp.Commitments[commitmentIndex].TildeC; }
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)); }
/// <summary> /// first method to call - Initializes the ProverProof by generating the PresentationProof /// </summary> /// <param name="ip">IssuerParameter from the Issuer of the given token</param> /// <param name="attributes">Attributes which are included in the given token</param> /// <param name="proofRequirements">Necessary informations for creating the proofs (e.g. disclosedAttributes)</param> /// <param name="tokenWithKey">Token for which the proof will be done</param> /// <param name="supportedDateAttributes">If there is a RangeProof done, all date attributes where treated and formated especially</param> /// <param name="devicePresentationContext">If there was a device involved during the token generation, the context from the device is needed to generate the /// PresentationProof as well</param> /// <returns>returns the proof for the given token as json object or an error</returns> public string Init(IssuerParameters ip, List <BasicClaim> attributes, ProofRequirements proofRequirements, UProveKeyAndToken tokenWithKey, List <string> supportedDateAttributes, IDevicePresentationContext devicePresentationContext) { try { LogService.Log(LogService.LogType.Info, "ProverProof - init called"); this.ip = ip; this.proofRequirements = proofRequirements; ci.CreateBase64ForAttributeList(attributes, supportedDateAttributes, out rangeProofProperties); attributesToInclude = ci.ConvertAttributeListToBase64ByteArray(attributes); pppp = new ProverPresentationProtocolParameters(this.ip, proofRequirements.disclosedAttributes, proofRequirements.message, tokenWithKey, attributesToInclude); pppp.Committed = proofRequirements.committedAttributes; //// TODO //// if a scope is defined, we use the first attribute to derive a scope exclusive pseudonym //pppp.PseudonymAttributeIndex = (proofRequirements.scope == null ? 0 : 1); //pppp.PseudonymScope = proofRequirements.scope; // add device presentation context to the provers presentation context if (this.ip.IsDeviceSupported && devicePresentationContext != null) { pppp.SetDeviceData(proofRequirements.deviceMessage, devicePresentationContext); } // generate proof PresentationProof pProof = PresentationProof.Generate(pppp, out cpv); LogService.Log(LogService.LogType.Info, "ProverProof - init presentation proof generated"); proof = parser.ParseJsonToObject <Proof>(this.ip.Serialize <PresentationProof>(pProof)); proof.requirements = proofRequirements; string proofJson = parser.ParseObjectToJson(proof); LogService.Log(LogService.LogType.Info, "ProverProof - proof created: " + proofJson); return(proofJson); } catch (Exception e) { LogService.Log(LogService.LogType.FatalError, "ProverProof - Error during prover setup.", e); throw new CommunicationException("ProverProof - Error during ProverProof init; " + e); } }
public void GenerateNonRevocationProofTest() { RAParameters rap = RA.RAParameters; HashSet <FieldZqElement> revokedValues = new HashSet <FieldZqElement>(rap.group.FieldZq.GetRandomElements(10, false)); RA.UpdateAccumulator(revokedValues); // generate proof when xid is not revoked byte[] message = new byte[] { (byte)0 }; ProverPresentationProtocolParameters pppp = new ProverPresentationProtocolParameters(ip, null, message, upkt, attributes); pppp.Committed = new int[] { 1 }; CommitmentPrivateValues cpv; PresentationProof pp = PresentationProof.Generate(pppp, out cpv); int revocationCommitmentIndex = 0; NonRevocationProof nrp = RevocationUser.GenerateNonRevocationProof(ip, rap, RA.ComputeRevocationWitness(revokedValues, xid), revocationCommitmentIndex, pp, cpv, 1, attributes); RA.VerifyNonRevocationProof(ip, revocationCommitmentIndex, pp, nrp); }
public void PresentationProofConstructorTest() { // generate array of commitments using PresentationProof CommitmentPrivateValues cpv; Assert.IsNotNull(_proverParams, "prover params null"); PresentationProof proof = PresentationProof.Generate(_proverParams, out cpv); Assert.IsNotNull(proof.Commitments, "proof failed to generate commitments"); Assert.IsNotNull(cpv, "failed to output cpv"); Assert.IsNotNull(cpv.TildeO, "cpv.TildeO is null"); CommitmentValues [] expectedCommitmentValues = proof.Commitments; // generate array of commitments using Pedersen Commitment constructor PedersenCommitment [] proverCommitments = PedersenCommitment.ArrayOfPedersenCommitments(_proverParams, proof, cpv); // compare values GroupElement expectedG = _proverParams.IP.Gq.G; GroupElement expectedH = _proverParams.IP.G[1]; for (int commitIndex = 0; commitIndex < expectedCommitmentValues.Length; ++commitIndex) { int attributeIndex = _proverParams.Committed[commitIndex] - 1; FieldZqElement expectedCommittedValue = ProtocolHelper.ComputeXi(_proverParams.IP, attributeIndex, _proverParams.Attributes[attributeIndex]); Assert.AreEqual(expectedCommittedValue, proverCommitments[commitIndex].CommittedValue, "wrong committed value"); Assert.AreEqual(cpv.TildeO[commitIndex], proverCommitments[commitIndex].Opening, "opening does not match tildeO"); Assert.AreEqual(expectedG, proverCommitments[commitIndex].G, "base g wrong"); Assert.AreEqual(expectedH, proverCommitments[commitIndex].H, "base h wrong"); Assert.AreEqual(expectedCommitmentValues[commitIndex].TildeC, proverCommitments[commitIndex].Value, "wrong value"); } // generate array of closed pedersen commitments ClosedPedersenCommitment[] verifierCommitments = ClosedPedersenCommitment.ArrayOfClosedPedersenCommitments(_verifierParams.IP, proof); // compare bases and values to actualCommitments Assert.IsTrue(ClosedPedersenCommitment.AreBasesEqual(verifierCommitments), "all closed commitments should have same bases."); Assert.IsTrue(verifierCommitments[0].AreBasesEqual(proverCommitments[0]), "all closed commitments should have same bases as open commitments"); Assert.AreEqual(proverCommitments.Length, verifierCommitments.Length, "should be as many open and closed commitments"); for (int i = 0; i < verifierCommitments.Length; ++i) { Assert.AreEqual(verifierCommitments[i].Value, proverCommitments[i].Value, "open and closed commitments should be equal."); } }
public static PresentationProofComposite convertPresentationProof(PresentationProof p, BigInteger[] commitmentValues, byte[] tokenId, byte[] proofSession) { PresentationProofComposite pc = new PresentationProofComposite(); pc.A = p.A; pc.Ap = (p.Ap == null ? null : p.Ap); pc.DisclosedAttributes = p.DisclosedAttributes; pc.Ps = (p.Ps == null ? null : p.Ps.GetEncoded()); byte[][] byteArray = new byte[p.R.Length][]; for (int i = 0; i < byteArray.Length; i++) { byteArray[i] = p.R[i].ToByteArray(); } pc.R = byteArray; if (p.Commitments != null) { pc.TildeValues = new byte[3 * p.Commitments.Length][]; for (int i = 0; i < p.Commitments.Length; i++) { pc.TildeValues[(i * 3)] = p.Commitments[i].TildeC.GetEncoded(); pc.TildeValues[(i * 3) + 1] = p.Commitments[i].TildeA; pc.TildeValues[(i * 3) + 2] = p.Commitments[i].TildeR.ToByteArray(); } } if (commitmentValues != null) { if (commitmentValues.Length != p.Commitments.Length) { throw new ArgumentException("inconsistent commitment values"); } pc.TildeO = new byte[commitmentValues.Length][]; for (int i = 0; i < commitmentValues.Length; i++) { pc.TildeO[i] = commitmentValues[i].ToByteArray(); } } pc.TokenID = tokenId; pc.MessageD = (proofSession == null ? null : proofSession); return(pc); }
public static PresentationProof convertPresentationProofComposite(IssuerParameters ip, PresentationProofComposite pc, out byte[] tokenID, out byte[] proofSession) { PresentationProof p = new PresentationProof(); p.A = (pc.A == null ? null : pc.A); p.Ap = (pc.Ap == null ? null : pc.Ap); p.DisclosedAttributes = pc.DisclosedAttributes; p.Ps = (pc.Ps == null ? null : ip.Gq.CreateGroupElement(pc.Ps)); BigInteger[] biArray = new BigInteger[pc.R.Length]; for (int i = 0; i < biArray.Length; i++) { biArray[i] = new BigInteger(1, pc.R[i]); } p.R = biArray; if (pc.TildeValues != null) { int numCommitments = pc.TildeValues.Length / 3; p.Commitments = new CommitmentValues[numCommitments]; for (int i = 0; i < numCommitments; i++) { p.Commitments[i] = new CommitmentValues( ip.Gq.CreateGroupElement(pc.TildeValues[(i * 3)]), // tildeC pc.TildeValues[(i * 3) + 1], // tildaA new BigInteger(1, pc.TildeValues[(i * 3) + 2]) // tildeR ); } // we ignore the tildeO values. This method is called by the verifier, and // the tildeO values should never be sent to the verifier. } tokenID = pc.TokenID; proofSession = (pc.MessageD == null ? null : pc.MessageD); return(p); }
/// <summary> /// Verifies if the given json message has sent a correct proof /// the result is written into proofVerification.Proof /// Init must called first /// </summary> private void VerifyProof() { LogService.Log(LogService.LogType.Info, "IssuingVerifier - VerifyProof called"); if (!isInitialized) { proofAccepted = false; tokenAccepted = false; throw new Exception("VerifyProof - Init must be called first"); } int[] disclosedAttributes = proofRequirements.disclosedAttributes; int[] committedAttributes = proofRequirements.committedAttributes; byte[] message = proofRequirements.message; byte[] scope = proofRequirements.scope; byte[] deviceMessage = proofRequirements.deviceMessage; vppp = new VerifierPresentationProtocolParameters(IP, disclosedAttributes, message, IP.Deserialize <UProveToken>(tokenJson)); vppp.Committed = committedAttributes; // 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; try { pProof = IP.Deserialize <PresentationProof>(proofJson); pProof.Verify(vppp); } catch (InvalidUProveArtifactException e) { LogService.Log(LogService.LogType.FatalError, "IssuingVerifier - Proof verification failed", e); throw new Exception("VerifyProof - Proof verification failed", e); } proofAccepted = true; tokenAccepted = true; LogService.Log(LogService.LogType.Info, "IssuingVerifier - Proof passed tests"); }
/// <summary> /// Computes the non-revocation proof. /// </summary> /// <param name="ip">The Issuer parameters associated with the presented U-Prove token.</param> /// <param name="rap">The Revocation Authority parameters.</param> /// <param name="witness">The user non-revocation witness.</param> /// <param name="commitmentIndex">The 0-based index of the revocation commitment in the attribute commitments.</param> /// <param name="presentationProof">The presentation proof generated with the U-Prove token.</param> /// <param name="cpv">The commitment private values generated when presenting the U-Prove token.</param> /// <param name="revocationIndex">The 1-based index of the revocation attribute in the U-Prove token.</param> /// <param name="attributes">The token attributes.</param> /// <returns>A non-revocation proof.</returns> public static NonRevocationProof GenerateNonRevocationProof(IssuerParameters ip, RAParameters rap, RevocationWitness witness, int commitmentIndex, PresentationProof presentationProof, CommitmentPrivateValues cpv, int revocationIndex, byte[][] attributes) { if (revocationIndex <= 0) { throw new ArgumentException("revocationIndex must be positive: " + revocationIndex); } GroupElement tildeCid = presentationProof.Commitments[commitmentIndex].TildeC; FieldZqElement xid = ProtocolHelper.ComputeXi(ip, revocationIndex - 1, attributes[revocationIndex - 1]); FieldZqElement tildeOid = cpv.TildeO[commitmentIndex]; return(GenerateNonRevocationProof(rap, witness, tildeCid, xid, tildeOid)); }
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"); }
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); }
public void DevicePseudonymTest() { // 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(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); }
/// <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)); }
public void LongTest() { int numberOfAttribs = 25; // Issuer setup IssuerSetupParameters isp = new IssuerSetupParameters(numberOfAttribs); isp.UidP = new byte[] { 1, 2, 3, 4, 5, 6, 7, 8, 9 }; // isp.E = new byte[numberOfAttribs]; // extension by Fablei -> do not change MaxNumberOfAttributes 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); } }
/// <summary> /// Creates an array of Pedersen Commitments from the ProverPresentationProtocolParameters /// and the CommitmentPrivateValues. This is a convenience method for generating the /// Pedersen commitments output by the PresentationProof.Generate() method. /// </summary> /// <param name="pppp">The Prover parameters.</param> /// <param name="pp">The presentation proof.</param> /// <param name="cpv">The commitment private values.</param> /// <returns></returns> public static PedersenCommitment [] ArrayOfPedersenCommitments(ProverPresentationProtocolParameters pppp, PresentationProof pp, CommitmentPrivateValues cpv) { PedersenCommitment[] pedersenCommitments = new PedersenCommitment[cpv.TildeO.Length]; for (int index = 0; index < pedersenCommitments.Length; ++index) { pedersenCommitments[index] = new PedersenCommitment(pppp, pp, cpv, index); } return(pedersenCommitments); }
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(maxNumberOfAttributes); 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, maxNumberOfAttributes); ip2.S = encoding.GetBytes("wrong issuer params"); try { proof.Verify(ip2, disclosed, message, null, upkt[i].Token); Assert.Fail(); } catch (InvalidUProveArtifactException) { } // modify disclosed list int[] disclosed2; if (disclosed.Length == 0) { disclosed2 = new int[] { 1 }; } else { disclosed2 = new int[] { }; } try { proof.Verify(ip, disclosed2, message, deviceMessage, upkt[i].Token); Assert.Fail(); } catch (InvalidUProveArtifactException) { } // modify message try { proof.Verify(ip, disclosed, encoding.GetBytes("wrong message"), deviceMessage, upkt[i].Token); Assert.Fail(); } catch (InvalidUProveArtifactException) { } // modify token try { proof.Verify(ip, disclosed, message, deviceMessage, upkt[(i + 1) % numberOfTokens].Token); Assert.Fail(); } catch (InvalidUProveArtifactException) { } // modify proof proof.A = encoding.GetBytes("wrong proof"); try { proof.Verify(ip, disclosed, message, deviceMessage, upkt[i].Token); Assert.Fail(); } catch (InvalidUProveArtifactException) { } } } } } } } } }
/// <summary> /// Returns all Closed Pedersen Commitments associated with a presentation proof. /// This is a UProve integration function that is called by the verifier. /// </summary> /// <param name="ip">Issuer Parameters</param> /// <param name="proof">Instance of the proof presentation protocol</param> /// <returns></returns> public static ClosedPedersenCommitment[] ArrayOfClosedPedersenCommitments(IssuerParameters ip, PresentationProof proof) { ClosedPedersenCommitment[] closedPed = new ClosedPedersenCommitment[proof.Commitments.Length]; for (int i = 0; i < closedPed.Length; ++i) { closedPed[i] = new ClosedPedersenCommitment(ip, proof, i); } return(closedPed); }
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(numberOfAttributes); isp.GroupConstruction = useSubgroupConstruction ? GroupType.Subgroup : GroupType.ECC; isp.UidP = GetRandomBytes(MaxByteArrayLength); isp.UidH = hashFunction; //isp.E = IssuerSetupParameters.GetDefaultEValues(numberOfAttributes); // extension by Fablei -> do not change MaxNumberOfAttributes 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 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 }
/// <summary> /// Generates a set membership proof from U-Prove parameters. /// </summary> /// <param name="pppp">The prover presentation protocol parameters.</param> /// <param name="pp">The presentation proof.</param> /// <param name="cpv">The commitment private values returned when generating the presentation proof.</param> /// <param name="committedIndex">Index of the committed attribute used to generate the set membership proof.</param> /// <param name="setValues">Set values to prove against.</param> /// <param name="smRandom">Optional pregenerated random values, or <c>null</c>.</param> /// <returns>A set membership proof.</returns> public static SetMembershipProof Generate(ProverPresentationProtocolParameters pppp, PresentationProof pp, CommitmentPrivateValues cpv, int committedIndex, byte[][] setValues, SetMembershipProofGenerationRandomData smRandom = null) { // get the index of the commitment to use, given the underlying attribute's index int commitmentIndex = ClosedPedersenCommitment.GetCommitmentIndex(pppp.Committed, committedIndex); // generate the membership proof ProverSetMembershipParameters setProver = new ProverSetMembershipParameters( new PedersenCommitment(pppp, pp, cpv, commitmentIndex), VerifierSetMembershipParameters.GenerateMemberSet(pppp.IP, committedIndex, setValues), new CryptoParameters(pppp.IP)); return(new SetMembershipProof(setProver, smRandom)); }
/// <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 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)); }