/// <summary>
        /// Compute this.b array for the proof.
        /// </summary>
        /// <param name="prover">Prover parameters</param>
        /// <param name="equalW">w values for when exponents are equal</param>
        /// <param name="unequalW">w values for when exponents are unequal</param>
        private void ComputeB(ProverEqualityParameters prover, FieldZqElement[] equalW, FieldZqElement[] unequalW)
        {
            int unequalWIndex = 0;

            this.b = new GroupElement[prover.Witnesses.Length];
            for (int witnessIndex = 0; witnessIndex < this.b.Length; ++witnessIndex)
            {
                FieldZqElement[] randomData = new FieldZqElement[prover.Witnesses[witnessIndex].RepresentationLength];

                for (int exponentIndex = 0; exponentIndex < randomData.Length; ++exponentIndex)
                {
                    DoubleIndex di = new DoubleIndex(witnessIndex, exponentIndex);
                    int         equalWIndex;
                    if (prover.Map.TryRetrieveIntIndex(di, out equalWIndex))
                    {
                        randomData[exponentIndex] = equalW[equalWIndex];
                    }
                    else
                    {
                        randomData[exponentIndex] = unequalW[unequalWIndex];
                        ++unequalWIndex;
                    }
                }
                this.b[witnessIndex] = prover.Witnesses[witnessIndex].ComputeCommitment(randomData);
            }
        }
        /// <summary>
        /// Computes the resonses to the challenge.
        /// </summary>
        /// <param name="prover">Prover parameters.</param>
        /// <param name="equalW">random data for exponents in equality map.</param>
        /// <param name="unequalW">random data for exponents not in equality map.</param>
        private void ComputeResponses(ProverEqualityParameters prover, FieldZqElement[] equalW, FieldZqElement[] unequalW)
        {
            FieldZqElement challenge = ComputeChallenge(prover);

            this.responseEqual   = new FieldZqElement[equalW.Length];
            this.responseUnequal = new FieldZqElement[unequalW.Length];

            int unequalWIndex = 0;

            for (int witnessIndex = 0; witnessIndex < prover.Witnesses.Length; ++witnessIndex)
            {
                for (int exponentIndex = 0; exponentIndex < prover.Witnesses[witnessIndex].RepresentationLength; ++exponentIndex)
                {
                    FieldZqElement exponent = prover.Witnesses[witnessIndex].ExponentAtIndex(exponentIndex);

                    DoubleIndex di = new DoubleIndex(witnessIndex, exponentIndex);
                    int         equalWIndex;
                    if (prover.Map.TryRetrieveIntIndex(di, out equalWIndex))
                    {
                        FieldZqElement wValue = equalW[equalWIndex];
                        this.responseEqual[equalWIndex] = prover.Witnesses[witnessIndex].ComputeResponse(challenge, wValue, exponentIndex);
                    }
                    else
                    {
                        FieldZqElement wValue = unequalW[unequalWIndex];
                        this.responseUnequal[unequalWIndex] = prover.Witnesses[witnessIndex].ComputeResponse(challenge, wValue, exponentIndex);
                        ++unequalWIndex;
                    }
                }
            }
        }
        private void ConstructorHelper(ProverEqualityParameters prover)
        {
            // check prover parameters
            if (!prover.Verify())
            {
                throw new Exception("EqualityProof constructor failed. Invalid prover parameters.");
            }

            try
            {
                // set Group
                this.Group = prover.Group;
                this.IsGroupSerializable = true;

                // generate random w values
                FieldZqElement[] equalW;
                FieldZqElement[] unequalW;
                this.GenerateRandomData(prover, out equalW, out unequalW);

                //compute proof
                this.ComputeB(prover, equalW, unequalW);
                this.ComputeResponses(prover, equalW, unequalW);
            }
            catch (Exception e)
            {
                throw new Exception("Could not create EqualityProof.", e);
            }
        }
        /// <summary>
        /// Generates the random w values needed to compute the proof.
        /// </summary>
        /// <param name="prover">Prover parameters</param>
        /// <param name="equalW">Output array to place w values for when exponents are equal</param>
        /// <param name="unequalW">Output array to place w values for when exponents are unequal</param>
        private void GenerateRandomData(ProverEqualityParameters prover, out FieldZqElement[] equalW, out FieldZqElement[] unequalW)
        {
            equalW = prover.FieldZq.GetRandomElements(prover.Map.CountPrettyName, true);
            int lengthUnequalW = 0 - prover.Map.CountEquationAndExponentIndices;

            for (int dlIndex = 0; dlIndex < prover.Witnesses.Length; ++dlIndex)
            {
                lengthUnequalW += prover.Witnesses[dlIndex].RepresentationLength;
            }
            unequalW = prover.FieldZq.GetRandomElements(lengthUnequalW, true);
        }
