← Back to all posts
Protocol Cryptography Security

The Verifiable Delay Function — Wattcoin's Cryptographic Clock

July 13, 2026  —  8 min read

The Timing Problem

In any system where compensation depends on how long work takes, the obvious question arises: how do you prove how much time elapsed? A miner could claim a probe took 1000 ms when it actually took 200 ms, inflating their measured throughput by 5×.

Naïve solutions don't work. The coordinator could measure wall-clock time, but network round-trip latency adds noise. The worker could self-report its timing, but a dishonest worker would simply lie. Hardware clocks can be manipulated. Even cryptographic hash functions — the backbone of Proof-of-Work — can be parallelized, so they prove total computation, not elapsed time.

Wattcoin solves this with a Verifiable Delay Function (VDF) — a cryptographic primitive that takes a minimum amount of sequential time to compute, yet can be verified almost instantly. The VDF acts as a cryptographic clock: it proves that at least a certain amount of real time has passed, and no amount of parallelism, caching, or pre-computation can speed it up.

What Is a VDF?

A Verifiable Delay Function is a function that satisfies three properties:

  1. Sequential computation. The function requires a specified number of sequential steps. Each step depends on the output of the previous step, so parallelism provides no advantage. A computer with 1000 cores computes it at the same speed as a single core.
  2. Efficient verification. Anyone can verify the output is correct in a fraction of the time it took to compute. A proof that took 1 second to produce can be verified in roughly 1 millisecond.
  3. Deterministic output. Given the same input and parameters, the VDF always produces the same proof. There is no randomness in the output — the proof is a mathematical certificate of elapsed computation.

The VDF used in Wattcoin is the Wesolowski VDF scheme, implemented via the crypto-vdf library (Rust/GMP backend). It is based on repeated squaring in a class group of imaginary quadratic fields — a mathematical structure where squaring is easy but computing square roots is believed to be hard.

How Wattcoin Uses VDFs

Every peer probe in Wattcoin is paired with a VDF computation. The VDF serves two critical roles: proving elapsed time and binding the probe to a specific context.

Step 1: Challenge Derivation

When the coordinator issues a probe, it includes a unique probeId. The worker independently derives a 32-byte VDF challenge using SHA-256:

challenge = SHA-256("wtc-vdf-v1" | probeId | workerId | chainIndex)

This challenge is deterministic — given the same probe ID, worker ID, and chain index, every node on the network computes the same challenge. But it is also unique per context — changing any of the three inputs produces a completely different challenge. This prevents pre-computation: a worker cannot solve a VDF for a probe that hasn't been issued yet, because the challenge depends on the probe ID.

Step 2: Parallel Computation

The worker starts the VDF computation before the benchmark workload. Both run in parallel:

Worker receives probe
  |
  +--> VDF solve (main process, ~1s)                           
  +--> Benchmark (renderer/hardware, ~1s)
  |
  v
Total probe time = max(benchmark, VDF)

The VDF runs in the Electron main process while CPU, memory, GPU, or ASIC work runs in the renderer or hardware driver. Because they execute on different cores (or even different processes), they don't interfere with each other. Total probe time is the maximum of the two, not the sum.

Step 3: Proof Submission

When both computations finish, the worker submits the probe result along with the VDF proof:

  • vdfProof — the hex-encoded Wesolowski proof (~600 bytes)
  • vdfOutput — SHA-256 hash of the proof (compact identifier for receipts)
  • vdfSteps — the difficulty parameter (number of sequential squarings)
  • vdfDiscriminantSize — the bit-length of the discriminant (default 512)
  • vdfTimingMs — the worker's self-reported wall-clock time for the VDF computation

Step 4: Coordinator Verification

The coordinator independently verifies the VDF proof. This is the core security check:

  1. Reconstruct the challenge. The coordinator computes deriveVdfInput(probeId, workerId, chainIndex) using the same inputs. If the worker submitted a challenge for a different probe, worker, or chain position, verification fails.
  2. Verify the proof. The coordinator calls vdfVerify({ challenge, difficulty, discriminantSizeBits, proof }). This runs the Rust/GMP verification in ~1 ms. If the proof is invalid — wrong challenge, wrong difficulty, or forged — verification returns false.
  3. Sanity-check timing. The worker's self-reported vdfTimingMs must be at least 60% of the theoretical minimum time for those parameters. If a worker claims the VDF solved in 100 ms when the math requires at least 600 ms, the timing is flagged as suspicious.
  4. Use VDF timing as authoritative. The verified vdfTimingMs replaces the coordinator's wall-clock time for all throughput and energy calculations. This eliminates network RTT inflation and makes the timing cryptographically grounded.

Why VDF Timing Replaces Wall Clock

