Example #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);
        }
Example #2
0
        /// <summary>
        /// Returns an array of Zero and One FieldZqElements, in Small Endian notation.
        /// So sum result[i] * 2^i = integer.  If decompositionLength is too short,
        /// returns the minimum length array with the correct decomposition.
        /// </summary>
        /// <param name="integer">Integer to decompose</param>
        /// <param name="decompositionLength">Minimum number of bits.</param>
        /// <param name="fieldZq">Field</param>
        /// <returns></returns>
        public static BitArray GetBitDecomposition(FieldZqElement integer, int decompositionLength, FieldZq fieldZq)
        {
            // get bit array
            BitArray bits = new BitArray(VerifierBitDecompositionParameters.Reverse(integer.ToByteArray()));

            // compute minimum decompositionLength
            if ((decompositionLength < IndexOfMostSignificantNonZeroBit(bits) + 1))
            {
                decompositionLength = IndexOfMostSignificantNonZeroBit(bits) + 1;
            }

            // translate bits into array of FieldZqElements
            BitArray bitDecomposition = new BitArray(decompositionLength);

            for (int bitIndex = 0; bitIndex < bitDecomposition.Length; ++bitIndex)
            {
                if ((bitIndex < bits.Length) && bits.Get(bitIndex))
                {
                    bitDecomposition.Set(bitIndex, true);
                }
                else
                {
                    bitDecomposition.Set(bitIndex, false);
                }
            }
            return(bitDecomposition);
        }
Example #3
0
        /// <summary>
        /// Gets verifier parameters corresponding to this object.
        /// </summary>
        /// <returns></returns>
        public VerifierBitDecompositionParameters GetVerifierParameters()
        {
            VerifierBitDecompositionParameters verifierParams = new VerifierBitDecompositionParameters(
                this.ClosedCommitment,
                this.ClosedBitDecomposition(),
                this);

            return(verifierParams);
        }
Example #4
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);
            }
        }
Example #5
0
        /// <summary>
        /// Constructs a bit decomposition of openCommitment.CommittedValue and
        /// generates the appropriate ProverBitDecompositionParameters.
        /// If decompositionLength is too short, automatically chooses
        /// minimum required length.
        /// </summary>
        /// <param name="openCommitment">Pedersen Commitment to some value</param>
        /// <param name="decompositionLength">Number of bits in bit-decomposition.</param>
        /// <param name="parameterSet">Parameter set</param>
        /// <returns></returns>
        public ProverBitDecompositionParameters(
            PedersenCommitment openCommitment,
            int decompositionLength,
            CryptoParameters crypto)
            : base(crypto)
        {
            BitArray bits = VerifierBitDecompositionParameters.GetBitDecomposition(openCommitment.CommittedValue, decompositionLength, this.FieldZq);

            PedersenCommitment [] openBitDecomposition = new PedersenCommitment[bits.Length];
            for (int bitIndex = 0; bitIndex < bits.Length; ++bitIndex)
            {
                if (bits.Get(bitIndex))
                {
                    openBitDecomposition[bitIndex] = new PedersenCommitment(crypto.FieldZq.One, crypto);
                }
                else
                {
                    openBitDecomposition[bitIndex] = new PedersenCommitment(crypto.FieldZq.Zero, crypto);
                }
            }
            this.setProverParameters(openBitDecomposition, openCommitment);
        }
Example #6
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);
        }
Example #7
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);
        }
Example #8
0
        /// <summary>
        /// Constructor.  Takes as input an integer, creates a Pedersen Commitment to it, and generates
        /// a sequence of Pedersen Commitments to its bit decomposition.
        /// </summary>
        /// <param name="integer">Creates a Pedersen Commitment to this value.</param>
        /// <param name="decompositionLength">Minimum number of integers in the decomposition.</param>
        /// <param name="crypto">Cryptographic parameters.</param>
        /// <param name="hideCommittedValue">Decomposed integer is secret.</param>
        public ProverBitDecompositionParameters(FieldZqElement integer, int decompositionLength, CryptoParameters crypto, bool hideCommittedValue = true)
            : base(crypto)
        {
            BitArray bits = VerifierBitDecompositionParameters.GetBitDecomposition(integer, decompositionLength, this.FieldZq);

            PedersenCommitment[] openCommittedBits = new PedersenCommitment[bits.Length];
            PedersenCommitment   openCommitment;

            if (hideCommittedValue)
            {
                for (int i = 0; i < bits.Length; ++i)
                {
                    FieldZqElement curBit = this.FieldZq.Zero;
                    if (bits.Get(i))
                    {
                        curBit = this.FieldZq.One;
                    }
                    openCommittedBits[i] = new PedersenCommitment(curBit, this);
                }
                openCommitment = new PedersenCommitment(integer, this);
            }
            else
            {
                for (int i = 0; i < bits.Length; ++i)
                {
                    FieldZqElement curBit = this.FieldZq.Zero;
                    if (bits.Get(i))
                    {
                        curBit = this.FieldZq.One;
                    }
                    openCommittedBits[i] = new PedersenCommitment(this.G, this.H, curBit, this.FieldZq.Zero, this.Group);
                }
                openCommitment = new PedersenCommitment(this.G, this.H, integer, this.FieldZq.Zero, this.Group);
            }
            this.setProverParameters(openCommittedBits, openCommitment);
        }
