ethereumSign function

EthSignature ethereumSign(
  1. PrivateKey priv,
  2. List<int> hash
)

ethereumSign generates a deterministic ECDSA signature according to RFC 6979 and BIP 62 https://datatracker.ietf.org/doc/html/rfc6979 https://ethereum.stackexchange.com/questions/65910/is-signatures-from-web3-eth-personal-sign-deterministic-and-a-safe-to-be-used-as Ethereum uses the deterministic (and elliptic-curve) variant of DSA.

Implementation

EthSignature ethereumSign(PrivateKey priv, List<int> hash) {
  var k = generateSecret(priv.curve.n, priv.D, hash);
  var inv = k.modInverse(priv.curve.n);
  var hexK = k.toRadixString(16).padLeft((k.bitLength + 7) ~/ 8 * 2, '0');
  var p = priv.curve.scalarBaseMul(List<int>.generate(hexK.length ~/ 2,
      (i) => int.parse(hexK.substring(i * 2, i * 2 + 2), radix: 16)));
  var r = p.X % priv.curve.n;
  if (r.sign == 0) {
    throw Exception('calculated R is zero');
  }
  var y = p.Y % priv.curve.n;
  var v = (y % BigInt.two).toInt();

  var e = bitsToInt(hash, priv.curve.n.bitLength);
  var s = priv.D * r + e;
  s = (s * inv) % priv.curve.n;

  if (s > (priv.curve.n >> 1)) {
    s = priv.curve.n - s;
  }

  if (s.sign == 0) {
    throw Exception('calculated S is zero');
  }

  return EthSignature.fromRSV(r, s, v);
}