prepSig static method
(Uint8List, K2SigFunc)
prepSig(
- Uint8List message,
- BigInt privateKey, {
- RandomBytesFunc? randomBytesFunc,
- bool? lowS,
- 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
}