// 5.4 pg 29 /** * return true if the value r and s represent a DSA signature for * the passed in message (for standard DSA the message should be * a SHA-1 hash of the real message to be verified). */ public virtual bool VerifySignature(byte[] message, BigInteger r, BigInteger s) { BigInteger n = key.Parameters.N; // r and s should both in the range [1,n-1] if (r.SignValue < 1 || s.SignValue < 1 || r.CompareTo(n) >= 0 || s.CompareTo(n) >= 0) { return(false); } BigInteger e = CalculateE(n, message); BigInteger c = s.ModInverse(n); BigInteger u1 = e.Multiply(c).Mod(n); BigInteger u2 = r.Multiply(c).Mod(n); ECPoint G = key.Parameters.G; ECPoint Q = ((ECPublicKeyParameters)key).Q; ECPoint point = ECAlgorithms.SumOfTwoMultiplies(G, u1, Q, u2); if (point.IsInfinity) { return(false); } /* * If possible, avoid normalizing the point (to save a modular inversion in the curve field). * * There are ~cofactor elements of the curve field that reduce (modulo the group order) to 'r'. * If the cofactor is known and small, we generate those possible field values and project each * of them to the same "denominator" (depending on the particular projective coordinates in use) * as the calculated point.X. If any of the projected values matches point.X, then we have: * (point.X / Denominator mod p) mod n == r * as required, and verification succeeds. * * Based on an original idea by Gregory Maxwell (https://github.com/gmaxwell), as implemented in * the libsecp256k1 project (https://github.com/bitcoin/secp256k1). */ ECCurve curve = point.Curve; if (curve != null) { BigInteger cofactor = curve.Cofactor; if (cofactor != null && cofactor.CompareTo(Eight) <= 0) { ECFieldElement D = GetDenominator(curve.CoordinateSystem, point); if (D != null && !D.IsZero) { ECFieldElement X = point.XCoord; while (curve.IsValidFieldElement(r)) { ECFieldElement R = curve.FromBigInteger(r).Multiply(D); if (R.Equals(X)) { return(true); } r = r.Add(n); } return(false); } } } BigInteger v = point.Normalize().AffineXCoord.ToBigInteger().Mod(n); return(v.Equals(r)); }