dleqProve method
VRFProof
dleqProve(
- VRFInOut out, {
- bool kusamaVRF = true,
- GenerateRandom? nonceGenerator,
- MerlinTranscript? verifyScript,
Generates a Discrete Logarithm Equality Proof (DLEQ) for a Verifiable Random Function (VRF) output.
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 istruefor Kusama VRF compatibility.nonceGenerator(optional): A function that generates a nonce. Default is a function that generates a random 64-byte nonce.
Implementation
VRFProof dleqProve(
VRFInOut out, {
bool kusamaVRF = true,
GenerateRandom? nonceGenerator,
MerlinTranscript? verifyScript,
}) {
const int nonceLength = SchnorrkelKeyCost.nonceLength * 2;
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(nonceLength) ??
QuickCrypto.generateRandom(nonceLength);
if (nonce.length != nonceLength) {
throw const CryptoException("invalid nonce length.");
}
final nScalar = Ed25519Utils.scalarReduceConst(nonce);
final mult = RistrettoPoint.fromEdwardBytes(
Ed25519Utils.scalarMultBase(nScalar),
);
script.additionalData("vrf:R=g^r".codeUnits, mult.toBytes());
RistrettoPoint inputPoint = RistrettoPoint.fromBytes(out.input);
inputPoint = RistrettoPoint.fromEdwardBytes(
Ed25519Utils.pointScalarMult(inputPoint.toEdwardBytes(), nScalar),
);
script.additionalData("vrf:h^r".codeUnits, inputPoint.toBytes());
if (kusamaVRF) {
script.additionalData("vrf:pk".codeUnits, publicKey().toBytes());
}
script.additionalData("vrf:h^sk".codeUnits, out.output);
final c = script.toBytesWithReduceScalar(
"prove".codeUnits,
SchnorrkelKeyCost.vrfProofLength,
);
final multiply = Ed25519Utils.mulSub(c, key(), nScalar);
return VRFProof._(c, multiply);
}