Exemple #1
0
        /// <summary>
        /// If verifier knows Integer B, returns the default bit-decomposition. Returns Null if verifier does not know integer B.
        /// If bit[i] = 0, output[i] = verifier.G^0.
        /// If bit[i] = 1, output[i] = verifier.G.
        /// </summary>
        /// <param name="verifier">Verifier parameters.</param>
        /// <returns></returns>
        private static DLRepOfGroupElement[] DefaultOpenDecompositionOfIntegerB(VerifierRangeProofParameters verifier)
        {
            if (!verifier.IntegerBIsKnown)
            {
                return(null);
            }
            FieldZqElement integerB            = verifier.FieldZq.GetElement((uint)verifier.RangeNormalizedIntegerB);
            int            decompositionLength = ComputeDecompositionLength(verifier);
            BitArray       bitsB = VerifierBitDecompositionParameters.GetBitDecomposition(integerB, decompositionLength, verifier.FieldZq);

            PedersenCommitment[] defaultBitDecomposition = new PedersenCommitment[bitsB.Length];
            GroupElement []      bases = new GroupElement [2] {
                verifier.G, verifier.H
            };
            FieldZqElement [] exponent0 = new FieldZqElement[2] {
                verifier.FieldZq.Zero, verifier.FieldZq.Zero,
            };

            FieldZqElement [] exponent1 = new FieldZqElement[2] {
                verifier.FieldZq.One, verifier.FieldZq.Zero,
            };

            for (int i = 0; i < defaultBitDecomposition.Length; ++i)
            {
                if (!bitsB.Get(i))
                {
                    defaultBitDecomposition[i] = new PedersenCommitment(bases, exponent0, verifier.Group);
                }
                else
                {
                    defaultBitDecomposition[i] = new PedersenCommitment(bases, exponent1, verifier.Group);
                }
            }
            return(defaultBitDecomposition);
        }
Exemple #2
0
        /// <summary>
        /// Returns the number of bits needed to represent the committed value in ClosedIntegerA
        /// and ClosedIntegerB.  This is computed  ceiling(log_2 MaxValue-MinValue)
        /// </summary>
        /// <param name="verifier"></param>
        /// <returns></returns>
        private static int ComputeDecompositionLength(VerifierRangeProofParameters verifier)
        {
            int    range     = verifier.MaxValue - verifier.MinValue;
            double exactBits = System.Math.Log(range, 2.0);

            return((int)System.Math.Ceiling(exactBits));
        }
Exemple #3
0
        /// <summary>
        /// Returns array of ClosedDLRepOfGroupElement objects, where output[i] = A[i] / B[i].
        /// If verifier.IntegerBIsKnown is true, replaces input B with default B.
        /// </summary>
        /// <param name="verifier">Used to get bases G and H. If verifier knows B, generates new array B.</param>
        /// <param name="A">Array of group elements.</param>
        /// <param name="B">Array of group elements of same length as A. May be null if verifier.IntegerBIsKnown is true.</param>
        /// <returns></returns>
        public static GroupElement[] ComputeClosedAdivB(VerifierRangeProofParameters verifier, GroupElement[] A, GroupElement[] B)
        {
            if (verifier.IntegerBIsKnown)
            {
                B = DefaultClosedDecompositionOfIntegerB(verifier);
            }

            GroupElement [] closedAdivB = new GroupElement[A.Length];
            for (int i = 0; i < closedAdivB.Length; ++i)
            {
                closedAdivB[i] = verifier.Group.Divide(A[i], B[i]);
            }
            return(closedAdivB);
        }
