sign method

SchnorrkelSignature sign(
  1. MerlinTranscript signingContextScript, {
  2. GenerateRandom? nonceGenerator,
})

Signs a message using the Schnorrkel secret key and a specified signing context script.

This method generates a Schnorrkel signature for a given message by appending context-specific information to the signing context script and combining it with a nonce.

Parameters:

  • signingContextScript: A transcript containing context-specific information for the signature.
  • nonceGenerator (optional): A function that generates a nonce. Default is a function that generates a random 64-byte nonce.

Returns: A SchnorrkelSignature representing the generated signature.

Example Usage:

MerlinTranscript signingContextScript = ...;
SchnorrkelSecretKey secretKey = ...;
GenerateRandom? customNonceGenerator = (length) => ...;
SchnorrkelSignature signature = secretKey.sign(signingContextScript, customNonceGenerator);

The sign method generates a Schnorrkel signature for a message by incorporating context-specific information from the signing context script, a nonce, and the secret key. It returns a SchnorrkelSignature instance.

Implementation

SchnorrkelSignature sign(MerlinTranscript signingContextScript,
    {GenerateRandom? nonceGenerator}) {
  signingContextScript.additionalData(
      "proto-name".codeUnits, "Schnorr-sig".codeUnits);
  signingContextScript.additionalData(
      "sign:pk".codeUnits, publicKey().toBytes());
  final nonceRand =
      nonceGenerator?.call(64) ?? QuickCrypto.generateRandom(64);
  if (nonceRand.length != 64) {
    throw ArgumentException("invalid random bytes length");
  }
  final nonceBytes = Ed25519Utils.scalarReduce(nonceRand);
  final nonceBigint =
      BigintUtils.fromBytes(nonceBytes, byteOrder: Endian.little);
  final r =
      RistrettoPoint.fromEdwardsPoint(Curves.generatorED25519 * nonceBigint);
  signingContextScript.additionalData("sign:R".codeUnits, r.toBytes());
  final k =
      signingContextScript.toBytesWithReduceScalar("sign:c".codeUnits, 64);
  final km = ristretto_tools.mul(key(), k);
  final s = ristretto_tools.add(km, nonceBytes);
  final sig = SchnorrkelSignature._(s, r.toBytes());
  return sig;
}