Example #9
0
        /// <summary>
        /// Sets verifier parameters for situations when the committed value is known
        /// to the verifier.  Computes the bit decomposition for committedValue
        /// ClosedCommittment = G^committedValue
        /// ClosedCommittedBit[i] = G^bit[i]
        /// </summary>
        /// <param name="committedValue">Committed value.</param>
        /// <param name="decompositionLength">Minimum bit decomposition length.</param>
        public void setVerifierParameters(FieldZqElement committedValue, int decompositionLength)
        {
            if (committedValue == null)
            {
                base.setVerifierParameters(null);
                return;
            }
            BitArray commitedBits = VerifierBitDecompositionParameters.GetBitDecomposition(committedValue, decompositionLength, this.FieldZq);

            GroupElement[] publicValues = new GroupElement[commitedBits.Length + 1];
            for (int i = 0; i < commitedBits.Length; ++i)
            {
                if (!commitedBits.Get(i))
                {
                    publicValues[i] = this.Group.Identity;
                }
                else
                {
                    publicValues[i] = this.G;
                }
            }
            publicValues[publicValues.Length - 1] = this.G.Exponentiate(committedValue);
            this.setVerifierParameters(publicValues);
        }
Example #10
0
        /// <summary>
        /// Verifies that the ProverRangeProofParameters are valid.
        /// </summary>
        /// <returns>True if parameters are valid.</returns>
        new public bool Verify()
        {
            if (!base.Verify())
            {
                return(false);
            }

            // check that they're in range
            BitArray maxValueBits        = VerifierBitDecompositionParameters.GetBitDecomposition(this.GetRangeNormalizedFieldZqElement(this.MaxValue), 0, this.FieldZq);
            int      decompositionLength = maxValueBits.Length;
            BitArray minValueBits        = VerifierBitDecompositionParameters.GetBitDecomposition(this.GetRangeNormalizedFieldZqElement(this.MinValue), decompositionLength, this.FieldZq);


            // check integer A and integer B exist
            if (this.OpenIntegerA == null)
            {
                return(false);
            }
            BitArray bitA = VerifierBitDecompositionParameters.GetBitDecomposition(this.RangeNormalizedOpenIntegerA.ExponentAtIndex(0), decompositionLength, this.FieldZq);
            BitArray bitB;

            if (this.IntegerBIsKnown)
            {
                bitB = VerifierBitDecompositionParameters.GetBitDecomposition(this.GetRangeNormalizedFieldZqElement(this.IntegerB), decompositionLength, this.FieldZq);
            }
            else
            {
                if (this.OpenIntegerB == null)
                {
                    return(false);
                }
                bitB = VerifierBitDecompositionParameters.GetBitDecomposition(this.RangeNormalizedOpenIntegerB.ExponentAtIndex(0), decompositionLength, this.FieldZq);
            }

            // make sure integerA and integerB are in range.
            if ((Compare(bitA, minValueBits) < 0) ||
                (Compare(bitA, maxValueBits) > 0) ||
                (Compare(bitB, minValueBits) < 0) ||
                (Compare(bitB, maxValueBits) > 0))
            {
                return(false);
            }

            // now compare integerA and integerB based on range proof type.
            switch (this.RangeProofType)
            {
            case VerifierRangeProofParameters.ProofType.GREATER_THAN:
                if (Compare(bitA, bitB) <= 0)
                {
                    return(false);
                }
                break;

            case VerifierRangeProofParameters.ProofType.GREATER_THAN_OR_EQUAL_TO:
                if (Compare(bitA, bitB) < 0)
                {
                    return(false);
                }
                break;

            case VerifierRangeProofParameters.ProofType.LESS_THAN:
                if (Compare(bitA, bitB) >= 0)
                {
                    return(false);
                }
                break;

            case VerifierRangeProofParameters.ProofType.LESS_THAN_OR_EQUAL_TO:
                if (Compare(bitA, bitB) > 0)
                {
                    return(false);
                }
                break;
            }

            return(true);
        }