signSchnorrConst method
Implementation
List<int> signSchnorrConst(
{required List<int> digest, List<int>? extraEntropy}) {
if (digest.length != Curves.curveSecp256k1.baselen) {
throw CryptoSignException(
"The digest must be a ${Curves.curveSecp256k1.baselen}-byte array.");
}
final sec = privateKey.toBytes();
List<int> k = RFC6979.generateSecp256k1KBytes(
secexp: sec,
hashFunc: () => SHA256(),
data: digest,
extraEntropy: extraEntropy);
final kScalar = Secp256k1Utils.scalarFromBytes(k);
if (!Secp256k1Utils.scCheck(kScalar)) {
throw const CryptoSignException(
'Schnorr signing failed due to an unexpected error.');
}
Secp256k1Gej R = Secp256k1Gej();
Secp256k1.secp256k1ECmultGen(ecMultContext, R, kScalar);
Secp256k1Ge rg = Secp256k1Ge();
Secp256k1.secp256k1GeSetGej(rg, R);
Secp256k1.secp256k1FeNormalize(rg.x);
Secp256k1.secp256k1FeNormalize(rg.y);
List<int> nonce32 = List<int>.filled(32, 0);
Secp256k1.secp256k1FeGetB32(nonce32, rg.x);
final eHash = QuickCrypto.sha256Hash(
[...nonce32, ...privateKey.publicKey.toBytes(), ...digest]);
final sk = Secp256k1Utils.scalarFromBytes(sec);
final eSclar = Secp256k1Utils.scalarFromBytes(eHash);
if (!Secp256k1Utils.scCheck(sk) || !Secp256k1Utils.scCheck(eSclar)) {
throw const CryptoSignException(
'Schnorr signing failed due to an unexpected error.');
}
Secp256k1Scalar n = Secp256k1Scalar();
Secp256k1Scalar sigs = Secp256k1Scalar();
Secp256k1.secp256k1ScalarMul(n, eSclar, sk);
if (Secp256k1.secp256k1FeIsQuad(R.y) == 0) {
Secp256k1.secp256k1ScalarNegate(kScalar, kScalar);
}
Secp256k1.secp256k1ScalarAdd(sigs, kScalar, 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 [...nonce32, ...sBytes];
}