signBip340Const method
Implementation
List<int> signBip340Const(
{required List<int> digest, List<int>? tapTweakHash, List<int>? aux}) {
if (digest.length != BitcoinSignerUtils.baselen) {
throw CryptoSignException(
"The digest must be a ${BitcoinSignerUtils.baselen}-byte array.");
}
if (aux != null && aux.length != 32) {
throw CryptoSignException("The aux must be a 32-byte array.");
}
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];
}