/// <summary> /// Creates a new ClosedDLRepOfGroupElement object whose value is the product of all /// the values in the input array. Fails if any of the objects in dlarray have /// different bases. /// </summary> /// <param name="dlarray">Array of objects to multiply</param> /// <param name="product">Outputs product of dlarray</param> /// <returns>true on success, false on failure.</returns> public static bool TryStrictMultiply(ClosedDLRepOfGroupElement [] dlarray, out ClosedDLRepOfGroupElement product) { // make sure there is at least one element in the array if ((dlarray == null) || (dlarray.Length < 1)) { product = null; return(false); } //copy bases GroupElement [] newBases = new GroupElement[dlarray[0].RepresentationLength]; for (int baseIndex = 0; baseIndex < dlarray[0].RepresentationLength; ++baseIndex) { newBases[baseIndex] = dlarray[0].BaseAtIndex(baseIndex); for (int dlIndex = 1; dlIndex < dlarray.Length; ++dlIndex) { if (dlarray[dlIndex].BaseAtIndex(baseIndex) != dlarray[0].BaseAtIndex(baseIndex)) { product = null; return(false); } } } // compute product GroupElement value = dlarray[0].Group.Identity; for (int dlIndex = 0; dlIndex < dlarray.Length; ++dlIndex) { value *= dlarray[dlIndex].Value; } product = new ClosedDLRepOfGroupElement(newBases, value, dlarray[0].Group); return(true); }
/// <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> /// Transforms ClosedDLRepOfGroupElement object into ClosedPedersenCommitment. /// </summary> /// <param name="dl"></param> public ClosedPedersenCommitment(ClosedDLRepOfGroupElement dl) { if ((dl == null) || (dl.RepresentationLength != 2)) { throw new ArgumentException("Cannot convert input into Pedersen Commitment"); } this.Bases = new GroupElement[2] { dl.BaseAtIndex(0), dl.BaseAtIndex(1) }; this.Group = dl.Group; this.Value = dl.Value; }
/// <summary> /// Computes closed DL representation of E[i] = D[i]/D[i-1] * closedAdivB[i]^{-1}. /// Bases are X^{-1} and verifier.H. /// </summary> /// <param name="verifier">Verifier range proof parameters.</param> /// <param name="X">Array of commitments to (a-b)^2</param> /// <param name="D">Array of commitments to d.</param> /// <param name="closedAdivB">A/B</param> /// <returns>Array of same length as X, first element is null.</returns> public static ClosedDLRepOfGroupElement[] ComputeClosedE(VerifierRangeProofParameters verifier, GroupElement[] X, GroupElement[] D, GroupElement[] closedAdivB) { ClosedDLRepOfGroupElement[] closedE = new ClosedDLRepOfGroupElement[X.Length]; closedE[0] = null; for (int i = 1; i < closedE.Length; ++i) { closedE[i] = new ClosedDLRepOfGroupElement( new GroupElement[2] { verifier.Group.Invert(X[i]), verifier.H }, verifier.Group.Divide(new GroupElement[] { D[i] }, new GroupElement[] { D[i - 1], closedAdivB[i] }), verifier.Group); } return(closedE); }
/// <summary> /// Computes closed DL representation equations for X using /// bases closedAdivB[i] and verifier.H. /// </summary> /// <param name="verifier">Used to get base verifier.H</param> /// <param name="X">Array of group elements</param> /// <param name="closedAdivB">Used for base at index 0.</param> /// <returns>Array of same length as X, first element is null.</returns> public static ClosedDLRepOfGroupElement[] ComputeClosedX(VerifierRangeProofParameters verifier, GroupElement[] X, GroupElement [] closedAdivB) { ClosedDLRepOfGroupElement[] closedX = new ClosedDLRepOfGroupElement[X.Length]; closedX[0] = null; for (int i = 1; i < X.Length; ++i) { closedX[i] = new ClosedDLRepOfGroupElement( new GroupElement[2] { closedAdivB[i], verifier.H }, X[i], verifier.Group); } return(closedX); }
/// <summary> /// Combines all input arrays into an array of Closed DL representation equations /// to be used to verify FullRangeProof. Sets bases for closedD and AdivB as /// new GroupElement[2]{crypto.G, crypto.H}. /// </summary> /// <param name="closedD">closedD[length-1] excluded.</param> /// <param name="AdivB">AdivB[0] excluded.</param> /// <param name="closedX">closedX[0] excluded.</param> /// <param name="closedE">closedE[0] excluded.</param> /// <param name="crypto">Contains parameters G and H</param> /// <returns></returns> public static ClosedDLRepOfGroupElement[] CombineAllClosedDLReps(GroupElement[] closedD, GroupElement[] AdivB, ClosedDLRepOfGroupElement[] closedX, ClosedDLRepOfGroupElement[] closedE, CryptoParameters crypto) { ClosedDLRepOfGroupElement[] closedDL = new ClosedDLRepOfGroupElement[closedD.Length - 1 + AdivB.Length - 1 + closedX.Length - 1 + closedE.Length - 1]; int closedDLIndex = 0; GroupElement[] bases = new GroupElement[2] { crypto.G, crypto.H }; Group group = crypto.Group; for (int i = 0; i < closedD.Length - 1; ++i) { closedDL[closedDLIndex] = new ClosedDLRepOfGroupElement(bases, closedD[i], group); ++closedDLIndex; } for (int i = 1; i < AdivB.Length; ++i) { closedDL[closedDLIndex] = new ClosedDLRepOfGroupElement(bases, AdivB[i], group); ++closedDLIndex; } for (int i = 1; i < closedX.Length; ++i) { closedDL[closedDLIndex] = closedX[i]; ++closedDLIndex; } for (int i = 1; i < closedE.Length; ++i) { closedDL[closedDLIndex] = closedE[i]; ++closedDLIndex; } return(closedDL); }
/// <summary> /// Verifies the RangeProof. Returns true if it is valid, false otherwise. /// </summary> /// <param name="verifier">Verifier parameters.</param> /// <returns></returns> public bool Verify(VerifierRangeProofParameters verifier) { try { // Verify parameters if (!verifier.Verify()) { return(false); } // verify bit decomposition proofs if (!VerifyBitDecompositionProofs(verifier, this.A, this.B, ProofBitDecompositionOfA, ProofBitDecompositionOfB)) { return(false); } // verify FullRangeProof GroupElement[] closedAdivB = ComputeClosedAdivB(verifier, this.A, this.B); this.D[0] = closedAdivB[0]; ClosedDLRepOfGroupElement[] closedX = ComputeClosedX(verifier, this.X, closedAdivB); ClosedDLRepOfGroupElement[] closedE = ComputeClosedE(verifier, this.X, this.D, closedAdivB); ClosedDLRepOfGroupElement[] allClosedDL = CombineAllClosedDLReps(this.D, closedAdivB, closedX, closedE, verifier); EqualityMap map = ComputeEqualityMap(verifier, A.Length); VerifierEqualityParameters veParameters = new VerifierEqualityParameters( allClosedDL, map, verifier); bool success = this.FullRangeProof.Verify(veParameters); if (!success) { return(false); } // verify additional proof based on proof type GroupElement LastD = this.D[this.D.Length - 1]; switch (verifier.RangeProofType) { case VerifierRangeProofParameters.ProofType.GREATER_THAN: ClosedDLRepOfGroupElement gtEquation = new ClosedDLRepOfGroupElement( new GroupElement[1] { verifier.H }, LastD * verifier.G.Exponentiate(verifier.FieldZq.One.Negate()), verifier.Group); VerifierEqualityParameters greaterThanVerifier = new VerifierEqualityParameters( gtEquation, verifier); return(StrictlyThanProof.Verify(greaterThanVerifier)); case VerifierRangeProofParameters.ProofType.LESS_THAN: ClosedDLRepOfGroupElement ltEquation = new ClosedDLRepOfGroupElement( new GroupElement[1] { verifier.H }, LastD * verifier.G, verifier.Group); VerifierEqualityParameters lessThanVerifier = new VerifierEqualityParameters( ltEquation, verifier); return(StrictlyThanProof.Verify(lessThanVerifier)); case VerifierRangeProofParameters.ProofType.GREATER_THAN_OR_EQUAL_TO: VerifierSetMembershipParameters greaterEqualVerifier = new VerifierSetMembershipParameters( LastD, new FieldZqElement[] { verifier.FieldZq.Zero, verifier.FieldZq.One }, verifier); return(this.OrEqualToProof.Verify(greaterEqualVerifier)); case VerifierRangeProofParameters.ProofType.LESS_THAN_OR_EQUAL_TO: VerifierSetMembershipParameters lessEqualProver = new VerifierSetMembershipParameters( LastD, new FieldZqElement[] { verifier.FieldZq.Zero, verifier.FieldZq.One.Negate() }, verifier); return(this.OrEqualToProof.Verify(lessEqualProver)); } } catch (Exception) { } return(false); }