signBip340Const method
Implementation
List<int> signBip340Const({
required List<int> digest,
List<int>? tapTweakHash,
List<int>? aux,
}) {
if (digest.length != BitcoinSignerUtils.baselen) {
throw ArgumentException.invalidOperationArguments(
"signBip340Const",
name: "digest",
reason: "Invalid digest bytes length.",
);
}
if (aux != null && aux.length != 32) {
throw ArgumentException.invalidOperationArguments(
"signBip340Const",
name: "aux",
reason: "Invalid aux bytes length.",
);
}
final tKey = _tweakConst(
privateKey.toBytes(),
ecMultContext,
tapTweakHash: tapTweakHash,
);
aux ??= QuickCrypto.sha256Hash([
...digest,
...Secp256k1Utils.scalarToBytes(tKey),
]);
Secp256k1Ge mid = Secp256k1Ge();
Secp256k1Gej res = Secp256k1Gej();
Secp256k1.secp256k1ECmultGen(ecMultContext, res, tKey);
Secp256k1.secp256k1GeSetGej(mid, res);
if (Secp256k1.secp256k1FeIsOdd(mid.y) == 1) {
Secp256k1.secp256k1ScalarNegate(tKey, tKey);
}
final d = Secp256k1Utils.scalarToBytes(tKey);
final t = BytesUtils.xor(d, P2TRUtils.taggedHash("BIP0340/aux", aux));
Secp256k1.secp256k1FeNormalize(mid.x);
final xBytes = Secp256k1Utils.feToBytes(mid.x);
final kHash = P2TRUtils.taggedHash("BIP0340/nonce", [
...t,
...xBytes,
...digest,
]);
final k0 = Secp256k1Utils.scalarFromBytes(kHash);
if (!Secp256k1Utils.scCheck(k0)) {
throw const CryptoSignException(
'Schnorr signing failed due to an unexpected error.',
);
}
Secp256k1Ge midR = Secp256k1Ge();
Secp256k1Gej resR = Secp256k1Gej();
Secp256k1.secp256k1ECmultGen(ecMultContext, resR, k0);
Secp256k1.secp256k1GeSetGej(midR, resR);
if (Secp256k1.secp256k1FeIsOdd(midR.y) == 1) {
Secp256k1.secp256k1ScalarNegate(k0, k0);
}
Secp256k1.secp256k1FeNormalize(midR.x);
final rBytes = Secp256k1Utils.feToBytes(midR.x);
final eHash = P2TRUtils.taggedHash("BIP0340/challenge", [
...rBytes,
...xBytes,
...digest,
]);
final eSclar = Secp256k1Utils.scalarFromBytes(eHash);
if (!Secp256k1Utils.scCheck(eSclar)) {
throw const CryptoSignException(
'Schnorr signing failed due to an unexpected error.',
);
}
Secp256k1Scalar n = Secp256k1Scalar();
Secp256k1Scalar sigs = Secp256k1Scalar();
Secp256k1.secp256k1ScalarMul(n, eSclar, tKey);
Secp256k1.secp256k1ScalarAdd(sigs, k0, n);
if (!Secp256k1Utils.scCheck(sigs)) {
throw const CryptoSignException(
'Schnorr signing failed due to an unexpected error.',
);
}
List<int> sBytes = List<int>.filled(32, 0);
Secp256k1.secp256k1ScalarGetB32(sBytes, sigs);
return [...rBytes, ...sBytes];
}