Without VDFs, the coordinator would measure how long a probe took by recording the timestamp when it issued the probe and subtracting it from the timestamp when the result arrived. This includes:

  • Network round-trip time (varies from 10 ms to 500+ ms)
  • WebSocket serialization overhead
  • Operating system scheduling delays
  • Clock skew between machines

These factors add noise and can be manipulated. A worker on a slow connection appears slower than it is, and a worker that deliberately delays submission can appear to have taken longer.

The VDF eliminates all of these problems. The worker's self-reported vdfTimingMs is the time it actually took to solve the VDF — but this value is only trusted if the proof verifies correctly and the timing passes the sanity check. A worker that lies about its VDF timing either:

  • Reports a time that's too low → caught by the 60% sanity threshold
  • Reports a time that's too high → doesn't help, because the proof's mathematical properties cap the maximum speed
  • Reports a fake proof → caught immediately by vdfVerify()

The result: the coordinator gets a timing measurement that is independent of network conditions and cryptographically bounded to within a reasonable range of the true elapsed time.

Anti-Replay: Why Each VDF Is Unique

A subtle but critical property of the VDF system is that each proof is bound to a specific context. The challenge derivation formula ensures that:

  • Same probe, different worker → different challenge (because workerId changes)
  • Same worker, different probe → different challenge (because probeId changes)
  • Same probe and worker, different chain position → different challenge (because chainIndex changes)

This means a worker cannot pre-compute VDF proofs. The challenge for the next probe is unknown until the coordinator issues it. And even if a worker somehow obtained a valid VDF proof from a previous probe, it could not reuse it — the challenge would be different.

Discriminant Sizes and Difficulty

The VDF has two tunable parameters that control the security-vs-performance tradeoff:

Discriminant Bits Est. Solve Time Est. Verify Time Use Case
256 ~500 ms ~50 ms Fast probes on low-power hardware
512 ~1000 ms ~135 ms Default for all peer probes
1024 ~3000 ms ~400 ms Higher-security attestations
2048 ~12000 ms ~1500 ms Maximum security, rarely used

The default configuration uses 512-bit discriminants with 2000 sequential squarings (difficulty). This provides roughly 1 second of verifiable computation on a modern CPU, with verification completing in about 135 ms. The discriminant sizes are pre-computed and cached in memory for fast access.

VDF in the Signed Receipt

After the coordinator verifies the VDF proof, the VDF fields are included in the signed probe receipt. This receipt is the worker's cryptographic attestation of their energy expenditure:

{
  "version": 2,
  "probeId": "...",
  "workerId": "...",
  "wallClockMs": 1023,
  "iterations": 48291034,
  "vdfSteps": 2000,
  "vdfDiscriminantSize": 512,
  "vdfInput": "a1b2c3...",
  "vdfOutput": "d4e5f6...",
  "vdfProof": "012345...",
  ...
}

The VDF fields are part of the signed payload, so any tampering with VDF data invalidates the secp256k1 signature. The receipt version was bumped from 1 to 2 when VDF support was added, and old v1 receipts remain backward-compatible (VDF fields are simply absent).

What VDFs Don't Protect Against

VDFs are powerful but not a complete solution on their own. They prove elapsed time, but they don't prove what work was done during that time. A worker could solve a VDF correctly but submit fabricated benchmark results. This is why the probe system layers multiple protections:

  • Computational proof verification — the coordinator independently re-computes CPU benchmarks and cryptographically verifies GPU nonces and ASIC shares. A fabricated benchmark is detected even if the VDF is valid.
  • Hardware identity attestation — OS-level CPU model, DXGI GPU model from the native binary, and device type cross-checks prevent claiming hardware that isn't installed.
  • Multi-coordinator cross-attestation — every miner connects to multiple coordinators that independently issue probes. A single malicious coordinator cannot unilaterally validate fake results.
  • Trust scoring — probe results feed into a sliding-window trust score that scales mining power from 20% to 100%. Failed probes penalize the score, and sustained failure rates trigger additional penalties.

The VDF is the timing layer of this stack. It ensures that the time component of every measurement is trustworthy. The other layers ensure that the computation component is trustworthy. Together, they make Proof-of-Energy mining resistant to the full spectrum of timing and computation attacks.

Summary

Wattcoin's VDF implementation uses Wesolowski VDFs with 512-bit discriminants and 2000 sequential squarings to create a cryptographic clock that cannot be parallelized, pre-computed, or replayed. Every peer probe derives a unique challenge bound to the probe ID, worker ID, and chain position. The coordinator verifies the proof in ~1 ms and uses the VDF-measured timing as the authoritative source for throughput and energy calculations. The VDF fields are included in signed receipts, making any tampering detectable. While VDFs alone don't prevent all cheating, they provide the timing foundation that makes the rest of the probe system's guarantees possible.

Want to learn more? Read the peer probe system deep dive to see how VDFs fit into the full attestation framework, or check the open-source code on GitHub for the VDF implementation in electron-main/vdf.js.