Ejemplo n.º 1
0
        /// <summary>
        /// Combines the input arrays into a master array of DL representation equations to use
        /// for FullRangeProof.  Arrays should all be not null and of equal length.
        /// </summary>
        /// <param name="openD">openD[length-1] is excluded.</param>
        /// <param name="AdivB">AdivB[0] is excluded.</param>
        /// <param name="openX">openX[0] is excluded.</param>
        /// <param name="openE">openE[0] is excluded. </param>
        /// <returns>Concatentation of all arrays, minus excluded values.</returns>
        public static DLRepOfGroupElement[] CombineAllOpenDLReps(DLRepOfGroupElement [] openD, DLRepOfGroupElement[] AdivB, DLRepOfGroupElement[] openX, DLRepOfGroupElement[] openE)
        {
            DLRepOfGroupElement[] openDL = new DLRepOfGroupElement[openD.Length - 1 + AdivB.Length - 1 + openX.Length - 1 + openE.Length - 1];
            int openDLIndex = 0;

            for (int i = 0; i < openD.Length - 1; ++i)
            {
                openDL[openDLIndex] = openD[i];
                ++openDLIndex;
            }

            for (int i = 1; i < AdivB.Length; ++i)
            {
                openDL[openDLIndex] = AdivB[i];
                ++openDLIndex;
            }

            for (int i = 1; i < openX.Length; ++i)
            {
                openDL[openDLIndex] = openX[i];
                ++openDLIndex;
            }

            for (int i = 1; i < openE.Length; ++i)
            {
                openDL[openDLIndex] = openE[i];
                ++openDLIndex;
            }
            return(openDL);
        }
Ejemplo n.º 2
0
 /// <summary>
 /// Takes as input a series of commitments to 0 and 1, and composes them into a single Pedersen commitment:
 /// output.CommittedValue = product (2^i * committedBits[i].CommittedValue)
 /// </summary>
 /// <param name="committedBits">Array of commitments to Zero and One. Each commitment must use the same bases G and H.</param>
 /// <param name="fieldZq">Field corresponding to all PedersenCommitments</param>
 /// <param name="composition">Output paramter.</param>
 /// <returns>True on success, false on failure.</returns>
 private static bool ComposeCommitments(PedersenCommitment[] committedBits, FieldZq fieldZq, out PedersenCommitment composition)
 {
     try
     {
         FieldZqElement        two               = fieldZq.GetElement(2);
         FieldZqElement        powerOfTwo        = fieldZq.One;
         DLRepOfGroupElement[] bitsExpPowerOfTwo = new DLRepOfGroupElement[committedBits.Length];
         for (int i = 0; i < committedBits.Length; ++i)
         {
             bitsExpPowerOfTwo[i] = committedBits[i].Exponentiate(powerOfTwo);
             powerOfTwo           = powerOfTwo * two;
         }
         DLRepOfGroupElement actualComposition;
         bool success = DLRepOfGroupElement.TryStrictMultiply(bitsExpPowerOfTwo, out actualComposition);
         if (success)
         {
             composition = new PedersenCommitment(actualComposition);
             return(true);
         }
     }
     catch (Exception)
     {
         // do nothing
     }
     composition = null;
     return(false);
 }
        public PedersenCommitment(DLRepOfGroupElement dl)
        {
            if ((dl == null) || (dl.RepresentationLength != 2))
            {
                throw new ArgumentException("Cannot convert input into Pedersen Commitment");
            }

            GroupElement [] bases = new GroupElement[2] {
                dl.BaseAtIndex(0), dl.BaseAtIndex(1)
            };
            FieldZqElement[] exponents = new FieldZqElement[] { dl.ExponentAtIndex(0), dl.ExponentAtIndex(1) };
            this.Group = dl.Group;
            this.ComputeValue(bases, exponents);
        }
Ejemplo n.º 4
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);
 }
Ejemplo n.º 5
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);
 }
Ejemplo n.º 6
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;
        }
Ejemplo n.º 7
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);
        }
Ejemplo n.º 8
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);
 }
        /// <summary>
        /// Multiplies all objects in dlarray.  Adds all the exponents and multiplies the values.
        /// Fails if objects in dlarray don't have the same bases in the same order.
        /// </summary>
        /// <param name="dlarray"></param>
        /// <param name="product"></param>
        /// <returns></returns>
        public static bool TryStrictMultiply(DLRepOfGroupElement [] dlarray, out DLRepOfGroupElement product)
        {
            product = null;

            // make sure there is at least one element in the array
            if ((dlarray == null) || (dlarray.Length < 1))
            {
                return(false);
            }

            // compare bases
            for (int i = 1; i < dlarray.Length; ++i)
            {
                if (!dlarray[0].AreBasesEqual(dlarray[i]))
                {
                    return(false);
                }
            }


            GroupElement []   newBases     = new GroupElement[dlarray[0].RepresentationLength];
            FieldZqElement [] newExponents = new FieldZqElement[dlarray[0].RepresentationLength];

            for (int baseIndex = 0; baseIndex < dlarray[0].RepresentationLength; ++baseIndex)
            {
                newBases[baseIndex]     = dlarray[0].BaseAtIndex(baseIndex);
                newExponents[baseIndex] = dlarray[0].ExponentAtIndex(baseIndex);
                for (int dlIndex = 1; dlIndex < dlarray.Length; ++dlIndex)
                {
                    newExponents[baseIndex] += dlarray[dlIndex].ExponentAtIndex(baseIndex);
                }
            }

            product = new DLRepOfGroupElement(newBases, newExponents, dlarray[0].Group);
            return(true);
        }
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);
            }
        }