public bool VerifyHash(byte[] hash, byte[] sig) { if (sig.Length != (_params.Domain.Bits >> 2) + ((_params.Domain.Bits & 7) == 0 ? 0 : 2)) { throw new ArgumentException(); } if (hash.Length == 0) { throw new ArgumentException(); } if (_params.Q == null && _params.D != null) { _params.CreatePublicKeyFromPrivateKey(); } if (_params.Q == null) { throw new CryptographicException(); } int halfLen = sig.Length >> 1; Number r = new Number(sig, 0, halfLen, false); Number s = new Number(sig, halfLen, halfLen, false); Number e = HashToNumber(hash); IFiniteField field = _params.Domain.FieldN; if (r >= _params.Domain.N || s >= _params.Domain.N) { return(false); } // Step.1 e = field.ToElement(e); s = field.ToElement(s); Number r2 = field.ToElement(r); // Step.2 Number w = field.Invert(s); // Step.3 Number u1 = field.ToNormal(field.Multiply(e, w)); Number u2 = field.ToNormal(field.Multiply(r2, w)); // Step.4 //ECPoint X = _params.Domain.G.Multiply (u1).Add (_params.Q.Multiply (u2)); ECPoint X; if (u1.IsZero()) { X = _params.Domain.FieldN.GetInfinityPoint(_params.Domain.Group).Add(_params.Q.Multiply(u2)); } else { X = ECPoint.MultiplyAndAdd(_params.Domain.G, u1, _params.Q, u2); } // Step.5 if (X.IsInifinity()) { return(false); } X = X.Export(); // Step.6 Number v = X.X % _params.Domain.N; return(r.CompareTo(v) == 0); }