Ejemplo n.º 5
0
        /// <summary>
        /// Generates a list of Pedersen Commitments
        /// </summary>
        /// <param name="prover">Array of tokens</param>
        /// <param name="attributeIndices">target attribute for each token</param>
        /// <param name="commitmentsToAttribute">Pedersen commitment to target attribute in token.  Generated via method
        /// Proof.PedersenCommmitmentsToAttributes</param>
        public UProveIntegrationProof(ProverPresentationProtocolParameters [] prover, int [] attributeIndices, PedersenCommitment [] commitmentsToAttribute)
        {
            if ((prover == null) || (prover.Length == 0))
            {
                throw new ArgumentException("First argument should be an array of at least one element.");
            }

            if (!UProveIntegrationProof.AreTokensCompatible(prover))
            {
                throw new ArgumentException("All tokens must use same group.");
            }


            if ((attributeIndices == null) || (attributeIndices.Length != prover.Length))
            {
                throw new ArgumentNullException("Second argument must be an array of the same length as first argument.");
            }

            if ((commitmentsToAttribute == null) || (commitmentsToAttribute.Length != prover.Length))
            {
                throw new ArgumentNullException("Third argument must be an array of the same length as first argument.");
            }

            // copy Pedersen Commitment values
            this.PedersenCommitmentValues = new GroupElement[prover.Length];
            for (int i = 0; i < PedersenCommitmentValues.Length; ++i)
            {
                this.PedersenCommitmentValues[i] = commitmentsToAttribute[i].Value;
            }

            // Create Equality Proof between Pedersen Commitments and tokens.
            EqualityMap map = new EqualityMap();

            IWitness []       witnesses = new IWitness[prover.Length * 2];
            OpenUProveToken[] tokens    = new OpenUProveToken[prover.Length];
            for (int i = 0; i < tokens.Length; ++i)
            {
                // create uprove token and add target attribute to map
                witnesses[2 * i] = new OpenUProveToken(prover[i]);
                map.Add(new PrettyName("token", 2 * i), new DoubleIndex(i, attributeIndices[i]));

                // add pedersen commitment to witness list, and add to map
                witnesses[2 * i + 1] = commitmentsToAttribute[i];
                map.Add(new PrettyName("token", 2 * i + 1), new DoubleIndex(i, 0));
            }

            ProverEqualityParameters eqProver = new ProverEqualityParameters(witnesses, map, new CryptoParameters(prover[0].IP));

            this.TokenCommitmentEqualityProof = new EqualityProof(eqProver);
            this.TokenCommitmentEqualityProof.IsGroupSerializable = false;
        }
Ejemplo n.º 6
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;
            }
        }
