signSchnorr method
Implementation
List<int> signSchnorr(List<int> digest, {List<int>? extraEntropy}) {
if (digest.length != BitcoinSignerUtils.baselen) {
throw CryptoSignException(
"The digest must be a ${BitcoinSignerUtils.baselen}-byte array.");
}
BigInt d = privateKey.secretMultiplier;
final BigInt order = CryptoSignerConst.generatorSecp256k1.order!;
if (!(BigInt.one <= d && d <= order - BigInt.one)) {
throw const CryptoSignException(
"The secret key must be an integer in the range 1..n-1.");
}
extraEntropy ??= CryptoSignerConst.bchSchnorrRfc6979ExtraData;
BigInt k = RFC6979.generateK(
order: order,
secexp: privateKey.secretMultiplier,
hashFunc: () => SHA256(),
data: digest,
extraEntropy: extraEntropy);
final R = (CryptoSignerConst.generatorSecp256k1 * k);
if (ECDSAUtils.jacobi(R.y, CryptoSignerConst.curveSecp256k1.p).isNegative) {
k = order - k;
}
final eHash = QuickCrypto.sha256Hash(
[...R.toXonly(), ...privateKey.publicKey.toBytes(), ...digest]);
final BigInt e = BigintUtils.fromBytes(eHash) % order;
// Step 5: Compute Schnorr Signature: s = k + e * d (mod n)
final BigInt s = (k + e * d) % order;
final signature = BitcoinSchnorrSignature(r: R.x, s: s).toBytes();
// Step 6: Return Signature (64 bytes: R.x || s)
return signature;
}