public void Verify()

in UProveCrypto/PresentationProof.cs [687:831]


        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");
            }
        }