/// <summary> /// Generates a list of Pedersen Commitments /// </summary> /// <param name="prover">Array of tokens</param> /// <param name="attributeIndices">target attribute for each token</param> /// <param name="commitmentsToAttribute">Pedersen commitment to target attribute in token. Generated via method /// Proof.PedersenCommmitmentsToAttributes</param> public UProveIntegrationProof(ProverPresentationProtocolParameters [] prover, int [] attributeIndices, PedersenCommitment [] commitmentsToAttribute) { if ((prover == null) || (prover.Length == 0)) { throw new ArgumentException("First argument should be an array of at least one element."); } if (!UProveIntegrationProof.AreTokensCompatible(prover)) { throw new ArgumentException("All tokens must use same group."); } if ((attributeIndices == null) || (attributeIndices.Length != prover.Length)) { throw new ArgumentNullException("Second argument must be an array of the same length as first argument."); } if ((commitmentsToAttribute == null) || (commitmentsToAttribute.Length != prover.Length)) { throw new ArgumentNullException("Third argument must be an array of the same length as first argument."); } // copy Pedersen Commitment values this.PedersenCommitmentValues = new GroupElement[prover.Length]; for (int i = 0; i < PedersenCommitmentValues.Length; ++i) { this.PedersenCommitmentValues[i] = commitmentsToAttribute[i].Value; } // Create Equality Proof between Pedersen Commitments and tokens. EqualityMap map = new EqualityMap(); IWitness [] witnesses = new IWitness[prover.Length * 2]; OpenUProveToken[] tokens = new OpenUProveToken[prover.Length]; for (int i = 0; i < tokens.Length; ++i) { // create uprove token and add target attribute to map witnesses[2 * i] = new OpenUProveToken(prover[i]); map.Add(new PrettyName("token", 2 * i), new DoubleIndex(i, attributeIndices[i])); // add pedersen commitment to witness list, and add to map witnesses[2 * i + 1] = commitmentsToAttribute[i]; map.Add(new PrettyName("token", 2 * i + 1), new DoubleIndex(i, 0)); } ProverEqualityParameters eqProver = new ProverEqualityParameters(witnesses, map, new CryptoParameters(prover[0].IP)); this.TokenCommitmentEqualityProof = new EqualityProof(eqProver); this.TokenCommitmentEqualityProof.IsGroupSerializable = false; }
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> /// 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; }
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); } }
/// <summary> /// Verifies a proof that two tokens share an attribute value, without revealing it. /// </summary> /// <param name="verifier1">Equality proof parameters for the first token.</param> /// <param name="verifier2">Equality proof parameters for the second token.</param> /// <param name="eQProof">The equality proof to verify.</param> /// <exception cref="InvalidUProveArtifactException">Thrown if the proof is invalid.</exception> public static void VerifyUProveEqualityProof(EQProofUProveVerifierData verifier1, EQProofUProveVerifierData verifier2, EqualityProof eQProof) { int commitmentIndex1 = ClosedPedersenCommitment.GetCommitmentIndex(verifier1.VPPP.Committed, verifier1.index); int commitmentIndex2 = ClosedPedersenCommitment.GetCommitmentIndex(verifier2.VPPP.Committed, verifier2.index); ClosedPedersenCommitment closedPed1 = new ClosedPedersenCommitment(verifier1.VPPP.IP, verifier1.PP, commitmentIndex1); ClosedPedersenCommitment closedPed2 = new ClosedPedersenCommitment(verifier2.VPPP.IP, verifier2.PP, commitmentIndex2); CryptoParameters crypto = new CryptoParameters(verifier1.VPPP.IP); // Can use prover2.IP VerifierEqualityParameters equalityVerifier = new VerifierEqualityParameters(closedPed1, 0, closedPed2, 0, crypto); if (!eQProof.Verify(equalityVerifier)) { throw new InvalidUProveArtifactException("invalid equality proof"); } }