deterministicSign function

Signature deterministicSign(
  1. PrivateKey priv,
  2. List<int> hash
)

deterministicSign generates a deterministic ECDSA signature according to RFC 6979 and BIP 62 https://datatracker.ietf.org/doc/html/rfc6979

Implementation

Signature deterministicSign(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 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 Signature.fromRS(r, s);
}