Esempio n. 1
0
        /// <summary>
        /// Creates a range proof that compares a UProve attribute to a target date.
        /// Target attribute MUST NOT be hashed.
        /// Value MUST be generated via RangeProofParameterFactory.EncodeYearAndDayAsUProveAttribute.
        /// </summary>
        /// <param name="prover">Token information.</param>
        /// <param name="attributeIndexForProver">1-based index of target attribute.</param>
        /// <param name="proofType">Range proof type</param>
        /// <param name="targetDate">Compare token attribute to this date.  (Time component is ignored).</param>
        /// <param name="minYear">Minimum year for attribute and target date.</param>
        /// <param name="maxYear">Maximum year for attribute and target date.</param>
        public RangeProof(
            ProverPresentationProtocolParameters prover1,
            int attributeIndexForProver1,
            VerifierRangeProofParameters.ProofType proofType,
            ProverPresentationProtocolParameters prover2,
            int attributeIndexForProver2,
            int minValue,
            int maxValue)
        {
            // make sure target attribute is not hashed
            if ((prover1.IP.E[attributeIndexForProver1 - 1] == 0x01) || ((prover2.IP.E[attributeIndexForProver2 - 1]) == 0x01))
            {
                throw new ArgumentException("UProve attributes used in Range Proof must not be hashed.");
            }

            // generate Pedersen Commitments to token attributes
            ProverPresentationProtocolParameters[] provers = new ProverPresentationProtocolParameters[] { prover1, prover2 };
            int[] attributeIndices = new int[] { attributeIndexForProver1, attributeIndexForProver2 };
            PedersenCommitment[] attributeCommitments = PedersenCommitment.PedersenCommmitmentsToAttributes(provers, attributeIndices);

            // create range proof
            ProverRangeProofParameters rangeProver = new ProverRangeProofParameters(
                new CryptoParameters(prover1.IP),
                attributeCommitments[0],
                proofType,
                attributeCommitments[1],
                minValue,
                maxValue);

            ConstructorHelper(rangeProver);

            // Add UProve Integration proof
            this.UPIProof = new UProveIntegrationProof(provers, attributeIndices, attributeCommitments);
            this.UPIProof.IsGroupSerializable = false;
        }
Esempio n. 2
0
 /// <summary>
 /// Returns array of DLRepOfGroupElement objects, where output[i] = openA[i] / openB[i].
 /// Input arrays should be not null and of equal lengths.
 /// </summary>
 /// <param name="prover">Used to get bases G and H.</param>
 /// <param name="openA">Each openA[i] should have RepresentationLength=2, with bases equal to prover.G and prover.H</param>
 /// <param name="openB">Each openB[i] should have RepresentationLength=2, with bases equal to prover.G and prover.H</param>
 /// <returns></returns>
 public static DLRepOfGroupElement[] ComputeOpenAdivB(ProverRangeProofParameters prover, DLRepOfGroupElement [] openA, DLRepOfGroupElement [] openB)
 {
     DLRepOfGroupElement[] AdivB = new DLRepOfGroupElement[openA.Length];
     for (int i = 0; i < AdivB.Length; ++i)
     {
         AdivB[i] = new PedersenCommitment(
             prover.G,
             prover.H,
             openA[i].ExponentAtIndex(0) - openB[i].ExponentAtIndex(0),
             openA[i].ExponentAtIndex(1) - openB[i].ExponentAtIndex(1),
             prover.Group);
     }
     return(AdivB);
 }
Esempio n. 3
0
 /// <summary>
 /// Computes commitment to (a-b)^2.
 /// Let openAdivB[i] be a commitment to (a[i]-b[i]). This method chooses
 /// random u[i] and returns:
 /// output[i] = (openAdivB[i].Value)^(a[i]-b[i]) * prover.H^u[i]
 /// </summary>
 /// <param name="prover">Range proof parameters</param>
 /// <param name="openAdivB">Commitment to A/B</param>
 /// <returns>Array of same length as openAdivB, first element is null.</returns>
 public static DLRepOfGroupElement[] ComputeOpenX(ProverRangeProofParameters prover, DLRepOfGroupElement[] openAdivB)
 {
     FieldZqElement[]      u     = prover.FieldZq.GetRandomElements(openAdivB.Length, true);
     DLRepOfGroupElement[] openX = new DLRepOfGroupElement[openAdivB.Length];
     openX[0] = null;
     for (int i = 1; i < openX.Length; ++i)
     {
         openX[i] = new PedersenCommitment(
             openAdivB[i].Value,
             prover.H,
             openAdivB[i].ExponentAtIndex(0),
             u[i],
             prover.Group);
     }
     return(openX);
 }
Esempio n. 4
0
        /// <summary>
        /// Computes an array of commitments to d=Compute_d(prover,AdivB).
        /// </summary>
        /// <param name="prover">Used for bases G, H.</param>
        /// <param name="AdivB">Used to compute committed values d.</param>
        /// <returns>Array of same length as AdivB.</returns>
        public static DLRepOfGroupElement[] ComputeOpenD(ProverRangeProofParameters prover, DLRepOfGroupElement [] AdivB)
        {
            FieldZqElement[]      d = Compute_d(prover, AdivB);
            DLRepOfGroupElement[] D = new DLRepOfGroupElement[d.Length];
            FieldZqElement[]      t = prover.FieldZq.GetRandomElements(d.Length, true);
            D[0] = AdivB[0];
            for (int i = 1; i < D.Length; ++i)
            {
                D[i] = new PedersenCommitment(
                    prover.G,
                    prover.H,
                    d[i],
                    t[i],
                    prover.Group);
            }

            return(D);
        }
