/// <summary>
        /// Helper method for constructing proof. Computes a[index], c[index], r[index] values for when
        /// the committedValue is not equal to prover.MemberSet[index].
        /// </summary>
        /// <param name="index">Index into prover.MemberSet</param>
        /// <param name="prover">Prover parameters</param>
        /// <param name="randomChallengeValue">Value to set c[index]</param>
        /// <param name="randomResponseValue">Value to set r[index]</param>
        private void generateFakeProof(int index, ProverSetMembershipParameters prover, FieldZqElement randomChallengeValue, FieldZqElement randomResponseValue)
        {
            if (index < this.c.Length)
            {
                this.c[index] = randomChallengeValue;
            }

            this.r[index] = randomResponseValue;

            // compute this.a[index] as a multi-exponentiation
            // a[index] = h^r[index] * g^{memberset[index] + c[index]} * X^{-c[index]
            GroupElement[] bases = new GroupElement[3]
            {
                prover.H,                         // h
                prover.G,                         // g
                prover.ClosedCommitment           // X
            };
            FieldZqElement[] exponents = new FieldZqElement[3]
            {
                randomResponseValue,                            // r[index]
                prover.MemberSet[index] * randomChallengeValue, // memberset[index] * c
                randomChallengeValue.Negate()                   // -c
            };
            this.a[index] = prover.Group.MultiExponentiate(bases, exponents);
        }
 /// <summary>
 /// Helper method for constructing proof.
 /// Generates a the c, r, a values for when the committed value is identical to
 /// the element in the memberSet located at index.
 /// </summary>
 /// <param name="index">Index into prover.MemberSet</param>
 /// <param name="prover">Prover parameters</param>
 /// <param name="randomWValue">random value to use to compute proof</param>
 /// <param name="challengeValue">Challenge to use to compute proof</param>
 private void generateRealProof(int index, ProverSetMembershipParameters prover, FieldZqElement randomWValue, FieldZqElement challengeValue)
 {
     if (index < this.c.Length)
     {
         this.c[index] = challengeValue;
     }
     this.r[index] = (challengeValue * prover.OpenCommitment.Opening) + randomWValue;
 }
        private void ConstructorHelper(ProverSetMembershipParameters prover, SetMembershipProofGenerationRandomData smRandom = null)
        {
            try
            {
                // check that parameters can be used to construct valid proof.
                if (!prover.Verify())
                {
                    throw new ArgumentException("Invalid proof parameters.  Cannot create proof");
                }

                // set Group context
                this.Group = prover.Group;
                this.IsGroupSerializable = true;

                // allocate space for proof
                this.c = new FieldZqElement[prover.MemberSet.Length - 1];
                this.a = new GroupElement[prover.MemberSet.Length];
                this.r = new FieldZqElement[prover.MemberSet.Length];

                // generate random values needed for proof
                if (smRandom == null)
                {
                    // generate a pair of random values for each fake proofs, plus the random exponent for the real one
                    smRandom = SetMembershipProofGenerationRandomData.Generate(prover.FieldZq, prover.MemberSet.Length - 1);
                }

                // Find index of prover.OpenCommitment.CommittedValue in prover.MemberSet
                int indexOfCommittedValue = prover.IndexOfCommittedValueInSet;

                // generate a fake proof for each prover.MemberSet element that is not
                // equal to CommitedValue.
                FieldZqElement sumOfSubChallenges = prover.FieldZq.Zero;

                int randomIndex = 0;
                for (int index = 0; index < prover.MemberSet.Length; ++index)
                {
                    if (index != indexOfCommittedValue)
                    {
                        this.generateFakeProof(index, prover, smRandom.c[randomIndex], smRandom.r[randomIndex]);
                        sumOfSubChallenges += smRandom.c[randomIndex];
                        randomIndex++;
                    }
                }

                // generate challenge, and a real proof for committment.CommittedValue
                this.generateRealA(indexOfCommittedValue, prover, smRandom.w);
                FieldZqElement challenge = this.ComputeChallenge(prover);
                this.generateRealProof(indexOfCommittedValue, prover, smRandom.w, sumOfSubChallenges.Negate() + challenge);
            }
            catch (Exception e)
            {
                throw new Exception("Could not create SetMembershipProof.", e);
            }
        }
        /// <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));
        }
