/// <summary> /// Constructs a <code>VerifierPresentationProtocolParameters</code> instance. /// </summary> /// <param name="ip">The issuer parameters.</param> /// <param name="disclosed">Disclosed attribute indices.</param> /// <param name="message">Presentation message.</param> /// <param name="token">Presented token.</param> public VerifierPresentationProtocolParameters(IssuerParameters ip, int[] disclosed, byte[] message, UProveToken token) { IP = ip; Disclosed = disclosed; Message = message; Token = token; }
/// <summary> /// Verifies a U-Prove token signature. /// </summary> /// <param name="ip">The Issuer parameters corresponding to the U-Prove token.</param> /// <param name="upt">The U-Prove token to verify.</param> /// <exception cref="InvalidUProveArtifactException">If the U-Prove token is invalid.</exception> public static void VerifyTokenSignature(IssuerParameters ip, UProveToken upt) { Group Gq = ip.Gq; FieldZq Zq = ip.Zq; if (upt.H == Gq.Identity) { throw new InvalidUProveArtifactException("Invalid U-Prove token (public key H = 1)"); } GroupElement[] bases = new GroupElement[2]; FieldZqElement[] exponents = new FieldZqElement[2]; HashFunction hash = ip.HashFunction; hash.Hash(upt.H); hash.Hash(upt.PI); hash.Hash(upt.SigmaZPrime); bases[0] = Gq.G; exponents[0] = upt.SigmaRPrime; bases[1] = ip.G[0]; exponents[1] = upt.SigmaCPrime.Negate(); hash.Hash(Gq.MultiExponentiate(bases, exponents)); bases[0] = upt.H; exponents[0] = upt.SigmaRPrime; bases[1] = upt.SigmaZPrime; exponents[1] = upt.SigmaCPrime.Negate(); hash.Hash(Gq.MultiExponentiate(bases, exponents)); if (upt.SigmaCPrime != Zq.GetElementFromDigest(hash.Digest)) { throw new InvalidUProveArtifactException("Invalid U-Prove token signature"); } }
/// <summary> /// Computes the U-Prove token identifier. /// </summary> /// <param name="ip">The issuer parameters associated with <code>upt</code>.</param> /// <param name="upt">The U-Prove token from which to compute the identifier.</param> /// <returns></returns> public static byte[] ComputeTokenID(IssuerParameters ip, UProveToken upt) { HashFunction hash = ip.HashFunction; hash.Hash(upt.H); hash.Hash(upt.SigmaZPrime); hash.Hash(upt.SigmaCPrime); hash.Hash(upt.SigmaRPrime); return(hash.Digest); }
internal static FieldZqElement GenerateChallenge(IssuerParameters ip, UProveToken upt, byte[] a, int pseudonymIndex, byte[] ap, GroupElement Ps, byte[] m, byte[] md, int[] disclosed, FieldZqElement[] disclosedX, int[] committed, CommitmentValues[] commitments, out byte[] mdPrime) { bool hasCommitments = (committed != null && committed.Length > 0); if (hasCommitments) { if (committed.Length != commitments.Length) { throw new ArgumentException("Inconsistent committed indices and commitment values"); } } HashFunction hash = ip.HashFunction; hash.Hash(ComputeTokenID(ip, upt)); hash.Hash(a); hash.Hash(disclosed); hash.Hash(disclosedX); if (!hasCommitments) { hash.HashNull(); // C hash.HashNull(); // < {tildeC} > hash.HashNull(); // < {tildeA} > } else { hash.Hash(committed); hash.Hash(commitments.Length); // length of < {tildeC} > for (int i = 0; i < commitments.Length; i++) { hash.Hash(commitments[i].TildeC); } hash.Hash(commitments.Length); // length of < {tildeA} > for (int i = 0; i < commitments.Length; i++) { hash.Hash(commitments[i].TildeA); } } hash.Hash(pseudonymIndex == PresentationProof.DeviceAttributeIndex ? 0 : pseudonymIndex); hash.Hash(ap); hash.Hash(Ps); hash.Hash(m); mdPrime = hash.Digest; if (upt.IsDeviceProtected) { hash = ip.HashFunction; hash.Hash(md); hash.Hash(mdPrime); return(ip.Zq.GetElementFromDigest(hash.Digest)); } else { return(ip.Zq.GetElementFromDigest(mdPrime)); } }
/// <summary> /// Indicates that attributes are carried over from the source token into the new one. /// </summary> /// <param name="sourceIndex">The indices of the attributes in the existing token.</param> /// <param name="destinationIndex">The indices of the attributes in the new token.</param> /// /// <param name="sourceIP">The Issuer Parameters used to issue the source token. This can be the same as <c>Ip</c> if the /// same Issuer issues the source and new tokens.</param> /// <param name="sourceToken">The source token.</param> public void CarryOverAttribute(int[] sourceIndex, int[] destinationIndex, IssuerParameters sourceIP, UProveToken sourceToken) { if (sourceIndex == null || destinationIndex == null || sourceIP == null || sourceToken == null) { throw new ArgumentNullException("arguments can't be null"); } if (sourceIndex.Length != destinationIndex.Length) { throw new ArgumentException("sourceIndex and destinationIndex must have the same lenght"); } if (!sourceToken.Uidp.SequenceEqual <byte>(sourceIP.UidP)) { throw new ArgumentException("sourceToken and sourceIP do not match"); } C = destinationIndex; Corig = sourceIndex; SourceIP = sourceIP; Tokens = sourceToken; HasCarryOverAttributes = true; }
/// <summary> /// Verifies a U-Prove token signature. /// </summary> /// <param name="ip">The Issuer parameters corresponding to the U-Prove token.</param> /// <param name="upt">The U-Prove token to verify.</param> /// <exception cref="InvalidUProveArtifactException">If the U-Prove token is invalid.</exception> public static void VerifyTokenSignature(IssuerParameters ip, UProveToken upt) { Group Gq = ip.Gq; FieldZq Zq = ip.Zq; if (upt.H == Gq.Identity) { throw new InvalidUProveArtifactException("Invalid U-Prove token (public key H = 1)"); } HashFunction hash = ip.HashFunction; hash.Hash(upt.H); hash.Hash(upt.PI); hash.Hash(upt.SigmaZPrime); hash.Hash(Gq.G.Exponentiate(upt.SigmaRPrime) * ip.G[0].Exponentiate(upt.SigmaCPrime.Negate())); hash.Hash(upt.H.Exponentiate(upt.SigmaRPrime) * upt.SigmaZPrime.Exponentiate(upt.SigmaCPrime.Negate())); if (upt.SigmaCPrime != Zq.GetElementFromDigest(hash.Digest)) { throw new InvalidUProveArtifactException("Invalid U-Prove token signature"); } }
/// <summary> /// Computes the U-Prove token identifier. /// </summary> /// <param name="ip">The issuer parameters associated with <code>upt</code>.</param> /// <param name="upt">The U-Prove token from which to compute the identifier.</param> /// <returns></returns> public static byte[] ComputeTokenID(IssuerParameters ip, UProveToken upt) { HashFunction hash = ip.HashFunction; hash.Hash(upt.H); hash.Hash(upt.SigmaZPrime); hash.Hash(upt.SigmaCPrime); hash.Hash(upt.SigmaRPrime); return hash.Digest; }
public static UProveToken convertUProveTokenComposite(IssuerParameters ip, UProveTokenComposite utc) { UProveToken up = new UProveToken(); up.H = ip.Gq.CreateGroupElement(utc.H); up.IsDeviceProtected = utc.IsDeviceProtected; up.PI = utc.PI; up.SigmaCPrime = new BigInteger(1, utc.SigmaCPrime); up.SigmaRPrime = new BigInteger(1, utc.SigmaRPrime); up.SigmaZPrime = ip.Gq.CreateGroupElement(utc.SigmaZPrime); up.TI = utc.TI; up.Uidp = utc.Uidp; return up; }
public void Verify(IssuerParameters ip, int[] disclosed, int[] committed, int pseudonymAttribIndex, GroupElement gs, byte[] message, byte[] messageD, UProveToken upt) { try { // make sure disclosed list is sorted if (disclosed == null) { // can't be null later, so make it an empty array disclosed = new int[] { }; } Array.Sort(disclosed); Group Gq = ip.Gq; int n = ip.E.Length; bool presentPseudonym = false; if (gs != null && pseudonymAttribIndex != 0) { 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 // no nym { pseudonymAttribIndex = 0; } bool verifyCommitments = (committed != null && committed.Length > 0); if (verifyCommitments) { Array.Sort(committed); } ProtocolHelper.VerifyTokenSignature(ip, upt); FieldZqElement[] disclosedX = new FieldZqElement[disclosedAttributes.Length]; GroupElement dAccumulator = ip.G[0] * ip.G[n + 1].Exponentiate(ProtocolHelper.ComputeXt(ip, upt.TI, upt.IsDeviceProtected)); // g0 * gt^xt GroupElement uAccumulator = upt.H.Exponentiate(this.r[0]); int dIndex = 0; int uIndex = 1; int cIndex = 0; int pseudonymResponseIndex = 0; int[] commitmentResponseIndices = verifyCommitments ? new int[committed.Length] : null; for (int i = 1; i <= n; i++) { if (disclosed.Contains(i)) { disclosedX[dIndex] = ProtocolHelper.ComputeXi(ip, i - 1, disclosedAttributes[dIndex]); dAccumulator = dAccumulator * ip.G[i].Exponentiate(disclosedX[dIndex]); dIndex++; } else { uAccumulator = uAccumulator * ip.G[i].Exponentiate(this.r[uIndex]); if (presentPseudonym) { if (pseudonymAttribIndex == i) { pseudonymResponseIndex = uIndex; } } if (verifyCommitments) { if (committed.Contains(i)) { // remember which response correspond to which commitment commitmentResponseIndices[cIndex] = uIndex; cIndex++; } } uIndex++; } } if (pseudonymAttribIndex == DeviceAttributeIndex) { pseudonymResponseIndex = this.r.Length - 1; // r_d is the last response in the array } byte[] unused; // verifier doesn't use the returned message for device FieldZqElement c = ProtocolHelper.GenerateChallenge(ip, upt, this.a, pseudonymAttribIndex, this.ap, this.ps, message, messageD, disclosed, disclosedX, committed, this.Commitments, out unused); HashFunction hash = ip.HashFunction; hash.Hash((dAccumulator.Exponentiate(c.Negate()) * uAccumulator * (upt.IsDeviceProtected ? ip.Gd.Exponentiate(this.r[this.r.Length -1]) : Gq.Identity))); if (!this.a.SequenceEqual(hash.Digest)) { throw new InvalidUProveArtifactException("Invalid presentation proof"); } if (presentPseudonym) { hash.Hash(this.ps.Exponentiate(c).Multiply(gs.Exponentiate(this.r[pseudonymResponseIndex]))); if (!this.ap.SequenceEqual(hash.Digest)) { throw new InvalidUProveArtifactException("Invalid pseudonym"); } } if (verifyCommitments) { for (int i = 0; i < commitmentResponseIndices.Length; i++) { CommitmentValues commitment = this.Commitments[i]; hash.Hash(commitment.TildeC.Exponentiate(c).Multiply(ip.Gq.G.Exponentiate(this.r[commitmentResponseIndices[i]])).Multiply(ip.G[1].Exponentiate(commitment.TildeR))); if (!commitment.TildeA.SequenceEqual(hash.Digest)) { throw new InvalidUProveArtifactException("Invalid commitment " + committed[i]); } } } } catch (ArgumentException) { throw new InvalidUProveArtifactException("Invalid presentation proof"); } catch (IndexOutOfRangeException) { throw new InvalidUProveArtifactException("Invalid presentation proof"); } }
public void Verify(IssuerParameters ip, int[] disclosed, int[] committed, int pseudonymAttribIndex, byte[] pseudonymScope, byte[] message, byte[] messageD, UProveToken upt) { GroupElement gs = ProtocolHelper.GenerateScopeElement(ip.Gq, pseudonymScope); Verify(ip, disclosed, committed, pseudonymAttribIndex, gs, message, messageD, upt); }
public void Verify(IssuerParameters ip, int[] disclosed, byte[] message, byte[] messageD, UProveToken upt) { GroupElement gs = null; Verify(ip, disclosed, null, 0, gs, message, messageD, upt); }
public void Verify(IssuerParameters ip, int[] disclosed, int[] committed, int pseudonymAttribIndex, GroupElement gs, byte[] message, byte[] messageD, UProveToken upt) { try { // make sure disclosed list is sorted if (disclosed == null) { // can't be null later, so make it an empty array disclosed = new int[] { }; } Array.Sort(disclosed); Group Gq = ip.Gq; int n = ip.E.Length; bool presentPseudonym = false; if (gs != null && pseudonymAttribIndex != 0) { 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 // no nym { pseudonymAttribIndex = 0; } bool verifyCommitments = (committed != null && committed.Length > 0); if (verifyCommitments) { Array.Sort(committed); } ProtocolHelper.VerifyTokenSignature(ip, upt); int dArraySize = disclosed.Length + 2; GroupElement[] dBases = new GroupElement[dArraySize]; FieldZqElement[] dExponents = new FieldZqElement[dArraySize]; dBases[0] = ip.G[0]; dExponents[0] = ip.Zq.One; // g0^1 dBases[1] = ip.G[n + 1]; dExponents[1] = ProtocolHelper.ComputeXt(ip, upt.TI, upt.IsDeviceProtected); // gt^xt FieldZqElement[] disclosedX = new FieldZqElement[disclosedAttributes.Length]; int aPreImageArraySize = 2 + (n - disclosed.Length) + (upt.IsDeviceProtected ? 1 : 0); GroupElement[] aPreImageBases = new GroupElement[aPreImageArraySize]; FieldZqElement[] aPreImageExponents = new FieldZqElement[aPreImageArraySize]; // aPreImage arrays' index 0 values depend on the dArray values; they will be filled out later aPreImageBases[1] = upt.H; aPreImageExponents[1] = this.r[0]; // h^r0 int dIndex = 0; int uIndex = 1; int cIndex = 0; int pseudonymResponseIndex = 0; int[] commitmentResponseIndices = verifyCommitments ? new int[committed.Length] : null; for (int i = 1; i <= n; i++) { if (disclosed.Contains(i)) { disclosedX[dIndex] = ProtocolHelper.ComputeXi(ip, i - 1, disclosedAttributes[dIndex]); dBases[dIndex + 2] = ip.G[i]; dExponents[dIndex + 2] = disclosedX[dIndex]; dIndex++; } else { aPreImageBases[uIndex + 1] = ip.G[i]; aPreImageExponents[uIndex + 1] = this.r[uIndex]; // gi^ri if (presentPseudonym) { if (pseudonymAttribIndex == i) { pseudonymResponseIndex = uIndex; } } if (verifyCommitments) { if (committed.Contains(i)) { // remember which response correspond to which commitment commitmentResponseIndices[cIndex] = uIndex; cIndex++; } } uIndex++; } } if (pseudonymAttribIndex == DeviceAttributeIndex) { pseudonymResponseIndex = this.r.Length - 1; // r_d is the last response in the array } byte[] unused; // verifier doesn't use the returned message for device FieldZqElement c = ProtocolHelper.GenerateChallenge(ip, upt, this.a, pseudonymAttribIndex, this.ap, this.ps, message, messageD, disclosed, disclosedX, committed, this.Commitments, out unused); aPreImageBases[0] = Gq.MultiExponentiate(dBases, dExponents); aPreImageExponents[0] = c.Negate(); // g0.gt^xt.Product[gi^xi]_(for disclosed i) if (upt.IsDeviceProtected) { aPreImageBases[aPreImageArraySize - 1] = ip.Gd; aPreImageExponents[aPreImageArraySize - 1] = this.r[this.r.Length - 1]; // gd^rd } HashFunction hash = ip.HashFunction; hash.Hash(Gq.MultiExponentiate(aPreImageBases, aPreImageExponents)); if (!this.a.SequenceEqual(hash.Digest)) { throw new InvalidUProveArtifactException("Invalid presentation proof"); } if (presentPseudonym) { hash.Hash(Gq.MultiExponentiate(new GroupElement[] { ps, gs }, new FieldZqElement[] { c, r[pseudonymResponseIndex] })); if (!this.ap.SequenceEqual(hash.Digest)) { throw new InvalidUProveArtifactException("Invalid pseudonym"); } } if (verifyCommitments) { GroupElement[] cBases = new GroupElement[3]; FieldZqElement[] cExponents = new FieldZqElement[3]; cBases[1] = Gq.G; cBases[2] = ip.G[1]; cExponents[0] = c; for (int i = 0; i < commitmentResponseIndices.Length; i++) { CommitmentValues commitment = this.Commitments[i]; cBases[0] = commitment.TildeC; cExponents[1] = this.r[commitmentResponseIndices[i]]; cExponents[2] = commitment.TildeR; hash.Hash(Gq.MultiExponentiate(cBases, cExponents)); if (!commitment.TildeA.SequenceEqual(hash.Digest)) { throw new InvalidUProveArtifactException("Invalid commitment " + committed[i]); } } } } catch (ArgumentException) { throw new InvalidUProveArtifactException("Invalid presentation proof"); } catch (IndexOutOfRangeException) { throw new InvalidUProveArtifactException("Invalid presentation proof"); } }
internal static FieldZqElement GenerateChallenge(IssuerParameters ip, UProveToken upt, byte[] a, int pseudonymIndex, byte[] ap, GroupElement Ps, byte[] m, byte[] md, int[] disclosed, FieldZqElement[] disclosedX, int[] committed, CommitmentValues[] commitments, out byte[] mdPrime) { bool hasCommitments = (committed != null && committed.Length > 0); if (hasCommitments) { if (committed.Length != commitments.Length) { throw new ArgumentException("Inconsistent committed indices and commitment values"); } } HashFunction hash = ip.HashFunction; hash.Hash(ComputeTokenID(ip, upt)); hash.Hash(a); hash.Hash(disclosed); hash.Hash(disclosedX); if (!hasCommitments) { hash.HashNull(); // C hash.HashNull(); // < {tildeC} > hash.HashNull(); // < {tildeA} > } else { hash.Hash(committed); hash.Hash(commitments.Length); // length of < {tildeC} > for (int i = 0; i < commitments.Length; i++) { hash.Hash(commitments[i].TildeC); } hash.Hash(commitments.Length); // length of < {tildeA} > for (int i = 0; i < commitments.Length; i++) { hash.Hash(commitments[i].TildeA); } } hash.Hash(pseudonymIndex == PresentationProof.DeviceAttributeIndex ? 0 : pseudonymIndex); hash.Hash(ap); hash.Hash(Ps); hash.Hash(m); mdPrime = hash.Digest; if (upt.IsDeviceProtected) { hash = ip.HashFunction; hash.Hash(md); hash.Hash(mdPrime); return ip.Zq.GetElementFromDigest(hash.Digest); } else { return ip.Zq.GetElementFromDigest(mdPrime); } }
public static UProveTokenComposite convertUProveToken(UProveToken up) { UProveTokenComposite utc = new UProveTokenComposite(); utc.H = up.H.GetEncoded(); utc.IsDeviceProtected = up.IsDeviceProtected; utc.PI = up.PI; utc.SigmaCPrime = up.SigmaCPrime.ToByteArray(); utc.SigmaRPrime = up.SigmaRPrime.ToByteArray(); utc.SigmaZPrime = up.SigmaZPrime.GetEncoded(); utc.TI = up.TI; utc.Uidp = up.Uidp; return utc; }
public void Verify(IssuerParameters ip, int[] disclosed, int[] committed, int pseudonymAttribIndex, GroupElement gs, byte[] message, byte[] messageD, UProveToken upt) { try { // make sure disclosed list is sorted if (disclosed == null) { // can't be null later, so make it an empty array disclosed = new int[] { }; } Array.Sort(disclosed); Group Gq = ip.Gq; int n = ip.E.Length; bool presentPseudonym = false; if (gs != null && pseudonymAttribIndex != 0) { 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 // no nym { pseudonymAttribIndex = 0; } bool verifyCommitments = (committed != null && committed.Length > 0); if (verifyCommitments) { Array.Sort(committed); } ProtocolHelper.VerifyTokenSignature(ip, upt); FieldZqElement[] disclosedX = new FieldZqElement[disclosedAttributes.Length]; GroupElement dAccumulator = ip.G[0] * ip.G[n + 1].Exponentiate(ProtocolHelper.ComputeXt(ip, upt.TI, upt.IsDeviceProtected)); // g0 * gt^xt GroupElement uAccumulator = upt.H.Exponentiate(this.r[0]); int dIndex = 0; int uIndex = 1; int cIndex = 0; int pseudonymResponseIndex = 0; int[] commitmentResponseIndices = verifyCommitments ? new int[committed.Length] : null; for (int i = 1; i <= n; i++) { if (disclosed.Contains(i)) { disclosedX[dIndex] = ProtocolHelper.ComputeXi(ip, i - 1, disclosedAttributes[dIndex]); dAccumulator = dAccumulator * ip.G[i].Exponentiate(disclosedX[dIndex]); dIndex++; } else { uAccumulator = uAccumulator * ip.G[i].Exponentiate(this.r[uIndex]); if (presentPseudonym) { if (pseudonymAttribIndex == i) { pseudonymResponseIndex = uIndex; } } if (verifyCommitments) { if (committed.Contains(i)) { // remember which response correspond to which commitment commitmentResponseIndices[cIndex] = uIndex; cIndex++; } } uIndex++; } } if (pseudonymAttribIndex == DeviceAttributeIndex) { pseudonymResponseIndex = this.r.Length - 1; // r_d is the last response in the array } byte[] unused; // verifier doesn't use the returned message for device FieldZqElement c = ProtocolHelper.GenerateChallenge(ip, upt, this.a, pseudonymAttribIndex, this.ap, this.ps, message, messageD, disclosed, disclosedX, committed, this.Commitments, out unused); HashFunction hash = ip.HashFunction; hash.Hash((dAccumulator.Exponentiate(c.Negate()) * uAccumulator * (upt.IsDeviceProtected ? ip.Gd.Exponentiate(this.r[this.r.Length - 1]) : Gq.Identity))); if (!this.a.SequenceEqual(hash.Digest)) { throw new InvalidUProveArtifactException("Invalid presentation proof"); } if (presentPseudonym) { hash.Hash(this.ps.Exponentiate(c).Multiply(gs.Exponentiate(this.r[pseudonymResponseIndex]))); if (!this.ap.SequenceEqual(hash.Digest)) { throw new InvalidUProveArtifactException("Invalid pseudonym"); } } if (verifyCommitments) { for (int i = 0; i < commitmentResponseIndices.Length; i++) { CommitmentValues commitment = this.Commitments[i]; hash.Hash(commitment.TildeC.Exponentiate(c).Multiply(ip.Gq.G.Exponentiate(this.r[commitmentResponseIndices[i]])).Multiply(ip.G[1].Exponentiate(commitment.TildeR))); if (!commitment.TildeA.SequenceEqual(hash.Digest)) { throw new InvalidUProveArtifactException("Invalid commitment " + committed[i]); } } } } catch (ArgumentException) { throw new InvalidUProveArtifactException("Invalid presentation proof"); } catch (IndexOutOfRangeException) { throw new InvalidUProveArtifactException("Invalid presentation proof"); } }