/// <summary>
        /// Verifies that a UProve token attribute is in a given set.
        /// </summary>
        /// <param name="verifier">Verifier info about token.</param>
        /// <param name="attributeIndexForVerifier">Target attribute, 1-based index.</param>
        /// <param name="setValues">Set of values for attribute.</param>
        /// <returns></returns>
        public bool Verify(
            VerifierPresentationProtocolParameters verifier,
            int attributeIndexForVerifier,
            byte [][] setValues)
        {
            // Verify UProve Integration Proof
            if (this.UPIProof == null)
            {
                return(false);
            }
            VerifierPresentationProtocolParameters[] verifiers = new VerifierPresentationProtocolParameters[1] {
                verifier
            };
            int[] attributeIndices = new int[1] {
                attributeIndexForVerifier
            };
            if (!this.UPIProof.Verify(verifiers, attributeIndices))
            {
                return(false);
            }

            // Verify Set Membership Proof
            FieldZqElement[] memberSet = VerifierSetMembershipParameters.GenerateMemberSet(verifier.IP, attributeIndexForVerifier, setValues);
            VerifierSetMembershipParameters setVerifier = new VerifierSetMembershipParameters(this.UPIProof.PedersenCommitmentValues[0], memberSet, new CryptoParameters(verifier.IP));

            return(this.Verify(setVerifier));
        }
        /// <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>
        /// 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>
        /// Computes the challenge.  This method is used by both the prover and verifier.
        /// </summary>
        /// <param name="verifier">Verifier parameters</param>
        /// <returns>Challenge</returns>
        private FieldZqElement ComputeChallenge(VerifierSetMembershipParameters verifier)
        {
            HashFunction hash = new HashFunction(verifier.HashFunctionName);

            // H(desc(Gq), g = G, g1 = H, <S>, C, <a>)
            verifier.Group.UpdateHash(hash);
            hash.Hash(verifier.G);
            hash.Hash(verifier.H);
            hash.Hash(verifier.MemberSet);
            hash.Hash(verifier.ClosedCommitment);
            hash.Hash(this.a);
            return(verifier.FieldZq.GetElementFromDigest(hash.Digest));
        }
        /// <summary>
        /// Constructor. Creates a proof that a token attribute is in a given set.
        /// </summary>
        /// <param name="prover">Token description.</param>
        /// <param name="attributeIndexForProver">1-based attribute index in token.</param>
        /// <param name="setValues">Set of attributes to compare to token attribute.</param>
        /// <param name="smRandom">Random data for set membership proof.</param>
        /// <returns>Inequality proof.</returns>
        public SetMembershipProof(ProverPresentationProtocolParameters prover, int attributeIndexForProver, byte[][] setValues, SetMembershipProofGenerationRandomData smRandom = null)
        {
            // generate Pedersen Commitments to token attribute
            ProverPresentationProtocolParameters[] provers = new ProverPresentationProtocolParameters[] { prover };
            int[] attributeIndices = new int[] { attributeIndexForProver };
            PedersenCommitment[] attributeCommitments = PedersenCommitment.PedersenCommmitmentsToAttributes(provers, attributeIndices);

            // create set membership proof using Pedersen Commitment
            FieldZqElement[] memberSet = VerifierSetMembershipParameters.GenerateMemberSet(prover.IP, attributeIndexForProver, setValues);
            ProverSetMembershipParameters setProver = new ProverSetMembershipParameters(attributeCommitments[0], memberSet, new CryptoParameters(prover.IP));

            ConstructorHelper(setProver, smRandom);

            // add UProve Integration proof
            this.UPIProof = new UProveIntegrationProof(provers, attributeIndices, attributeCommitments);
            this.UPIProof.IsGroupSerializable = false;
        }