Exemple #5
0
        public void ConstructorHelper(ProverBitDecompositionParameters prover)
        {
            try
            {
                if (!prover.Verify())
                {
                    throw new ArgumentException("Could not create BitDecompositionProof because prover parameters are invalid.");
                }

                this.Group = prover.Group;
                this.IsGroupSerializable = true;

                // Generate proof that each Pedersen Commitment in prover.OpenBitDecomposition
                // is a valid commitment to either 0 or 1.
                this.bitCommitmentProof = new SetMembershipProof[prover.DecompositionLength];
                FieldZqElement[] memberSet = BitDecompositionProof.SetOfZeroAndOne(prover);
                for (int proofIndex = 0; proofIndex < bitCommitmentProof.Length; ++proofIndex)
                {
                    ProverSetMembershipParameters psmParameters = new ProverSetMembershipParameters(
                        prover.OpenBitDecomposition(proofIndex),
                        memberSet,
                        prover);
                    bitCommitmentProof[proofIndex] = new SetMembershipProof(psmParameters);
                    bitCommitmentProof[proofIndex].IsGroupSerializable = false;
                }

                //now create proof that actualComposedBits and parameters.OpenCommitment are
                //commitments to the same value.
                PedersenCommitment actualComposedBits;
                if (ComposeCommitments(prover.OpenBitDecomposition(), prover.FieldZq, out actualComposedBits))
                {
                    ProverEqualityParameters peParameters =
                        new ProverEqualityParameters(
                            actualComposedBits,
                            0,
                            prover.OpenCommitment,
                            0,
                            prover);
                    this.compositionProof = new EqualityProof(peParameters);
                    this.compositionProof.IsGroupSerializable = false;
                }
                else
                {
                    throw new Exception("Could not create BitDecompositionProof.");
                }
            }
            catch (Exception e)
            {
                throw e;
            }
        }
        /// <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;
        }
 /// <summary>
 /// Helper method for constructing proof.
 /// Computes a[index].
 /// </summary>
 /// <param name="index">Index into prover.MemberSet</param>
 /// <param name="prover">Prover parameters</param>
 /// <param name="randomWValue">random value</param>
 private void generateRealA(int index, ProverSetMembershipParameters prover, FieldZqElement randomWValue)
 {
     this.a[index] = prover.OpenCommitment.H.Exponentiate(randomWValue);
 }
        }                                                // responses

        /// <summary>
        /// Constructs a SetMembershipProof.  Throws exception if prover
        /// parameters do not allow creating valid proof.
        /// </summary>
        /// <param name="prover">Prover parameters</param>
        /// <param name="smRandom">The optional pre-generated random values to generate the proof, or <c>null</c>.</param>
        public SetMembershipProof(ProverSetMembershipParameters prover, SetMembershipProofGenerationRandomData smRandom = null)
        {
            ConstructorHelper(prover, smRandom);
        }
Exemple #9
0
        public void ConstructorHelper(ProverRangeProofParameters prover)
        {
            try
            {
                // verify prover parameters
                if (!prover.Verify())
                {
                    throw new ArgumentException("RangeProof: could not create RangeProof because prover parameters are invalid.");
                }


                // set group
                this.Group = prover.Group;
                this.IsGroupSerializable = true;

                // set up the bit decomposition proof and compute helper values
                DLRepOfGroupElement[] openAdivB = CreateBitDecompositionProofs(prover);
                if (this.ProofBitDecompositionOfA != null)
                {
                    this.ProofBitDecompositionOfA.IsGroupSerializable = false;
                }
                if (this.ProofBitDecompositionOfB != null)
                {
                    this.ProofBitDecompositionOfB.IsGroupSerializable = false;
                }
                DLRepOfGroupElement[] openD = ComputeOpenD(prover, openAdivB);

                DLRepOfGroupElement[] openX = ComputeOpenX(prover, openAdivB);
                DLRepOfGroupElement[] openE = ComputeOpenE(prover, openD, openX, openAdivB);

                // compute RangeProof
                DLRepOfGroupElement[]    allOpenDL = CombineAllOpenDLReps(openD, openAdivB, openX, openE);
                EqualityMap              map       = ComputeEqualityMap(prover, A.Length);
                ProverEqualityParameters peParams  = new ProverEqualityParameters(
                    allOpenDL,
                    map,
                    prover);
                this.FullRangeProof = new EqualityProof(peParams);
                this.FullRangeProof.IsGroupSerializable = false;

                // set X and D
                this.SetX(openX);
                this.SetD(openD);

                // create additional proofs based on proof type
                PedersenCommitment LastD = (PedersenCommitment)openD[openD.Length - 1];
                switch (prover.RangeProofType)
                {
                case VerifierRangeProofParameters.ProofType.GREATER_THAN:
                // Prove that D is a commitment to 1
                case VerifierRangeProofParameters.ProofType.LESS_THAN:
                    // Prove that D is a commitment to -1
                    DLRepOfGroupElement equation = new DLRepOfGroupElement(
                        new GroupElement[1] {
                        prover.H
                    },
                        new FieldZqElement[1] {
                        LastD.ExponentAtIndex(1)
                    },
                        prover.Group);
                    ProverEqualityParameters strictProver = new ProverEqualityParameters(
                        equation,
                        prover);
                    this.StrictlyThanProof = new EqualityProof(strictProver);
                    this.StrictlyThanProof.IsGroupSerializable = false;
                    break;

                case VerifierRangeProofParameters.ProofType.GREATER_THAN_OR_EQUAL_TO:
                    // Prove that D is a commitment to either 0 or 1
                    ProverSetMembershipParameters greaterEqualProver = new ProverSetMembershipParameters(
                        LastD,
                        new FieldZqElement[] { prover.FieldZq.Zero, prover.FieldZq.One },
                        prover);
                    this.OrEqualToProof = new SetMembershipProof(greaterEqualProver);
                    this.OrEqualToProof.IsGroupSerializable = false;
                    break;

                case VerifierRangeProofParameters.ProofType.LESS_THAN_OR_EQUAL_TO:
                    // Prove that D is a commitment to either 0 or -1
                    ProverSetMembershipParameters lessEqualProver = new ProverSetMembershipParameters(
                        LastD,
                        new FieldZqElement[] { prover.FieldZq.Zero, prover.FieldZq.One.Negate() },
                        prover);
                    this.OrEqualToProof = new SetMembershipProof(lessEqualProver);
                    this.OrEqualToProof.IsGroupSerializable = false;
                    break;
                }
            }
            catch (Exception e)
            {
                throw new Exception("RangeProof: Could not create range proof.", e);
            }
        }