public static GroupElement VerifyProof()

in UProveCrypto/CollaborativeIssuance.cs [451:568]


        public static GroupElement VerifyProof(IssuerPreIssuanceParameters ipip, PreIssuanceProof proof, byte[] message)
        {
            // Validate paramters first
            ipip.Validate();

            IssuerParameters ip = ipip.IP;
            FieldZq Zq = ip.Zq;
            Group Gq = ip.Gq;

            List<GroupElement> bases = new List<GroupElement>();
            List<FieldZqElement> exponents = new List<FieldZqElement>();

            GroupElement[] C = null;
            GroupElement[] CPrime = null;

            FieldZqElement c = Zq.GetElementFromDigest(proof.c);

            if (ipip.HasCarryOverAttributes)
            {
                // validate presentation proof
                int[] disclosed = new int[] {}; 
                VerifierPresentationProtocolParameters vppp = new VerifierPresentationProtocolParameters(ipip.SourceIP, disclosed, message, ipip.Tokens);
                vppp.Committed = ipip.Corig;

                try
                {
                    proof.presentation.Verify(vppp);
                }
                catch (InvalidUProveArtifactException e)
                {
                    throw new InvalidUProveArtifactException("Failed to verify pre-Issuance proof, presentation proof " + 0 + " failed to verify ("+e.ToString()+")");
                }

                // extract the commitments
                C = new GroupElement[ipip.C.Length];
                CPrime = new GroupElement[ipip.C.Length];
                for (int i = 0; i < C.Length; i++)
                {
                    C[i] = proof.presentation.Commitments[i].TildeC;
                
                    // Compute the CPrime[i] values. 
                    bases = new List<GroupElement>();
                    exponents = new List<FieldZqElement>();
                    bases.Add(C[i]);
                    exponents.Add(c);
                    bases.Add(Gq.G);
                    exponents.Add(proof.GetResponse("sx" + ipip.C[i]));
                    bases.Add(ip.G[1]);
                    exponents.Add(proof.GetResponse("sR" + i));
                    CPrime[i] = Gq.MultiExponentiate(bases.ToArray(), exponents.ToArray());
                    //Debug.WriteLine("CPrime[i] = " + BitConverter.ToString(CPrime[i].GetEncoded()));                
                }
            }

            // Compute D'
            FieldZqElement sd = proof.GetResponse("sD");
            GroupElement DPrime = Gq.MultiExponentiate(proof.Ch0, proof.h0, c, c.Negate()); // TODO: add Inverse() to group element to simplify this
            DPrime = DPrime.Multiply(Gq.G.Exponentiate(sd));
            //Debug.WriteLine("DPrime = " + BitConverter.ToString(DPrime.GetEncoded()));

            // Compute T'
            FieldZqElement sBeta0 = proof.GetResponse("sBeta0");
            GroupElement TPrime = Gq.MultiExponentiate(proof.Ch0, proof.CGamma, c, sBeta0);
            //Debug.WriteLine("TPrime = " + BitConverter.ToString(TPrime.GetEncoded()));

            // Compute gammaK (product of known attributes)
            bases = new List<GroupElement>();
            exponents = new List<FieldZqElement>();
            int t = ip.G.Length-1;
            FieldZqElement xt = ProtocolHelper.ComputeXt(ip, ipip.TI, ipip.DeviceProtected);
            bases.Add(ip.G[0]);
            exponents.Add(ip.Zq.One);
            bases.Add(ip.G[t]);
            exponents.Add(xt);  // gammaK = g0*(gt^xt)
            for (int i = 1; i < ip.G.Length - 1; i++)
            {
                if (ipip.K.Contains(i))
                {
                    FieldZqElement xi = ProtocolHelper.ComputeXi(ip, i-1, ipip.Attributes[i-1]);
                    bases.Add(ip.G[i]);
                    exponents.Add(xi);
                }
            }
            GroupElement gammaK = Gq.MultiExponentiate(bases.ToArray(), exponents.ToArray());

            // Compute Cgamma'
            bases = new List<GroupElement>();
            exponents = new List<FieldZqElement>();
            bases.Add(proof.CGamma);
            exponents.Add(c);
            bases.Add(gammaK);
            exponents.Add(c.Negate());  // TODO: do with one exp; i.e., (CGamma/gammaK)^c
            for (int i = 1; i < ip.G.Length - 1; i++)
            {
                if (!ipip.K.Contains(i))
                {
                    FieldZqElement sxi = proof.GetResponse("sx" + i);
                    bases.Add(ip.G[i]);
                    exponents.Add(sxi);
                }
            }
            bases.Add(Gq.G);
            exponents.Add(proof.GetResponse("sRho"));
            GroupElement CgammaPrime = Gq.MultiExponentiate(bases.ToArray(), exponents.ToArray());
            // TODO: if deviceprotected multiply device base/response.
            //Debug.WriteLine("CgammaPrime = " + BitConverter.ToString(CgammaPrime.GetEncoded()));

            // Recompute challenge
            byte[] cPrime = ComputeChallenge(ip, proof.h0, proof.CGamma, proof.Ch0, C, DPrime, CgammaPrime, TPrime, CPrime, message);
            //Debug.WriteLine("c' = " + BitConverter.ToString(cPrime));

            if (!cPrime.SequenceEqual<byte>(proof.c))
            {
                throw new InvalidUProveArtifactException("invalid proof");
            }

            return proof.h0;
        }