Esempio n. 6
0
        /// <summary>
        /// Checks that this bit decomposition proof is valid with respect to
        /// the given verifier parameters.
        /// </summary>
        /// <param name="verifier">Verifier parameters.</param>
        /// <returns>True if this proof is valid, false otherwise.</returns>
        public bool Verify(VerifierBitDecompositionParameters verifier)
        {
            try
            {
                // check verifier parameters
                if (!verifier.Verify())
                {
                    return(false);
                }

                // check each set membership proof
                VerifierSetMembershipParameters smParameters = new VerifierSetMembershipParameters(verifier);
                FieldZqElement[] memberSet = SetOfZeroAndOne(verifier);
                for (int committedBitIndex = 0; committedBitIndex < this.bitCommitmentProof.Length; ++committedBitIndex)
                {
                    GroupElement committedBit = verifier.ClosedBitDecomposition(committedBitIndex);
                    smParameters.setVerifierParameters(committedBit, memberSet);
                    if (!this.bitCommitmentProof[committedBitIndex].Verify(smParameters))
                    {
                        return(false);
                    }
                }

                // check the composition proof
                GroupElement   actualComposedValue = ComposeClosedCommittedBits(verifier.ClosedBitDecomposition(), verifier);
                GroupElement[] bases = new GroupElement[2] {
                    verifier.G, verifier.H
                };
                VerifierEqualityParameters veParameters = new VerifierEqualityParameters(
                    new ClosedDLRepOfGroupElement(bases, actualComposedValue, verifier.Group),
                    0,
                    new ClosedDLRepOfGroupElement(bases, verifier.ClosedCommitment, verifier.Group),
                    0,
                    verifier);

                if (!this.compositionProof.Verify(veParameters))
                {
                    return(false);
                }
                return(true);
            }
            catch (Exception)
            {
                return(false);
            }
        }
        /// <summary>
        /// Verify that this object contains a valid proof for the statement contained in
        /// verifier parameters.
        /// </summary>
        /// <param name="verifier">Common parameters for prover and verifier.</param>
        /// <returns>True if this is a valid proof, false otherwise. Returns false on error (no exceptions thrown).</returns>
        public bool Verify(VerifierSetMembershipParameters verifier)
        {
            try
            {
                // check parameters
                if (!verifier.Verify())
                {
                    return(false);
                }

                // make sure a,c,r are not null
                if ((a == null) || (c == null) || (r == null))
                {
                    return(false);
                }

                // make sure parameters correspond to the proof.
                if ((verifier.MemberSet.Length != a.Length) ||
                    (verifier.MemberSet.Length - 1 != c.Length) ||
                    (verifier.MemberSet.Length != r.Length) ||
                    (verifier.Group != this.Group))
                {
                    return(false);
                }


                // Verify each tuple a[index],c[index], r[index]
                for (int index = 0; index < verifier.MemberSet.Length; ++index)
                {
                    if (!VerifySubProof(verifier, index))
                    {
                        return(false);
                    }
                }
                return(true);
            }
            catch (Exception)
            {
                return(false);
            }
        }
        /// <summary>
        /// Helper method for Verify.
        /// Verifies that the (a[indexForMemberSet],c[indexForMemberSet],r[indexForMemberSet]) are
        /// a valid proof for verifier.MemberSet[indexForMemberSet].
        /// </summary>
        /// <param name="verifier">Verifier parameters</param>
        /// <param name="indexForMemberOfSet">index into verifier.MemberSet</param>
        /// <returns>True on success, false on failure.</returns>
        private bool VerifySubProof(VerifierSetMembershipParameters verifier, int indexForMemberOfSet)
        {
            // get the current challenge
            FieldZqElement subC;

            if (indexForMemberOfSet < this.c.Length)
            {
                subC = this.c[indexForMemberOfSet];
            }
            else
            {
                FieldZqElement challenge          = this.ComputeChallenge(verifier);
                FieldZqElement sumOfSubChallenges = verifier.FieldZq.Zero;
                for (int i = 0; i < this.c.Length; ++i)
                {
                    sumOfSubChallenges += this.c[i];
                }
                subC = challenge - sumOfSubChallenges;
            }

            // compute leftSide
            GroupElement leftSide = verifier.H.Exponentiate(this.r[indexForMemberOfSet]);

            // compute rightSide = X^{c} * g^{-memberOfSet * c} * a
            GroupElement[] bases = new GroupElement[]
            {
                verifier.ClosedCommitment,                  // X
                verifier.G,                                 // g
                this.a[indexForMemberOfSet]                 // a
            };
            FieldZqElement[] exponents = new FieldZqElement[]
            {
                subC,                                                    // c
                verifier.MemberSet[indexForMemberOfSet].Negate() * subC, // -memberOfSet * c
                verifier.FieldZq.One                                     // 1
            };
            GroupElement rightSide = verifier.Group.MultiExponentiate(bases, exponents);

            return(leftSide == rightSide);
        }
