/// <summary> /// Helper method for constructing proof. Computes a[index], c[index], r[index] values for when /// the committedValue is not equal to prover.MemberSet[index]. /// </summary> /// <param name="index">Index into prover.MemberSet</param> /// <param name="prover">Prover parameters</param> /// <param name="randomChallengeValue">Value to set c[index]</param> /// <param name="randomResponseValue">Value to set r[index]</param> private void generateFakeProof(int index, ProverSetMembershipParameters prover, FieldZqElement randomChallengeValue, FieldZqElement randomResponseValue) { if (index < this.c.Length) { this.c[index] = randomChallengeValue; } this.r[index] = randomResponseValue; // compute this.a[index] as a multi-exponentiation // a[index] = h^r[index] * g^{memberset[index] + c[index]} * X^{-c[index] GroupElement[] bases = new GroupElement[3] { prover.H, // h prover.G, // g prover.ClosedCommitment // X }; FieldZqElement[] exponents = new FieldZqElement[3] { randomResponseValue, // r[index] prover.MemberSet[index] * randomChallengeValue, // memberset[index] * c randomChallengeValue.Negate() // -c }; this.a[index] = prover.Group.MultiExponentiate(bases, exponents); }
/// <summary> /// Helper method for constructing proof. /// Generates a the c, r, a values for when the committed value is identical to /// the element in the memberSet located at index. /// </summary> /// <param name="index">Index into prover.MemberSet</param> /// <param name="prover">Prover parameters</param> /// <param name="randomWValue">random value to use to compute proof</param> /// <param name="challengeValue">Challenge to use to compute proof</param> private void generateRealProof(int index, ProverSetMembershipParameters prover, FieldZqElement randomWValue, FieldZqElement challengeValue) { if (index < this.c.Length) { this.c[index] = challengeValue; } this.r[index] = (challengeValue * prover.OpenCommitment.Opening) + randomWValue; }
private void ConstructorHelper(ProverSetMembershipParameters prover, SetMembershipProofGenerationRandomData smRandom = null) { try { // check that parameters can be used to construct valid proof. if (!prover.Verify()) { throw new ArgumentException("Invalid proof parameters. Cannot create proof"); } // set Group context this.Group = prover.Group; this.IsGroupSerializable = true; // allocate space for proof this.c = new FieldZqElement[prover.MemberSet.Length - 1]; this.a = new GroupElement[prover.MemberSet.Length]; this.r = new FieldZqElement[prover.MemberSet.Length]; // generate random values needed for proof if (smRandom == null) { // generate a pair of random values for each fake proofs, plus the random exponent for the real one smRandom = SetMembershipProofGenerationRandomData.Generate(prover.FieldZq, prover.MemberSet.Length - 1); } // Find index of prover.OpenCommitment.CommittedValue in prover.MemberSet int indexOfCommittedValue = prover.IndexOfCommittedValueInSet; // generate a fake proof for each prover.MemberSet element that is not // equal to CommitedValue. FieldZqElement sumOfSubChallenges = prover.FieldZq.Zero; int randomIndex = 0; for (int index = 0; index < prover.MemberSet.Length; ++index) { if (index != indexOfCommittedValue) { this.generateFakeProof(index, prover, smRandom.c[randomIndex], smRandom.r[randomIndex]); sumOfSubChallenges += smRandom.c[randomIndex]; randomIndex++; } } // generate challenge, and a real proof for committment.CommittedValue this.generateRealA(indexOfCommittedValue, prover, smRandom.w); FieldZqElement challenge = this.ComputeChallenge(prover); this.generateRealProof(indexOfCommittedValue, prover, smRandom.w, sumOfSubChallenges.Negate() + challenge); } catch (Exception e) { throw new Exception("Could not create SetMembershipProof.", e); } }
/// <summary> /// Generates a set membership proof from U-Prove parameters. /// </summary> /// <param name="pppp">The prover presentation protocol parameters.</param> /// <param name="pp">The presentation proof.</param> /// <param name="cpv">The commitment private values returned when generating the presentation proof.</param> /// <param name="committedIndex">Index of the committed attribute used to generate the set membership proof.</param> /// <param name="setValues">Set values to prove against.</param> /// <param name="smRandom">Optional pregenerated random values, or <c>null</c>.</param> /// <returns>A set membership proof.</returns> public static SetMembershipProof Generate(ProverPresentationProtocolParameters pppp, PresentationProof pp, CommitmentPrivateValues cpv, int committedIndex, byte[][] setValues, SetMembershipProofGenerationRandomData smRandom = null) { // get the index of the commitment to use, given the underlying attribute's index int commitmentIndex = ClosedPedersenCommitment.GetCommitmentIndex(pppp.Committed, committedIndex); // generate the membership proof ProverSetMembershipParameters setProver = new ProverSetMembershipParameters( new PedersenCommitment(pppp, pp, cpv, commitmentIndex), VerifierSetMembershipParameters.GenerateMemberSet(pppp.IP, committedIndex, setValues), new CryptoParameters(pppp.IP)); return(new SetMembershipProof(setProver, smRandom)); }
public void ConstructorHelper(ProverBitDecompositionParameters prover) { try { if (!prover.Verify()) { throw new ArgumentException("Could not create BitDecompositionProof because prover parameters are invalid."); } this.Group = prover.Group; this.IsGroupSerializable = true; // Generate proof that each Pedersen Commitment in prover.OpenBitDecomposition // is a valid commitment to either 0 or 1. this.bitCommitmentProof = new SetMembershipProof[prover.DecompositionLength]; FieldZqElement[] memberSet = BitDecompositionProof.SetOfZeroAndOne(prover); for (int proofIndex = 0; proofIndex < bitCommitmentProof.Length; ++proofIndex) { ProverSetMembershipParameters psmParameters = new ProverSetMembershipParameters( prover.OpenBitDecomposition(proofIndex), memberSet, prover); bitCommitmentProof[proofIndex] = new SetMembershipProof(psmParameters); bitCommitmentProof[proofIndex].IsGroupSerializable = false; } //now create proof that actualComposedBits and parameters.OpenCommitment are //commitments to the same value. PedersenCommitment actualComposedBits; if (ComposeCommitments(prover.OpenBitDecomposition(), prover.FieldZq, out actualComposedBits)) { ProverEqualityParameters peParameters = new ProverEqualityParameters( actualComposedBits, 0, prover.OpenCommitment, 0, prover); this.compositionProof = new EqualityProof(peParameters); this.compositionProof.IsGroupSerializable = false; } else { throw new Exception("Could not create BitDecompositionProof."); } } catch (Exception e) { throw e; } }
/// <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> /// Helper method for constructing proof. /// Computes a[index]. /// </summary> /// <param name="index">Index into prover.MemberSet</param> /// <param name="prover">Prover parameters</param> /// <param name="randomWValue">random value</param> private void generateRealA(int index, ProverSetMembershipParameters prover, FieldZqElement randomWValue) { this.a[index] = prover.OpenCommitment.H.Exponentiate(randomWValue); }
} // responses /// <summary> /// Constructs a SetMembershipProof. Throws exception if prover /// parameters do not allow creating valid proof. /// </summary> /// <param name="prover">Prover parameters</param> /// <param name="smRandom">The optional pre-generated random values to generate the proof, or <c>null</c>.</param> public SetMembershipProof(ProverSetMembershipParameters prover, SetMembershipProofGenerationRandomData smRandom = null) { ConstructorHelper(prover, smRandom); }
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); } }