public static PresentationProof Generate(IssuerParameters ip, int[] disclosed, int[] committed, int pseudonymAttribIndex, byte[] pseudonymScope, byte[] message, byte[] messageD, IDevicePresentationContext deviceContext, UProveKeyAndToken upkt, byte[][] attributes, ProofGenerationRandomData preGenW, out FieldZqElement[] tildeO) { GroupElement gs = ProtocolHelper.GenerateScopeElement(ip.Gq, pseudonymScope); return Generate(ip, disclosed, committed, pseudonymAttribIndex, gs, message, messageD, deviceContext, upkt, attributes, preGenW, out tildeO); }
public static PresentationProof Generate(IssuerParameters ip, int[] disclosed, int[] committed, int pseudonymAttribIndex, GroupElement gs, byte[] message, byte[] messageD, IDevicePresentationContext deviceContext, UProveKeyAndToken upkt, byte[][] attributes, ProofGenerationRandomData preGenW, out FieldZqElement[] tildeO) { CommitmentPrivateValues cpv; PresentationProof proof = Generate(ip, disclosed, committed, pseudonymAttribIndex, gs, message, messageD, deviceContext, upkt, attributes, preGenW, out cpv); tildeO = cpv.TildeO; return proof; }
/// <summary> /// Generates a presentation proof including optionally presenting a pseudonym, creating attribute commitments, and passing pre-generated random values. /// </summary> /// <param name="ip">The issuer parameters corresponding to <code>upkt</code>.</param> /// <param name="disclosed">An ordered array of disclosed attribute indices.</param> /// <param name="committed">An ordered array of committed attribute indices.</param> /// <param name="pseudonymAttribIndex">Index of the attribute used to create a scope-exclusive pseudonym, or 0 if no pseudonym is to be presented. The index must not be part of the disclosed attributes.</param> /// <param name="gs">The pseudonym scope element, or null if no pseudonym is to be presented.</param> /// <param name="message">The presentation message.</param> /// <param name="messageD">The message for the Device, or null.</param> /// <param name="deviceContext">The active device context, if token is device-protected, or null.</param> /// <param name="upkt">The U-Proke key and token.</param> /// <param name="attributes">The token attributes.</param> /// <param name="preGenW">Optional pregenerated random data for the proof generation.</param> /// <param name="cpv">Returned commitment private values if commitments are computed.</param> /// <returns>A presentation proof.</returns> internal static PresentationProof Generate(IssuerParameters ip, int[] disclosed, int[] committed, int pseudonymAttribIndex, GroupElement gs, byte[] message, byte[] messageD, IDevicePresentationContext deviceContext, UProveKeyAndToken upkt, byte[][] attributes, ProofGenerationRandomData preGenW, out CommitmentPrivateValues cpv) { if (upkt.Token.IsDeviceProtected && deviceContext == null) { throw new ArgumentNullException("Device context is not initialized"); } bool generateCommitments = (committed != null && committed.Length > 0); FieldZqElement[] tildeO = null; // make sure disclosed and committed lists are sorted if (disclosed == null) { // can't be null later, so make it an empty array disclosed = new int[] { }; } Array.Sort(disclosed); if (generateCommitments) { Array.Sort(committed); } int n = 0; if (ip.E != null) n = ip.E.Length; bool presentPseudonym = false; if (gs != null) { if (pseudonymAttribIndex < 1 || (pseudonymAttribIndex > n && pseudonymAttribIndex != DeviceAttributeIndex)) { throw new ArgumentException("pseudonymAttribIndex must be between 1 and " + n + " (inclusive)"); } if (disclosed.Contains(pseudonymAttribIndex)) { throw new ArgumentException("pseudonymAttribIndex cannot be in the disclosed attribute array"); } presentPseudonym = true; } else if (pseudonymAttribIndex > 0) { throw new ArgumentNullException("gs is null"); } else { pseudonymAttribIndex = 0; } Group Gq = ip.Gq; FieldZq Zq = ip.Zq; FieldZqElement xt = ProtocolHelper.ComputeXt(ip, upkt.Token.TI, upkt.Token.IsDeviceProtected); ProofGenerationRandomData random; if (preGenW == null) { random = ProofGenerationRandomData.Generate(n - disclosed.Length, generateCommitments ? committed.Length : 0, Zq, upkt.Token.IsDeviceProtected); } else { random = preGenW; } FieldZqElement[] x = new FieldZqElement[n]; GroupElement temp = upkt.Token.H.Exponentiate(random.W0); int uIndex = 0; int dIndex = 0; int cIndex = 0; PresentationProof proof = new PresentationProof(); proof.DisclosedAttributes = new byte[disclosed.Length][]; int pseudonymRandomizerIndex = 0; if (generateCommitments) { proof.Commitments = new CommitmentValues[committed.Length]; tildeO = new FieldZqElement[committed.Length]; } HashFunction hash = ip.HashFunction; for (int i = 0; i < n; i++) { x[i] = ProtocolHelper.ComputeXi(ip, i, attributes[i]); if (!disclosed.Contains(i + 1)) { temp = temp * ip.G[i + 1].Exponentiate(random.W[uIndex]); if (presentPseudonym) { if (pseudonymAttribIndex == (i + 1)) { pseudonymRandomizerIndex = uIndex; } } if (generateCommitments && committed.Contains(i + 1)) { GroupElement tildeC = ip.Gq.G.Exponentiate(x[i]) * ip.G[1].Exponentiate(random.TildeO[cIndex]); tildeO[cIndex] = random.TildeO[cIndex]; GroupElement temp2 = ip.Gq.G.Exponentiate(random.W[uIndex]) * ip.G[1].Exponentiate(random.TildeW[cIndex]); hash.Hash(temp2); byte[] tildeA = hash.Digest; proof.Commitments[cIndex] = new CommitmentValues(tildeC, tildeA, null); cIndex++; } uIndex++; } else if (generateCommitments && committed.Contains(i + 1)) { throw new ArgumentException("attribute " + (i + 1) + " cannot be both disclosed and committed"); } else { proof.DisclosedAttributes[dIndex] = attributes[i]; dIndex++; } } if (upkt.Token.IsDeviceProtected) { GroupElement ad; // pseudonym computed by device if (presentPseudonym && pseudonymAttribIndex == DeviceAttributeIndex) { GroupElement apPrime; GroupElement Ps; ad = deviceContext.GetInitialWitnessesAndPseudonym(gs, out apPrime, out Ps); hash.Hash(apPrime * gs.Exponentiate(random.Wd)); proof.Ap = hash.Digest; proof.Ps = Ps; } else { ad = deviceContext.GetInitialWitness(); } temp = temp * ip.Gd.Exponentiate(random.Wd) * ad; } hash.Hash(temp); proof.a = hash.Digest; // pseudonym derived from one token attribute if (presentPseudonym && pseudonymAttribIndex != DeviceAttributeIndex) { hash.Hash(gs.Exponentiate(random.W[pseudonymRandomizerIndex])); proof.Ap = hash.Digest; proof.Ps = gs.Exponentiate(x[pseudonymAttribIndex - 1]); } byte[] mdPrime; FieldZqElement c = ProtocolHelper.GenerateChallenge(ip, upkt.Token, proof.a, pseudonymAttribIndex, proof.ap, proof.Ps, message, messageD, disclosed, GetDisclosedX(disclosed, x), committed, proof.Commitments, out mdPrime); proof.r = new FieldZqElement[1 + n - disclosed.Length + (upkt.Token.IsDeviceProtected ? 1 : 0)]; // r_0, {r_i} for undisclosed i, r_d proof.r[0] = c * upkt.PrivateKey + random.W0; uIndex = 1; for (int i = 1; i <= n; i++) { if (!disclosed.Contains(i)) { proof.r[uIndex] = c.Negate() * x[i - 1] + random.W[uIndex - 1]; uIndex++; } } if (upkt.Token.IsDeviceProtected) { proof.r[proof.r.Length - 1] = deviceContext.GetDeviceResponse(messageD, mdPrime, ip.HashFunctionOID) + random.Wd; } if (generateCommitments) { for (int i = 0; i < committed.Length; i++) { proof.Commitments[i].TildeR = c.Negate() * random.TildeO[i] + random.TildeW[i]; } } random.Clear(); cpv = new CommitmentPrivateValues(tildeO); return proof; }
public static PresentationProof Generate(IssuerParameters ip, int[] disclosed, int[] committed, int pseudonymAttribIndex, byte[] pseudonymScope, byte[] message, byte[] messageD, IDevicePresentationContext deviceContext, UProveKeyAndToken upkt, byte[][] attributes, ProofGenerationRandomData preGenW, out FieldZqElement[] tildeO) { GroupElement gs = ProtocolHelper.GenerateScopeElement(ip.Gq, pseudonymScope); return(Generate(ip, disclosed, committed, pseudonymAttribIndex, gs, message, messageD, deviceContext, upkt, attributes, preGenW, out tildeO)); }
public static PresentationProof Generate(IssuerParameters ip, int[] disclosed, int[] committed, int pseudonymAttribIndex, GroupElement gs, byte[] message, byte[] messageD, IDevicePresentationContext deviceContext, UProveKeyAndToken upkt, byte[][] attributes, ProofGenerationRandomData preGenW, out FieldZqElement[] tildeO) { CommitmentPrivateValues cpv; PresentationProof proof = Generate(ip, disclosed, committed, pseudonymAttribIndex, gs, message, messageD, deviceContext, upkt, attributes, preGenW, out cpv); tildeO = cpv.TildeO; return(proof); }
/// <summary> /// Generates a presentation proof including optionally presenting a pseudonym, creating attribute commitments, and passing pre-generated random values. /// </summary> /// <param name="ip">The issuer parameters corresponding to <code>upkt</code>.</param> /// <param name="disclosed">An ordered array of disclosed attribute indices.</param> /// <param name="committed">An ordered array of committed attribute indices.</param> /// <param name="pseudonymAttribIndex">Index of the attribute used to create a scope-exclusive pseudonym, or 0 if no pseudonym is to be presented. The index must not be part of the disclosed attributes.</param> /// <param name="gs">The pseudonym scope element, or null if no pseudonym is to be presented.</param> /// <param name="message">The presentation message.</param> /// <param name="messageD">The message for the Device, or null.</param> /// <param name="deviceContext">The active device context, if token is device-protected, or null.</param> /// <param name="upkt">The U-Proke key and token.</param> /// <param name="attributes">The token attributes.</param> /// <param name="preGenW">Optional pregenerated random data for the proof generation.</param> /// <param name="cpv">Returned commitment private values if commitments are computed.</param> /// <returns>A presentation proof.</returns> internal static PresentationProof Generate(IssuerParameters ip, int[] disclosed, int[] committed, int pseudonymAttribIndex, GroupElement gs, byte[] message, byte[] messageD, IDevicePresentationContext deviceContext, UProveKeyAndToken upkt, byte[][] attributes, ProofGenerationRandomData preGenW, out CommitmentPrivateValues cpv) { if (upkt.Token.IsDeviceProtected && deviceContext == null) { throw new ArgumentNullException("Device context is not initialized"); } bool generateCommitments = (committed != null && committed.Length > 0); FieldZqElement[] tildeO = null; // make sure disclosed and committed lists are sorted if (disclosed == null) { // can't be null later, so make it an empty array disclosed = new int[] { }; } Array.Sort(disclosed); if (generateCommitments) { Array.Sort(committed); } int n = 0; if (ip.E != null) { n = ip.E.Length; if (n != attributes.Length) { throw new ArgumentException("number of attributes is inconsistent with issuer parameters"); } } bool presentPseudonym = false; if (gs != null) { if (pseudonymAttribIndex < 1 || (pseudonymAttribIndex > n && pseudonymAttribIndex != DeviceAttributeIndex)) { throw new ArgumentException("pseudonymAttribIndex must be between 1 and " + n + " (inclusive)"); } if (disclosed.Contains(pseudonymAttribIndex)) { throw new ArgumentException("pseudonymAttribIndex cannot be in the disclosed attribute array"); } presentPseudonym = true; } else if (pseudonymAttribIndex > 0) { throw new ArgumentNullException("gs is null"); } else { pseudonymAttribIndex = 0; } Group Gq = ip.Gq; FieldZq Zq = ip.Zq; FieldZqElement xt = ProtocolHelper.ComputeXt(ip, upkt.Token.TI, upkt.Token.IsDeviceProtected); ProofGenerationRandomData random; if (preGenW == null) { random = ProofGenerationRandomData.Generate(n - disclosed.Length, generateCommitments ? committed.Length : 0, Zq, upkt.Token.IsDeviceProtected); } else { random = preGenW; } // set up the multi-exponentiation arrays, with h^w0 as the first term int multiExpArraySize = 1 + (n - disclosed.Length) + (upkt.Token.IsDeviceProtected ? 1 : 0); GroupElement[] bases = new GroupElement[multiExpArraySize]; FieldZqElement[] exponents = new FieldZqElement[multiExpArraySize]; int multiExpIndex = 0; bases[multiExpIndex] = upkt.Token.H; exponents[multiExpIndex++] = random.W0; FieldZqElement[] x = new FieldZqElement[n]; int uIndex = 0; int dIndex = 0; int cIndex = 0; PresentationProof proof = new PresentationProof(); proof.DisclosedAttributes = new byte[disclosed.Length][]; int pseudonymRandomizerIndex = 0; if (generateCommitments) { proof.Commitments = new CommitmentValues[committed.Length]; tildeO = new FieldZqElement[committed.Length]; } HashFunction hash = ip.HashFunction; GroupElement[] cBases = new GroupElement[2] { Gq.G, ip.G[1] }; for (int i = 0; i < n; i++) { x[i] = ProtocolHelper.ComputeXi(ip, i, attributes[i]); if (!disclosed.Contains(i + 1)) { bases[multiExpIndex] = ip.G[i + 1]; exponents[multiExpIndex++] = random.W[uIndex]; if (presentPseudonym) { if (pseudonymAttribIndex == (i + 1)) { pseudonymRandomizerIndex = uIndex; } } if (generateCommitments && committed.Contains(i + 1)) { GroupElement tildeC = ip.Gq.MultiExponentiate(cBases, new FieldZqElement[2] { x[i], random.TildeO[cIndex] }); tildeO[cIndex] = random.TildeO[cIndex]; GroupElement temp2 = ip.Gq.MultiExponentiate(cBases, new FieldZqElement[2] { random.W[uIndex], random.TildeW[cIndex] }); hash.Hash(temp2); byte[] tildeA = hash.Digest; proof.Commitments[cIndex] = new CommitmentValues(tildeC, tildeA, null); cIndex++; } uIndex++; } else if (generateCommitments && committed.Contains(i + 1)) { throw new ArgumentException("attribute " + (i + 1) + " cannot be both disclosed and committed"); } else { proof.DisclosedAttributes[dIndex] = attributes[i]; dIndex++; } } GroupElement aPreImage; if (upkt.Token.IsDeviceProtected) { GroupElement ad; // pseudonym computed by device if (presentPseudonym && pseudonymAttribIndex == DeviceAttributeIndex) { GroupElement apPrime; GroupElement Ps; ad = deviceContext.GetInitialWitnessesAndPseudonym(gs, out apPrime, out Ps); hash.Hash(apPrime * gs.Exponentiate(random.Wd)); proof.Ap = hash.Digest; proof.Ps = Ps; } else { ad = deviceContext.GetInitialWitness(); } bases[multiExpIndex] = ip.Gd; exponents[multiExpIndex++] = random.Wd; aPreImage = Gq.MultiExponentiate(bases, exponents) * ad; } else { aPreImage = Gq.MultiExponentiate(bases, exponents); } hash.Hash(aPreImage); proof.a = hash.Digest; // pseudonym derived from one token attribute if (presentPseudonym && pseudonymAttribIndex != DeviceAttributeIndex) { hash.Hash(gs.Exponentiate(random.W[pseudonymRandomizerIndex])); proof.Ap = hash.Digest; proof.Ps = gs.Exponentiate(x[pseudonymAttribIndex - 1]); } byte[] mdPrime; FieldZqElement c = ProtocolHelper.GenerateChallenge(ip, upkt.Token, proof.a, pseudonymAttribIndex, proof.ap, proof.Ps, message, messageD, disclosed, GetDisclosedX(disclosed, x), committed, proof.Commitments, out mdPrime); proof.r = new FieldZqElement[1 + n - disclosed.Length + (upkt.Token.IsDeviceProtected ? 1 : 0)]; // r_0, {r_i} for undisclosed i, r_d proof.r[0] = c * upkt.PrivateKey + random.W0; uIndex = 1; for (int i = 1; i <= n; i++) { if (!disclosed.Contains(i)) { proof.r[uIndex] = c.Negate() * x[i - 1] + random.W[uIndex - 1]; uIndex++; } } if (upkt.Token.IsDeviceProtected) { proof.r[proof.r.Length - 1] = deviceContext.GetDeviceResponse(messageD, mdPrime, ip.HashFunctionOID) + random.Wd; } if (generateCommitments) { for (int i = 0; i < committed.Length; i++) { proof.Commitments[i].TildeR = c.Negate() * random.TildeO[i] + random.TildeW[i]; } } random.Clear(); cpv = new CommitmentPrivateValues(tildeO); return(proof); }