Esempio n. 9
0
        /// <summary>
        /// Verifies the RangeProof.  Returns true if it is valid, false otherwise.
        /// </summary>
        /// <param name="verifier">Verifier parameters.</param>
        /// <returns></returns>
        public bool Verify(VerifierRangeProofParameters verifier)
        {
            try
            {
                // Verify parameters
                if (!verifier.Verify())
                {
                    return(false);
                }

                // verify bit decomposition proofs
                if (!VerifyBitDecompositionProofs(verifier, this.A, this.B, ProofBitDecompositionOfA, ProofBitDecompositionOfB))
                {
                    return(false);
                }

                // verify FullRangeProof
                GroupElement[] closedAdivB = ComputeClosedAdivB(verifier, this.A, this.B);
                this.D[0] = closedAdivB[0];
                ClosedDLRepOfGroupElement[] closedX     = ComputeClosedX(verifier, this.X, closedAdivB);
                ClosedDLRepOfGroupElement[] closedE     = ComputeClosedE(verifier, this.X, this.D, closedAdivB);
                ClosedDLRepOfGroupElement[] allClosedDL = CombineAllClosedDLReps(this.D, closedAdivB, closedX, closedE, verifier);
                EqualityMap map = ComputeEqualityMap(verifier, A.Length);
                VerifierEqualityParameters veParameters = new VerifierEqualityParameters(
                    allClosedDL,
                    map,
                    verifier);

                bool success = this.FullRangeProof.Verify(veParameters);
                if (!success)
                {
                    return(false);
                }

                // verify additional proof based on proof type
                GroupElement LastD = this.D[this.D.Length - 1];
                switch (verifier.RangeProofType)
                {
                case VerifierRangeProofParameters.ProofType.GREATER_THAN:
                    ClosedDLRepOfGroupElement gtEquation = new ClosedDLRepOfGroupElement(
                        new GroupElement[1] {
                        verifier.H
                    },
                        LastD * verifier.G.Exponentiate(verifier.FieldZq.One.Negate()),
                        verifier.Group);
                    VerifierEqualityParameters greaterThanVerifier = new VerifierEqualityParameters(
                        gtEquation,
                        verifier);
                    return(StrictlyThanProof.Verify(greaterThanVerifier));

                case VerifierRangeProofParameters.ProofType.LESS_THAN:
                    ClosedDLRepOfGroupElement ltEquation = new ClosedDLRepOfGroupElement(
                        new GroupElement[1] {
                        verifier.H
                    },
                        LastD * verifier.G,
                        verifier.Group);
                    VerifierEqualityParameters lessThanVerifier = new VerifierEqualityParameters(
                        ltEquation,
                        verifier);
                    return(StrictlyThanProof.Verify(lessThanVerifier));

                case VerifierRangeProofParameters.ProofType.GREATER_THAN_OR_EQUAL_TO:
                    VerifierSetMembershipParameters greaterEqualVerifier = new VerifierSetMembershipParameters(
                        LastD,
                        new FieldZqElement[] { verifier.FieldZq.Zero, verifier.FieldZq.One },
                        verifier);
                    return(this.OrEqualToProof.Verify(greaterEqualVerifier));

                case VerifierRangeProofParameters.ProofType.LESS_THAN_OR_EQUAL_TO:
                    VerifierSetMembershipParameters lessEqualProver = new VerifierSetMembershipParameters(
                        LastD,
                        new FieldZqElement[] { verifier.FieldZq.Zero, verifier.FieldZq.One.Negate() },
                        verifier);
                    return(this.OrEqualToProof.Verify(lessEqualProver));
                }
            }
            catch (Exception)
            {
            }
            return(false);
        }