dleqProve method

VRFProof dleqProve(
  1. VRFInOut out, {
  2. bool kusamaVRF = true,
  3. GenerateRandom? nonceGenerator,
  4. MerlinTranscript? verifyScript,
})

Generates a Discrete Logarithm Equality Proof (DLEQ) for a Verifiable Random Function (VRF) output.

This method generates a DLEQ proof for a given VRF output, ensuring the equality of discrete logarithms of specific points in the VRF computation.

Parameters:

  • out: A VRFInOut containing the VRF output to prove.
  • kusamaVRF (optional): A boolean indicating whether to include the public key in the DLEQ proof. Default is true for Kusama VRF compatibility.
  • nonceGenerator (optional): A function that generates a nonce. Default is a function that generates a random 64-byte nonce.

Returns: A VRFProof representing the DLEQ proof.

Example Usage:

VRFInOut vrfOutput = ...;
SchnorrkelSecretKey secretKey = ...;
var dleqProof = secretKey.dleqProve(vrfOutput);

The dleqProve method generates a DLEQ proof for a VRF output, ensuring the equality of discrete logarithms between specific points in the VRF computation. It returns a VRFProof instance.

Implementation

VRFProof dleqProve(VRFInOut out,
    {bool kusamaVRF = true,
    GenerateRandom? nonceGenerator,
    MerlinTranscript? verifyScript}) {
  final script = verifyScript ?? MerlinTranscript("VRF");
  script.additionalData("proto-name".codeUnits, "DLEQProof".codeUnits);
  script.additionalData("vrf:h".codeUnits, out.input);
  if (!kusamaVRF) {
    script.additionalData("vrf:pk".codeUnits, publicKey().toBytes());
  }
  final nonce = nonceGenerator?.call(64) ?? QuickCrypto.generateRandom(64);
  if (nonce.length != 64) {
    throw const ArgumentException("invalid random bytes length");
  }
  final n = Ed25519Utils.scalarReduce(nonce);
  final scalar = BigintUtils.fromBytes(n, byteOrder: Endian.little);
  final mult =
      RistrettoPoint.fromEdwardsPoint(Curves.generatorED25519 * scalar);
  script.additionalData("vrf:R=g^r".codeUnits, mult.toBytes());
  final inputPoint = RistrettoPoint.fromBytes(out.input);
  final hr = inputPoint * scalar;
  script.additionalData("vrf:h^r".codeUnits, hr.toBytes());
  if (kusamaVRF) {
    script.additionalData("vrf:pk".codeUnits, publicKey().toBytes());
  }
  script.additionalData("vrf:h^sk".codeUnits, out.output);
  final c = script.toBytesWithReduceScalar("prove".codeUnits, 64);
  final multiply = Ed25519Utils.mul(c, key());
  final s = Ed25519Utils.sub(n, multiply);

  return VRFProof._(c, s);
}