/// <summary> /// Constructor. Creates an instance of ProverSetMembershipParameters that /// is ready to use to create a SetMembershipProof (assuming openCommitment /// and memberSet are not null). /// </summary> /// <param name="openCommitment">OpenCommitment</param> /// <param name="memberSet">MemberSet</param> /// <param name="parameters">Sets crypto parameters: Group, FieldZq, G, H, HashFunction. /// If null uses default parameters.</param> public ProverSetMembershipParameters( PedersenCommitment openCommitment, FieldZqElement [] memberSet, CryptoParameters parameters) : base(parameters) { this.setProverParameters(openCommitment, memberSet); }
/// <summary> /// Constructor. /// </summary> /// <param name="openCommitment">Pedersen commitment about which proof is made</param> /// <param name="openBitDecompisition">Bit decompisition of openCommitment.CommittedValue.</param> /// <param name="parameterSet">Parameters</param> /// <param name="fieldZq">FieldZq associated with parameterSet.</param> public ProverBitDecompositionParameters( PedersenCommitment openCommitment, PedersenCommitment [] openBitDecomposition, CryptoParameters parameters) : base(parameters) { this.setProverParameters(openBitDecomposition, openCommitment); }
/// <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); }
/// <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; }
/// <summary> /// Creates an array of PedersenCommitments to the specified attributes /// </summary> /// <param name="prover">Array of tokens</param> /// <param name="attributeIndices">Attribute to commit in token (1-based array)</param> /// <returns>Array of PedersenCommitments</returns> public static PedersenCommitment[] PedersenCommmitmentsToAttributes(ProverPresentationProtocolParameters[] prover = null, int[] attributeIndices = null) { if ((prover == null) || (prover.Length == null)) { throw new ArgumentException("First argument must be an array of at least one element."); } if (attributeIndices == null) { throw new ArgumentNullException("Second argument may not be null if first argument is not null."); } if (prover.Length != attributeIndices.Length) { throw new ArgumentException("Prover array and attribute index array must be of equal length."); } PedersenCommitment[] peds = new PedersenCommitment[prover.Length]; for (int i = 0; i < peds.Length; ++i) { peds[i] = new PedersenCommitment(prover[i].IP, attributeIndices[i], prover[i].Attributes[attributeIndices[i] - 1]); } return(peds); }
/// <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); }
/// <summary> /// Sets prover parameters for proving that /// the committed value in openCommitmentX is not equal to the /// committed value in openCommitmentY. /// </summary> /// <param name="openCommitmentX">Pedersen Commitment</param> /// <param name="openCommitmentY">Pedersen Commitment</param> public void setProverParameters(PedersenCommitment openCommitmentX, PedersenCommitment openCommitmentY) { PedersenCommitment[] witnesses = new PedersenCommitment[2]; witnesses[0] = openCommitmentX; witnesses[1] = openCommitmentY; this.setProverParameters(witnesses); this.CompareToKnownValue = false; }
/// <summary> /// Sets prover parameters for proving that /// the committed value in openCommitment is not equal to value. /// </summary> /// <param name="openCommitment">Pedersen Commitment</param> /// <param name="value">Value known to verifier</param> /// <param name="parameters">Crypto parameters</param> public void setProverParameters(PedersenCommitment openCommitment, FieldZqElement value) { PedersenCommitment[] witnesses = new PedersenCommitment[1]; witnesses[0] = openCommitment; this.setProverParameters(witnesses); this.Value = value; this.CompareToKnownValue = true; }
/// <summary> /// Constructor. Creates prover parameters for proving that /// the committed value in openCommitmentX is not equal to the /// committed value in openCommitmentY. /// </summary> /// <param name="openCommitmentX">Pedersen Commitment</param> /// <param name="openCommitmentY">Pedersen Commitment</param> /// <param name="parameters">Crypto parameters</param> public ProverInequalityProofParameters( PedersenCommitment openCommitmentX, PedersenCommitment openCommitmentY, CryptoParameters parameters) : base(parameters) { this.setProverParameters(openCommitmentX, openCommitmentY); }
/// <summary> /// Constructor. Creates prover parameters for proving that /// the committed value in openCommitment is not equal to value. /// </summary> /// <param name="openCommitment">Pedersen Commitment</param> /// <param name="value">Value known to verifier</param> /// <param name="parameters">Crypto parameters</param> public ProverInequalityProofParameters( PedersenCommitment openCommitment, FieldZqElement value, CryptoParameters parameters) : base(parameters) { this.setProverParameters(openCommitment, value); }
/// <summary> /// Creates an array of Pedersen Commitments from the ProverPresentationProtocolParameters /// and the CommitmentPrivateValues. This is a convenience method for generating the /// Pedersen commitments output by the PresentationProof.Generate() method. /// </summary> /// <param name="pppp">The Prover parameters.</param> /// <param name="pp">The presentation proof.</param> /// <param name="cpv">The commitment private values.</param> /// <returns></returns> public static PedersenCommitment [] ArrayOfPedersenCommitments(ProverPresentationProtocolParameters pppp, PresentationProof pp, CommitmentPrivateValues cpv) { PedersenCommitment[] pedersenCommitments = new PedersenCommitment[cpv.TildeO.Length]; for (int index = 0; index < pedersenCommitments.Length; ++index) { pedersenCommitments[index] = new PedersenCommitment(pppp, pp, cpv, index); } return(pedersenCommitments); }
/// <summary> /// Returns entire bit decomposition. /// </summary> /// <returns></returns> public PedersenCommitment[] OpenBitDecomposition() { PedersenCommitment[] output = new PedersenCommitment[this.DecompositionLength]; for (int i = 0; i < output.Length; ++i) { output[i] = this.OpenBitDecomposition(i); } return(output); }
/// <summary> /// Sets prover parameters. /// </summary> /// <param name="openCommittedBits">Bit decomposition.</param> /// <param name="openCommitment">Commited integer.</param> public void setProverParameters(PedersenCommitment[] openCommittedBits, PedersenCommitment openCommitment) { PedersenCommitment [] ped = new PedersenCommitment[openCommittedBits.Length + 1]; for (int dlIndex = 0; dlIndex < openCommittedBits.Length; ++dlIndex) { ped[dlIndex] = openCommittedBits[dlIndex]; } ped[ped.Length - 1] = openCommitment; this.setProverParameters(ped); }
/// <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); }
/// <summary> /// Constructor. Use this constructor when the verifier DOES NOT know the value /// of IntegerB. /// </summary> /// <param name="crypto">Crypto parameters.</param> /// <param name="openIntegerA">Pedersen Commitment to integerA.</param> /// <param name="rangeProofType">Type of range proof.</param> /// <param name="openIntegerB">Pedersen Commitment to integerB.</param> /// <param name="minRange">Minimum value for integerA and integerB.</param> /// <param name="maxRange">Maximum value for integerA and integerB.</param> public ProverRangeProofParameters( CryptoParameters crypto, PedersenCommitment openIntegerA, ProofType rangeProofType, PedersenCommitment openIntegerB, int minRange, int maxRange) : base(crypto) { this.setProverParameters(new PedersenCommitment[] { openIntegerA, openIntegerB }); this.IntegerBIsKnown = false; this.RangeProofType = rangeProofType; this.MinValue = minRange; this.MaxValue = maxRange; }
/// <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); }
/// <summary> /// Constructor. Creates an inequality proof that a token attribute is not equal to some value. /// </summary> /// <param name="prover">Token description.</param> /// <param name="attributeIndexForProver">1-based attribute index in token.</param> /// <param name="attributeValue">Attribute value to compare actual token attribute.</param> /// <returns>Inequality proof.</returns> public InequalityProof(ProverPresentationProtocolParameters prover, int attributeIndexForProver, byte[] attributeValue) { // generate Pedersen Commitments to attributes ProverPresentationProtocolParameters[] provers = new ProverPresentationProtocolParameters[] { prover }; int[] attributeIndices = new int[] { attributeIndexForProver }; PedersenCommitment[] attributeCommitments = PedersenCommitment.PedersenCommmitmentsToAttributes(provers, attributeIndices); // create inequality proof using Pedersen Commitmetns FieldZqElement committedAttribute = ProtocolHelper.ComputeXi(prover.IP, attributeIndexForProver - 1, attributeValue); ProverInequalityProofParameters ieqProver = new ProverInequalityProofParameters(attributeCommitments[0], committedAttribute, new CryptoParameters(prover.IP)); ConstructorHelper(ieqProver); // add UProve Integration proof this.UPIProof = new UProveIntegrationProof(provers, attributeIndices, attributeCommitments); this.UPIProof.IsGroupSerializable = false; }
/// <summary> /// Generates proofs that a token attribute value is not equal to any values in the target array. /// </summary> /// <param name="prover">Inequality proof parameters for the token.</param> /// <param name="target">Target values array.</param> /// <returns>An inequality proof.</returns> public static InequalityProof[] GenerateUProveInequalityProofs(EQProofUProveProverData prover, byte[][] target) { // Create PedersenCommitments int commitmentIndex = ClosedPedersenCommitment.GetCommitmentIndex(prover.PPPP.Committed, prover.index); PedersenCommitment ped = new PedersenCommitment(prover.PPPP, prover.PP, prover.CPV, commitmentIndex); // Create EqualityProof CryptoParameters crypto = new CryptoParameters(prover.PPPP.IP); InequalityProof[] proofs = new InequalityProof[target.Length]; for (int i = 0; i < target.Length; i++) { FieldZqElement targetValue = ProtocolHelper.ComputeXi(prover.PPPP.IP, prover.index - 1, target[i]); proofs[i] = new InequalityProof(new ProverInequalityProofParameters(ped, targetValue, crypto)); } return(proofs); }
/// <summary> /// Constructor. Creates a proof that a token attribute is in a given set. /// </summary> /// <param name="prover">Token description.</param> /// <param name="attributeIndexForProver">1-based attribute index in token.</param> /// <param name="setValues">Set of attributes to compare to token attribute.</param> /// <param name="smRandom">Random data for set membership proof.</param> /// <returns>Inequality proof.</returns> public SetMembershipProof(ProverPresentationProtocolParameters prover, int attributeIndexForProver, byte[][] setValues, SetMembershipProofGenerationRandomData smRandom = null) { // generate Pedersen Commitments to token attribute ProverPresentationProtocolParameters[] provers = new ProverPresentationProtocolParameters[] { prover }; int[] attributeIndices = new int[] { attributeIndexForProver }; PedersenCommitment[] attributeCommitments = PedersenCommitment.PedersenCommmitmentsToAttributes(provers, attributeIndices); // create set membership proof using Pedersen Commitment FieldZqElement[] memberSet = VerifierSetMembershipParameters.GenerateMemberSet(prover.IP, attributeIndexForProver, setValues); ProverSetMembershipParameters setProver = new ProverSetMembershipParameters(attributeCommitments[0], memberSet, new CryptoParameters(prover.IP)); ConstructorHelper(setProver, smRandom); // add UProve Integration proof this.UPIProof = new UProveIntegrationProof(provers, attributeIndices, attributeCommitments); this.UPIProof.IsGroupSerializable = false; }
/// <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> /// Constructor. Use this constructor when the verifier knows the value /// of IntegerB. /// </summary> /// <param name="crypto">Crypto parameters.</param> /// <param name="openIntegerA">Pedersen Commitment to integerA.</param> /// <param name="rangeProofType">Type of range proof.</param> /// <param name="integerB">integerB.</param> /// <param name="minRange">Minimum value for integerA and integerB.</param> /// <param name="maxRange">Maximum value for integerA and integerB.</param> public ProverRangeProofParameters( CryptoParameters crypto, PedersenCommitment openIntegerA, ProofType rangeProofType, int integerB, int minRange, int maxRange) : base(crypto) { PedersenCommitment openIntegerB = new PedersenCommitment(this.G, this.H, this.FieldZq.GetElement((uint)integerB), this.FieldZq.Zero, this.Group); this.setProverParameters(new PedersenCommitment[] { openIntegerA, openIntegerB }); this.IntegerBIsKnown = true; this.IntegerB = integerB; this.RangeProofType = rangeProofType; this.MinValue = minRange; this.MaxValue = maxRange; }
/// <summary> /// Generates a proof that two attribute values are different, without revealing them. /// </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 inequality proof.</returns> public static InequalityProof GenerateUProveInequalityProof(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 ProverInequalityProofParameters inequalityProver = new ProverInequalityProofParameters(ped1, ped2, crypto); // compares committed values in ped1 and ped2 return(new InequalityProof(inequalityProver)); }
/// <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); }
/// <summary> /// Generates proof for when prover.CompareToKnownValue=false. /// Computes X/Y and generates proof for showing the committed value /// in X/Y is not equal to 0. /// </summary> /// <param name="prover">Prover parameters for comparing CommitmentX to CommitmentY</param> private void CreateProofForUnknownValue(ProverInequalityProofParameters prover) { // Compute Pedersen Commitment X/Y PedersenCommitment newOpenX = new PedersenCommitment( new GroupElement[2] { prover.G, prover.H }, new FieldZqElement[2] { prover.CommitmentX.CommittedValue - prover.CommitmentY.CommittedValue, prover.CommitmentX.Opening - prover.CommitmentY.Opening }, prover.Group); // new prover parameters ProverInequalityProofParameters newProver = new ProverInequalityProofParameters(newOpenX, prover.FieldZq.Zero, prover); // generate proof this.CreateProofForKnownValue(newProver); }
/// <summary> /// Constructor. Creates an inequality proof that an attribute in one token is not equal to an attribute in another token. /// </summary> /// <param name="prover1">Token.</param> /// <param name="attributeIndexForProver1">Target attribute in first token, uses 1-based index.</param> /// <param name="prover2">Token</param> /// <param name="attributeIndexForProver2">Target attribute in second token, uses 1-based index</param> /// <returns>Proof of inequality.</returns> public InequalityProof( ProverPresentationProtocolParameters prover1, int attributeIndexForProver1, ProverPresentationProtocolParameters prover2, int attributeIndexForProver2) { // generate Pedersen Commitments to attributes ProverPresentationProtocolParameters[] provers = new ProverPresentationProtocolParameters[] { prover1, prover2 }; int [] attributeIndices = new int[] { attributeIndexForProver1, attributeIndexForProver2 }; PedersenCommitment[] attributeCommitments = PedersenCommitment.PedersenCommmitmentsToAttributes(provers, attributeIndices); // create inequality proof using Pedersen Commitmetns ProverInequalityProofParameters ieqProver = new ProverInequalityProofParameters(attributeCommitments[0], attributeCommitments[1], new CryptoParameters(prover1.IP)); ConstructorHelper(ieqProver); // add UProve Integration proof this.UPIProof = new UProveIntegrationProof(provers, attributeIndices, attributeCommitments); this.UPIProof.IsGroupSerializable = false; }
public static GroupElement[] GetCommitmentValues(CryptoParameters crypto, FieldZqElement[] committedValues, FieldZqElement[] openings) { if ((crypto == null) || (committedValues == null) || (openings == null) || (committedValues.Length != openings.Length)) { throw new ArgumentException("GetCommitmentValues expects non-null input, with arrays committedValues and openings of the same length."); } GroupElement[] values = new GroupElement[committedValues.Length]; for (int i = 0; i < committedValues.Length; ++i) { PedersenCommitment ped = new PedersenCommitment( crypto.G, crypto.H, committedValues[i], openings[i], crypto.Group); values[i] = ped.Value; } return(values); }
/// <summary> /// Returns ProverRangeProofParameters that the committed date to the /// the verifier target date. Range proof will require bit decomposition of approximately 9 + log_2 (maxYear - minYear) bits. /// </summary> /// <param name="crypto">Crypto parameters</param> /// <param name="commitmentToDayOfYear">Commitment value in [0,365]</param> /// <param name="commitmentToYear">Commitment to a year in [minYear, maxYear].</param> /// <param name="rangeProofType">Range proof type.</param> /// <param name="verifierTargetDate">Commitment to a date in [minYear, maxYear +1).</param> /// <param name="minYear">Limits range of proof. </param> /// <param name="maxYear">Limits range of proof.</param> /// <returns></returns> public static ProverRangeProofParameters GetDateTimeProverParameters(CryptoParameters crypto, PedersenCommitment commitmentToYear, PedersenCommitment commitmentToDayOfYear, VerifierRangeProofParameters.ProofType rangeProofType, DateTime verifierTargetDate, int minYear, int maxYear) { //Check crypto parameters and pedersen commitment generators G and H if (!commitmentToYear.AreBasesEqual(commitmentToDayOfYear)) { throw new ArgumentException("PedersenCommitments commitmentToYear and commitmentToDayOfYear have different bases."); } if ((crypto.G != commitmentToYear.BaseAtIndex(0)) || (crypto.H != commitmentToYear.BaseAtIndex(1))) { throw new ArgumentException("PedersenCommitments commitmentToYear and commitmentToDayOfYear should use bases crypto.G and crypto.H."); } FieldZqElement minYearElement = crypto.FieldZq.GetElement((uint)minYear); FieldZqElement daysInOneYear = crypto.FieldZq.GetElement(366); FieldZqElement committedYear = commitmentToYear.ExponentAtIndex(0); FieldZqElement committedDay = commitmentToDayOfYear.ExponentAtIndex(0); FieldZqElement openingYear = commitmentToYear.ExponentAtIndex(1); FieldZqElement openingDay = commitmentToDayOfYear.ExponentAtIndex(1); PedersenCommitment commitmentToYearAndDay = new PedersenCommitment( crypto.G, crypto.H, (committedYear + minYearElement.Negate()) * daysInOneYear + committedDay, openingYear * daysInOneYear + openingDay, crypto.Group); int maxValue = (maxYear - minYear) * 366 + 365; int verifierYearAndDay = EncodeYearAndDay(verifierTargetDate, minYear); return(new ProverRangeProofParameters( crypto, commitmentToYearAndDay, rangeProofType, verifierYearAndDay, 0, maxValue)); }
/// <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); }
/// <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); }
/// <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); }