prepSig static method

(Uint8List, K2SigFunc) prepSig(
  1. Uint8List message,
  2. BigInt privateKey, {
  3. RandomBytesFunc? randomBytesFunc,
  4. bool? lowS,
  5. Uint8List? extraEntropy,
})

Implementation

static (Uint8List seed, K2SigFunc k2sig) prepSig(
    Uint8List message, BigInt privateKey,
    {RandomBytesFunc? randomBytesFunc, bool? lowS, Uint8List? extraEntropy}) {
  // RFC6979 3.2: we skip step A
  lowS ??= true;
  // msg bigint
  final BigInt h1i = bits2int_modN(message);
  // msg octets
  final Uint8List h1o = bigIntToBytes(h1i);
  // Step D of RFC6979 3.2
  final List<Uint8List> seed = [bigIntToBytes(privateKey), h1o];
  // RFC6979 3.6: additional k' (optional)
  if (extraEntropy != null && extraEntropy.isNotEmpty) {
    if (extraEntropy.length != fLen) {
      // Expected 32 bytes of extra data
      throw Exception('extraEntropy not provided');
    }
    seed.add(extraEntropy);
  }
  // convert msg to bigint
  final BigInt m = h1i;

  // Transform k => Signature.
  Signature? k2sig(Uint8List kBytes) {
    // RFC6979 method.
    final k = bits2int(kBytes);
    // Check 0 < k < CURVE.n
    if (!ge(k)) {
      return null;
    }
    // k^-1 mod n, NOT mod P
    final ik = inverse(k, N);
    // q = Gk
    final AffinePoint q = Point.G.mul(k).affinePoint();
    // r = q.x mod n
    final r = mod(q.x, N);
    if (r == BigInt.zero) {
      // r=0 invalid
      return null;
    }
    // s = k^-1(m + rd) mod n
    final s = mod(ik * mod(m + mod(privateKey * r, N), N), N);
    if (s == BigInt.zero) {
      return null;
    } // s=0 invalid
    BigInt normS = s; // normalized S
    int rec = (q.x == r ? 0 : 2) | (q.y & BigInt.one).toInt(); // recovery bit
    if (lowS! && moreThanHalfN(s)) {
      // if lowS was passed, ensure s is always
      normS = mod(-s, N); // in the bottom half of CURVE.n
      rec ^= 1;
    }
    return Signature(r: r, s: normS, recovery: rec); // use normS, not s
  }

  return (concatBytes(seed), k2sig); // return Bytes+Checker
}