Exemple #4
0
 /// <summary>
 /// Computes closed DL representation of E[i] = D[i]/D[i-1] * closedAdivB[i]^{-1}.
 /// Bases are X^{-1} and verifier.H.
 /// </summary>
 /// <param name="verifier">Verifier range proof parameters.</param>
 /// <param name="X">Array of commitments to (a-b)^2</param>
 /// <param name="D">Array of commitments to d.</param>
 /// <param name="closedAdivB">A/B</param>
 /// <returns>Array of same length as X, first element is null.</returns>
 public static ClosedDLRepOfGroupElement[] ComputeClosedE(VerifierRangeProofParameters verifier, GroupElement[] X, GroupElement[] D, GroupElement[] closedAdivB)
 {
     ClosedDLRepOfGroupElement[] closedE = new ClosedDLRepOfGroupElement[X.Length];
     closedE[0] = null;
     for (int i = 1; i < closedE.Length; ++i)
     {
         closedE[i] = new ClosedDLRepOfGroupElement(
             new GroupElement[2] {
             verifier.Group.Invert(X[i]), verifier.H
         },
             verifier.Group.Divide(new GroupElement[] { D[i] }, new GroupElement[] { D[i - 1], closedAdivB[i] }),
             verifier.Group);
     }
     return(closedE);
 }
Exemple #5
0
 /// <summary>
 /// Computes closed DL representation equations for X using
 /// bases closedAdivB[i] and verifier.H.
 /// </summary>
 /// <param name="verifier">Used to get base verifier.H</param>
 /// <param name="X">Array of group elements</param>
 /// <param name="closedAdivB">Used for base at index 0.</param>
 /// <returns>Array of same length as X, first element is null.</returns>
 public static ClosedDLRepOfGroupElement[] ComputeClosedX(VerifierRangeProofParameters verifier, GroupElement[] X, GroupElement [] closedAdivB)
 {
     ClosedDLRepOfGroupElement[] closedX = new ClosedDLRepOfGroupElement[X.Length];
     closedX[0] = null;
     for (int i = 1; i < X.Length; ++i)
     {
         closedX[i] = new ClosedDLRepOfGroupElement(
             new GroupElement[2] {
             closedAdivB[i], verifier.H
         },
             X[i],
             verifier.Group);
     }
     return(closedX);
 }
Exemple #6
0
        public bool Verify(
            VerifierPresentationProtocolParameters verifier1,
            int attributeIndexForVerifier1,
            VerifierRangeProofParameters.ProofType proofType,
            VerifierPresentationProtocolParameters verifier2,
            int attributeIndexForVerifier2,
            int minYear,
            int maxYear)
        {
            // Verify target attribute is not hashed
            if ((verifier1.IP.E[attributeIndexForVerifier1 - 1] == 0x01) || (verifier2.IP.E[attributeIndexForVerifier1 - 1] == 0x01))
            {
                return(false);
            }


            // Verify UProve Integration Proof
            if (this.UPIProof == null)
            {
                return(false);
            }
            VerifierPresentationProtocolParameters[] verifiers = new VerifierPresentationProtocolParameters[2] {
                verifier1, verifier2
            };
            int[] attributeIndices = new int[2] {
                attributeIndexForVerifier1, attributeIndexForVerifier2
            };
            if (!this.UPIProof.Verify(verifiers, attributeIndices))
            {
                return(false);
            }

            // Verify Range Proof
            VerifierRangeProofParameters rangeVerifier = new VerifierRangeProofParameters(
                new CryptoParameters(verifier1.IP),
                this.UPIProof.PedersenCommitmentValues[0],
                proofType,
                this.UPIProof.PedersenCommitmentValues[1],
                minYear,
                maxYear);

            return(this.Verify(rangeVerifier));
        }