Ejemplo n.º 7
0
        /// <summary>
        /// Genererates proof for when prover.CompareToKnownValue=true.
        /// </summary>
        /// <param name="prover"></param>
        private void CreateProofForKnownValue(ProverInequalityProofParameters prover)
        {
            // Pedersen Commitment to a random value a
            // A = g^a h^r
            FieldZqElement     a     = prover.FieldZq.GetRandomElement(true);
            FieldZqElement     r     = prover.FieldZq.GetRandomElement(true);
            PedersenCommitment openA = new PedersenCommitment(prover.G, prover.H, a, r, prover.Group);

            // B = g^(x-value)a
            DLRepOfGroupElement openB = new DLRepOfGroupElement(
                new GroupElement[1] {
                prover.G
            },
                new FieldZqElement[1] {
                (prover.CommitmentX.CommittedValue - prover.Value) * a
            },
                prover.Group
                );

            // C = (Xg^{-value})^a h^{-ya} = B
            PedersenCommitment openC = new PedersenCommitment(
                prover.CommitmentX.Value * prover.G.Exponentiate(prover.Value.Negate()),
                prover.H,
                a,
                a.Negate() * prover.CommitmentX.Opening,
                prover.Group
                );

            // Create DL equations
            DLRepOfGroupElement[] equations = new DLRepOfGroupElement[]
            {
                prover.CommitmentX,
                openA,
                openB,
                openC
            };

            // generate proof
            EqualityMap map = this.GetEqualityMap();
            ProverEqualityParameters eqProver = new ProverEqualityParameters(equations, map, prover);

            this.Proof = new EqualityProof(eqProver);
            this.A     = openA.Value;
            this.B     = openB.Value;
        }
        /// <summary>
        /// Generate a proof that two tokens share an attribute value, without revealing it.
        /// </summary>
        /// <param name="prover1">Equality proof parameters for the first token.</param>
        /// <param name="prover2">Equality proof parameters for the second token.</param>
        /// <returns>An equality proof.</returns>
        public static EqualityProof GenerateUProveEqualityProof(EQProofUProveProverData prover1, EQProofUProveProverData prover2)
        {
            if (!prover1.PPPP.IP.Gq.Equals(prover2.PPPP.IP.Gq))
            {
                throw new ArgumentException("both provers must share the same group");
            }
            // Create PedersenCommitments
            int commitmentIndex1    = ClosedPedersenCommitment.GetCommitmentIndex(prover1.PPPP.Committed, prover1.index);
            PedersenCommitment ped1 = new PedersenCommitment(prover1.PPPP, prover1.PP, prover1.CPV, commitmentIndex1);
            int commitmentIndex2    = ClosedPedersenCommitment.GetCommitmentIndex(prover2.PPPP.Committed, prover2.index);
            PedersenCommitment ped2 = new PedersenCommitment(prover2.PPPP, prover2.PP, prover2.CPV, commitmentIndex2);

            // Create EqualityProof
            CryptoParameters         crypto         = new CryptoParameters(prover1.PPPP.IP);                  // Can use prover2.IP
            ProverEqualityParameters equalityProver = new ProverEqualityParameters(ped1, 0, ped2, 0, crypto); // compares committed values in ped1 and ped2

            return(new EqualityProof(equalityProver));
        }
        /// <summary>
        /// Constructor. Creates proof that two UProve tokens have equal attributes.
        /// </summary>
        /// <param name="prover1">Description of token 1.</param>
        /// <param name="attributeIndexForProver1">1-based index for target attribute in token 1.</param>
        /// <param name="prover2">Description of token 2.</param>
        /// <param name="attributeIndexForProver2">1-based index for target attribute in token 2.</param>
        public EqualityProof(ProverPresentationProtocolParameters prover1, int attributeIndexForProver1, ProverPresentationProtocolParameters prover2, int attributeIndexForProver2)
        {
            if (!prover1.IP.Gq.Equals(prover2.IP.Gq))
            {
                throw new ArgumentException("both provers must share the same group");
            }

            // Create OpenUProveTokens
            OpenUProveToken token1 = new OpenUProveToken(prover1);
            OpenUProveToken token2 = new OpenUProveToken(prover2);

            // Create proof
            ProverEqualityParameters eqProver = new ProverEqualityParameters(
                token1,
                attributeIndexForProver1,
                token2,
                attributeIndexForProver2,
                new CryptoParameters(prover1.IP));

            ConstructorHelper(eqProver);
        }
Ejemplo n.º 10
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);
            }
        }
 /// <summary>
 /// Creates an equality proof given the prover parameters.
 /// </summary>
 /// <param name="prover"></param>
 public EqualityProof(ProverEqualityParameters prover)
 {
     ConstructorHelper(prover);
 }