sign = function(hashbuf, privkey, opts) {
  const { endian = 'big', randomK = false } = opts || {};
  $.checkState(BufferUtil.isBuffer(hashbuf) && hashbuf.length === 32, 'hashbuf must be a 32 byte buffer');
  $.checkState(privkey && privkey.bn, 'privkey must be a PrivateKey');
  
  var d = privkey.bn;
  hashbuf = Buffer.from(hashbuf);
  if (endian === 'little') {
    hashbuf.reverse();
  }

  var e = BN.fromBuffer(hashbuf);
  var N = Point.getN();
  var G = Point.getG();
  // try different values of k until r, s are valid
  var badrs = 0;
  var k, Q, r, s;
  do {
    k = randomK ? getRandomK() : getDeterministicK(hashbuf, privkey, badrs);
    badrs++;
    Q = G.mul(k);
    r = Q.x.umod(N);
    s = k.invm(N).mul(e.add(d.mul(r))).umod(N);
  } while (r.cmp(BN.Zero) <= 0 || s.cmp(BN.Zero) <= 0);

  s = toLowS(s);

  return new Signature({
    s: BN.fromBuffer(s.toBuffer()),
    r: BN.fromBuffer(r.toBuffer()),
    compressed: privkey.publicKey.compressed
  });
}
Sign a hash with a private key.
@param {Buffer|Uint8Array} hashbuf
@param {PrivateKey} privkey
@param {Object|undefined} opts An object of optional parameters
@param {String} opts.endian 'big' or 'little' (default: big)
@param {Boolean} opts.randomK Use a random value for k - produces a non-deterministic signature (default: false)
@returns {Signature}