Exemple #7
0
        /// <summary>
        /// Computes the EqualityMap used by both the prover and verifier.
        /// </summary>
        /// <param name="verifier">Public parameters</param>
        /// <param name="decompositionLength">Number of bits used to represent integer A and integer B (e.g. A.Length)</param>
        /// <returns>EqualityMap</returns>
        public static EqualityMap ComputeEqualityMap(VerifierRangeProofParameters verifier, int decompositionLength)
        {
            EqualityMap map     = new EqualityMap();
            int         dlIndex = 0;

            // process forall i in [0,m-2] D[i] = g^{delta,i} h^{tau,i}
            for (int i = 0; i < decompositionLength - 1; ++i)
            {
                map.Add(new PrettyName("delta", i), new DoubleIndex(dlIndex, 0));
                ++dlIndex;
            }
            // skip D[m -1] -- this will be a separate proof based on RangeProofType

            // process forall i in [1,m-1]:  A[i]/B[i] = g^{chi,i} h^{zeta,i}
            // Note: A[0]/B[0] appears in the proof indirectly as D[0]
            for (int i = 1; i < decompositionLength; ++i)
            {
                map.Add(new PrettyName("chi", i), new DoubleIndex(dlIndex, 0));
                ++dlIndex;
            }

            // process forall i in [1,m-1]: X[i] = (A[i]/B[i])^{chi,i} h^{mu,i}
            // Note: X[0]=null.
            for (int i = 1; i < decompositionLength; ++i)
            {
                map.Add(new PrettyName("chi", i), new DoubleIndex(dlIndex, 0));
                ++dlIndex;
            }

            // process forall i in [1,m-1]: E[i] = (X[i]^-1)^{delta, i-1} h^{nu,i}
            // Note: E[0] = null.
            for (int i = 1; i < decompositionLength; ++i)
            {
                map.Add(new PrettyName("delta", i - 1), new DoubleIndex(dlIndex, 0));
                ++dlIndex;
            }

            return(map);
        }
Exemple #8
0
        /// <summary>
        /// If verifier knows Integer B, returns the default bit-decomposition. Returns Null if verifier does not know integer B.
        /// If bit[i] = 0, output[i] = verifier.G^0.
        /// If bit[i] = 1, output[i] = verifier.G.
        /// </summary>
        /// <param name="verifier">Verifier parameters.</param>
        /// <returns></returns>
        private static GroupElement[] DefaultClosedDecompositionOfIntegerB(VerifierRangeProofParameters verifier)
        {
            if (!verifier.IntegerBIsKnown)
            {
                return(null);
            }
            FieldZqElement integerB            = verifier.FieldZq.GetElement((uint)verifier.RangeNormalizedIntegerB);
            int            decompositionLength = ComputeDecompositionLength(verifier);
            BitArray       bitsB = VerifierBitDecompositionParameters.GetBitDecomposition(integerB, decompositionLength, verifier.FieldZq);

            GroupElement[] defaultBitDecomposition = new GroupElement[bitsB.Length];
            for (int i = 0; i < defaultBitDecomposition.Length; ++i)
            {
                if (bitsB.Get(i))
                {
                    defaultBitDecomposition[i] = verifier.G;
                }
                else
                {
                    defaultBitDecomposition[i] = verifier.Group.Identity;
                }
            }
            return(defaultBitDecomposition);
        }
Exemple #9
0
        /// <summary>
        /// Verifies that A is a valid bit decomposition of verifier.ClosedIntegerA and
        /// B is a valid bit decomposition of verifier.ClosedIntegerB.
        /// </summary>
        /// <param name="verifier"></param>
        /// <param name="A">Bit decomposition of A.</param>
        /// <param name="B">Bit decomposition of B.</param>
        /// <param name="proofA">Proof that A is a valid bit decomposition of verifier.ClosedIntegerA.</param>
        /// <param name="proofB">Proof that B is a valid bit decomposition of verifier.ClosedIntegerB.</param>
        /// <returns></returns>
        private static bool VerifyBitDecompositionProofs(VerifierRangeProofParameters verifier, GroupElement [] A, GroupElement [] B, BitDecompositionProof proofA, BitDecompositionProof proofB)
        {
            // verify A

            VerifierBitDecompositionParameters bitVerifierA = new VerifierBitDecompositionParameters(verifier.RangeNormalizedClosedIntegerA, A, verifier);

            if (!proofA.Verify(bitVerifierA))
            {
                return(false);
            }

            // verify B
            if ((verifier.IntegerBIsKnown) && (B == null) && (proofB == null))
            {
                return(true);
            }
            VerifierBitDecompositionParameters bitVerifierB = new VerifierBitDecompositionParameters(verifier.RangeNormalizedClosedIntegerB, B, verifier);

            if (!proofB.Verify(bitVerifierB))
            {
                return(false);
            }
            return(true);
        }
Exemple #10
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);
        }