public EccVerificationResult Verify(EccDomainParameters domainParameters, EccKeyPair keyPair, BitString message, EccSignature signature, bool skipHash = false) { // Check r and s to be within the interval [1, n-1] if (signature.R < 1 || signature.R > domainParameters.CurveE.OrderN - 1 || signature.S < 1 || signature.S > domainParameters.CurveE.OrderN) { return(new EccVerificationResult("signature values not within the necessary interval")); } // Hash message e = H(m) var bitsOfDigestNeeded = System.Math.Min(domainParameters.CurveE.OrderN.ExactBitLength(), Sha.HashFunction.OutputLen); // Determine whether to hash or skip the hash step for component test var hashDigest = skipHash ? message : Sha.HashMessage(message).Digest; var e = hashDigest.MSBSubstring(0, bitsOfDigestNeeded).ToPositiveBigInteger(); // Compute u1 = e * s^-1 (mod n) var sInverse = signature.S.ModularInverse(domainParameters.CurveE.OrderN); var u1 = (e * sInverse) % domainParameters.CurveE.OrderN; // Compute u2 = r * s^-1 (mod n) var u2 = (signature.R * sInverse) % domainParameters.CurveE.OrderN; // Compute point R = u1 * G + u2 * Q, if R is infinity, return invalid var u1TimesG = domainParameters.CurveE.Multiply(domainParameters.CurveE.BasePointG, u1); var u2TimesQ = domainParameters.CurveE.Multiply(keyPair.PublicQ, u2); var pointR = domainParameters.CurveE.Add(u1TimesG, u2TimesQ); // Convert xR to an integer j var j = pointR.X; // Compute v = j (mod n) var v = j % domainParameters.CurveE.OrderN; // If v == r, return valid, otherwise invalid if (v == signature.R) { return(new EccVerificationResult()); } else { return(new EccVerificationResult("v did not match r, signature not valid")); } }
public EccSignatureResult(EccSignature signature) { Signature = signature; }