isValidEthSignature static method

bool isValidEthSignature(
  1. BigInt r,
  2. BigInt s,
  3. int v, {
  4. bool homesteadOrLater = true,
  5. int chainId = -1,
  6. bool vIsBareRecoveryId = false,
})

vIsBareRecoveryId: EIP-1559/EIP-7702 typed transactions store the bare y-parity (0/1) in v, not the legacy EIP-155-encoded value (recId + chainId*2 + 35). Passing the typed-tx v through the EIP-155 formula yields a bogus recovery id and rejects every valid signature; callers must set this for typed transactions.

Implementation

static bool isValidEthSignature(BigInt r, BigInt s, int v,
    {bool homesteadOrLater = true,
    int chainId = -1,
    bool vIsBareRecoveryId = false}) {
  var SECP256K1_N_DIV_2 = hexToBigInt(dynamicToHex(
      '7fffffffffffffffffffffffffffffff5d576e7357a4501ddfe92f46681b20a0'));
  var SECP256K1_N = hexToBigInt(dynamicToHex(
      'fffffffffffffffffffffffffffffffebaaedce6af48a03bbfd25e8cd0364141'));

  final recoveryId =
      vIsBareRecoveryId ? v : calculateEthSigRecovery(v, chainId: chainId);
  if (!isValidEthSigRecovery(recoveryId)) return false;
  // r and s are structurally valid whenever 1 <= value < n — the shortest
  // big-endian encoding may legitimately be under 32 bytes (leading zero
  // byte), so byte length must not gate validity here.
  if (r == BigInt.zero ||
      r >= SECP256K1_N ||
      s == BigInt.zero ||
      s >= SECP256K1_N) return false;
  if (homesteadOrLater && s > SECP256K1_N_DIV_2) return false;

  return true;
}