/// <summary> /// Returns all Closed Pedersen Commitments associated with a presentation proof. /// This is a UProve integration function that is called by the verifier. /// </summary> /// <param name="ip">Issuer Parameters</param> /// <param name="proof">Instance of the proof presentation protocol</param> /// <returns></returns> public static ClosedPedersenCommitment[] ArrayOfClosedPedersenCommitments(IssuerParameters ip, PresentationProof proof) { ClosedPedersenCommitment[] closedPed = new ClosedPedersenCommitment[proof.Commitments.Length]; for (int i = 0; i < closedPed.Length; ++i) { closedPed[i] = new ClosedPedersenCommitment(ip, proof, i); } return(closedPed); }
/// <summary> /// Verifies this proof for when verifier.CompareToKnownValue=true. /// </summary> /// <param name="verifier">Verifier parameters</param> /// <returns></returns> private bool VerifyProofForKnownValue(VerifierInequalityProofParameters verifier) { // B must not be 1. if (this.B == verifier.Group.Identity) { return(false); } // Reconstruct DL equations from proof and verifier parameters ClosedPedersenCommitment closedX = new ClosedPedersenCommitment( new GroupElement[2] { verifier.G, verifier.H }, verifier.ClosedCommitmentX, verifier.Group); ClosedPedersenCommitment closedA = new ClosedPedersenCommitment( new GroupElement[2] { verifier.G, verifier.H }, this.A, verifier.Group); ClosedDLRepOfGroupElement closedB = new ClosedDLRepOfGroupElement( new GroupElement[1] { verifier.G }, this.B, verifier.Group); ClosedPedersenCommitment closedC = new ClosedPedersenCommitment( new GroupElement[2] { closedX.Value *verifier.G.Exponentiate(verifier.Value.Negate()), verifier.H }, this.B, verifier.Group); ClosedDLRepOfGroupElement[] equations = new ClosedDLRepOfGroupElement[] { closedX, closedA, closedB, closedC }; // verify the proof EqualityMap map = this.GetEqualityMap(); VerifierEqualityParameters eqVerifier = new VerifierEqualityParameters(equations, map, verifier); if (!this.Proof.Verify(eqVerifier)) { return(false); } return(true); }
/// <summary> /// Verifies a set membership proof from U-Prove parameters. /// </summary> /// <param name="vppp">The verifier presentation protocol parameters.</param> /// <param name="pProof">A presentation proof.</param> /// <param name="smProof">A set 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 verify against.</param> /// <returns>True if the proof is valid, false otherwise.</returns> public static bool Verify(VerifierPresentationProtocolParameters vppp, PresentationProof pProof, SetMembershipProof smProof, int committedIndex, byte[][] setValues) { // get the index of the commitment to use, given the underlying attribute's index int commitmentIndex = ClosedPedersenCommitment.GetCommitmentIndex(vppp.Committed, committedIndex); // verify the membership proof ClosedDLRepOfGroupElement closedCommittedClearance = new ClosedPedersenCommitment(vppp.IP, pProof, commitmentIndex); VerifierSetMembershipParameters setVerifier = new VerifierSetMembershipParameters( closedCommittedClearance.Value, VerifierSetMembershipParameters.GenerateMemberSet(vppp.IP, committedIndex, setValues), new CryptoParameters(vppp.IP)); return(smProof.Verify(setVerifier)); }
/// <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)); }
/// <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"); } }
/// <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> /// 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> /// Verifies proofs that a token attribute value is not equal to a any of the target values. /// </summary> /// <param name="verifier">Equality proof parameters for the token.</param> /// <param name="target">Target values.</param> /// <param name="eQProof">The inequality proofs to verify.</param> /// <exception cref="InvalidUProveArtifactException">Thrown if a proof is invalid.</exception> public static void VerifyUProveEqualityProofs(EQProofUProveVerifierData verifier, byte[][] target, InequalityProof[] iNeqProof) { if (target == null || iNeqProof == null || target.Length != iNeqProof.Length) { throw new ArgumentException("target and iNeqProof must have the same length"); } int commitmentIndex = ClosedPedersenCommitment.GetCommitmentIndex(verifier.VPPP.Committed, verifier.index); ClosedPedersenCommitment closedPed = new ClosedPedersenCommitment(verifier.VPPP.IP, verifier.PP, commitmentIndex); CryptoParameters crypto = new CryptoParameters(verifier.VPPP.IP); for (int i = 0; i < target.Length; i++) { FieldZqElement targetValue = ProtocolHelper.ComputeXi(verifier.VPPP.IP, verifier.index - 1, target[i]); if (!iNeqProof[i].Verify(new VerifierInequalityProofParameters(closedPed.Value, targetValue, crypto))) { throw new InvalidUProveArtifactException("invalid equality proof"); } } }
/// <summary> /// Verifies this proof that the committed values are valid Pedersen Commitments to token attributes. /// </summary> /// <param name="verifier">Array of verifier token parameters.</param> /// <param name="attributeIndices">Target attribute in each token.</param> /// <param name="committedValues">Array of Pedersen Commitment values.</param> /// <returns></returns> public bool Verify(VerifierPresentationProtocolParameters [] verifier, int [] attributeIndices) { if ((verifier == null) || (verifier.Length == 0)) { throw new ArgumentException("First argument should be an array of at least one element."); } if (!UProveIntegrationProof.AreTokensCompatible(verifier)) { throw new ArgumentException("All tokens must use same group."); } if ((attributeIndices == null) || (attributeIndices.Length != verifier.Length)) { throw new ArgumentNullException("Second argument must be an array of the same length as first argument."); } if ((this.PedersenCommitmentValues == null) || (this.PedersenCommitmentValues.Length != verifier.Length)) { throw new ArgumentNullException("Third argument must be an array of the same length as first argument."); } EqualityMap map = new EqualityMap(); IStatement[] statements = new IStatement[verifier.Length * 2]; ClosedUProveToken[] tokens = new ClosedUProveToken[verifier.Length]; for (int i = 0; i < tokens.Length; ++i) { // create uprove token and add target attribute to map statements[2 * i] = new ClosedUProveToken(verifier[i]); map.Add(new PrettyName("token", 2 * i), new DoubleIndex(i, attributeIndices[i])); // add pedersen commitment to witness list, and add to map statements[2 * i + 1] = new ClosedPedersenCommitment(verifier[i].IP, this.PedersenCommitmentValues[i]); map.Add(new PrettyName("token", 2 * i + 1), new DoubleIndex(i, 0)); } VerifierEqualityParameters eqVerifier = new VerifierEqualityParameters(statements, map, new CryptoParameters(verifier[0].IP)); return(this.TokenCommitmentEqualityProof.Verify(eqVerifier)); }