ethereumSign function
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);
}