signSchnorrConst method

List<int> signSchnorrConst({
  1. required List<int> digest,
  2. List<int>? extraEntropy,
})

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];
}