Esempio n. 5
0
 /// <summary>
 /// Let a[i] be the committed bits in openAdivB,
 ///
 /// Computes the arrray d as follows:
 /// d[0] = a[0]
 /// d[i] = d[i-1] - d[i-1]*a[i]^2 + a[i]
 /// </summary>
 /// <param name="prover">Prover parameters</param>
 /// <returns>The array d</returns>
 private static FieldZqElement[] Compute_d(ProverRangeProofParameters prover, DLRepOfGroupElement [] openAdivB)
 {
     FieldZqElement[] d = new FieldZqElement[openAdivB.Length];
     for (int i = 0; i < d.Length; ++i)
     {
         FieldZqElement difference = openAdivB[i].ExponentAtIndex(0);
         if (i == 0)
         {
             d[0] = difference;
         }
         else
         {
             d[i] = d[i - 1]
                    + (d[i - 1].Negate() * difference * difference)
                    + difference;
         }
     }
     return(d);
 }
Esempio n. 6
0
 /// <summary>
 /// Creates a DL representation equation E[i].
 /// Let d[i] be the committed value in D[i].
 /// Let E[i].Value = D[i]/D[i-1] * AdivB[i]^{-1}.
 /// Computes nu[i] so that the following relation holds
 /// E[i].Value= (X[i]^{-1})^{d[i-1]} * prover.H^{nu[i]}.
 /// </summary>
 /// <param name="prover"></param>
 /// <param name="D">Commitments to d</param>
 /// <param name="X">Commitment to (a-b)^2</param>
 /// <param name="AdivB">A/B</param>
 /// <returns>Array of same length as D, first element is null.</returns>
 public static DLRepOfGroupElement[] ComputeOpenE(ProverRangeProofParameters prover, DLRepOfGroupElement[] D, DLRepOfGroupElement [] X, DLRepOfGroupElement [] AdivB)
 {
     DLRepOfGroupElement[] E = new DLRepOfGroupElement[D.Length];
     E[0] = null;
     for (int i = 1; i < E.Length; ++i)
     {
         FieldZqElement nu =
             D[i].ExponentAtIndex(1)                       // t[i]
             - D[i - 1].ExponentAtIndex(1)                 // - t[i-1]
             - AdivB[i].ExponentAtIndex(1)                 // - r[i]
             + (D[i - 1].ExponentAtIndex(0)                // + (d[i-1] * r[i] * adivb[i])
                * AdivB[i].ExponentAtIndex(1)
                * AdivB[i].ExponentAtIndex(0))
             + (D[i - 1].ExponentAtIndex(0)                // (d[i-1] * u[i])
                * X[i].ExponentAtIndex(1));
         E[i] = new PedersenCommitment(
             prover.Group.Invert(X[i].Value),
             prover.H,
             D[i - 1].ExponentAtIndex(0),
             nu,
             prover.Group);
     }
     return(E);
 }
Esempio n. 7
0
        /// <summary>
        /// Creates a bit decomposition of prover.OpenIntegerA and prover.OpenIntegerB,
        /// and proofs that they are valid.  Sets member fields
        /// A, B, ProofBitDecompositionOfA and ProofBitDecompositionOfB.
        /// </summary>
        /// <param name="prover">Prover range proof parameters</param>
        /// <param name="bitProverA">outputs parameters for bit decomposition proof for A</param>
        /// <param name="bitProverB">outputs parameters for bit decomposition proof for B</param>
        /// <returns>Array AdivB with the bit decomposition of A divided by the bit decomposition of B.</returns>
        private DLRepOfGroupElement [] CreateBitDecompositionProofs(ProverRangeProofParameters prover)
        {
            int decompositionLength = RangeProof.ComputeDecompositionLength(prover);

            // create proof for A
            ProverBitDecompositionParameters bitProverA = new ProverBitDecompositionParameters(prover.RangeNormalizedOpenIntegerA, decompositionLength, prover);

            this.ProofBitDecompositionOfA = new BitDecompositionProof(bitProverA);
            this.A = bitProverA.ClosedBitDecomposition();

            // create proof for B if it is unknown.
            ProverBitDecompositionParameters bitProverB = new ProverBitDecompositionParameters(prover.RangeNormalizedOpenIntegerB, decompositionLength, prover);

            if (prover.IntegerBIsKnown)
            {
                this.ProofBitDecompositionOfB = null;
                this.B = null;
                DLRepOfGroupElement[] defaultB = DefaultOpenDecompositionOfIntegerB(prover);
                return(ComputeOpenAdivB(prover, bitProverA.OpenBitDecomposition(), defaultB));
            }
            this.ProofBitDecompositionOfB = new BitDecompositionProof(bitProverB);
            this.B = bitProverB.ClosedBitDecomposition();
            return(ComputeOpenAdivB(prover, bitProverA.OpenBitDecomposition(), bitProverB.OpenBitDecomposition()));
        }
Esempio n. 8
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);
            }
        }
Esempio n. 9
0
 /// <summary>
 /// Creates a RangeProof given the parameters.  Throws an ArgumentException on error.
 /// </summary>
 /// <param name="prover"></param>
 public RangeProof(ProverRangeProofParameters prover)
 {
     ConstructorHelper(prover);
 }