ecdsaVerify function
Verifies an ECDSA signature (DER SEQUENCE { r, s }) over digest.
Implementation
bool ecdsaVerify(EcPublicKey key, List<int> digest, Uint8List signatureDer) {
final BigInt r, s;
try {
final seq = DerObject.parse(signatureDer).children;
r = seq[0].asInteger;
s = seq[1].asInteger;
} on Object {
return false;
}
final curve = key.curve;
final n = curve.n;
if (r <= BigInt.zero || r >= n || s <= BigInt.zero || s >= n) return false;
// leftmost bits of the digest, per SEC1 ยง4.1.4
var e = BigInt.zero;
for (final byte in digest) {
e = (e << 8) | BigInt.from(byte);
}
final excess = digest.length * 8 - n.bitLength;
if (excess > 0) e >>= excess;
final w = s.modInverse(n);
final u1 = (e * w) % n;
final u2 = (r * w) % n;
final point = _add(
curve, _multiply(curve, curve.g, u1), _multiply(curve, (key.x, key.y), u2));
if (point == null) return false;
return point.$1 % n == r;
}