A Trustless zk Re-Genesis

The trust-minimized restart still leaned on an honest two-thirds of validators to sign. This time we replace the signatures with a zero-knowledge validity proof — anyone verifies it in milliseconds, and no coalition of validators can forge it.

In A Trust-Minimized Re-Genesis we halted a chain, changed a rule that’s supposed to be unchangeable, and relaunched it with its ledger provably intact. That migration was trust-minimized: to accept the new genesis you needed an honest two-thirds of the old validators to sign the checkpoint.

We were careful to call that trust-minimized, not trustless — and this is the loose thread. If two-thirds of the validators colluded, they could sign a false root and boot a fraudulent chain, and the migration would look perfectly valid. Safety rested on validator honesty.

This post cuts that thread. We replace the signatures with a zero-knowledge validity proof — a small piece of cryptography that shows the new genesis is the honest continuation of the old chain. Anyone can check it in milliseconds, and no coalition of validators, not even all of them, can forge one.

Proof size
128 B
any ledger size
Verify time
~2 ms
anyone, anywhere
Validators to trust
0
for safety
Forgeable?
No
even all of them

What a validity proof is, in 60 seconds

If you’ve met zk-rollups, skip ahead. If not, one idea does all the work.

A validity proof (the cryptographic machinery is a ) lets someone who did a computation hand you a tiny receipt that convinces you it was done correctly — without redoing it, and without showing you the inputs. Three properties matter here:

  • Succinct — the proof is a fixed, tiny size (ours is 128 bytes) and checks in milliseconds, no matter how big the computation was.
  • Sound — you cannot produce a proof of a false statement. Not with more compute, not with a validator majority. A false claim simply has no valid proof.
  • Zero-knowledge — the proof reveals nothing beyond the statement itself. You can prove “the ledger is correct” while keeping the balances private, disclosing only the accounts you choose.

Hold the middle one — soundness — because it’s what turns “trust the validators” into “check the math.”

The gap we’re closing

Last time, the validators’ signatures did one job: they attested that the exported state matched the committed root. Attestation is a promise, and a promise is only as good as the people making it. A two-thirds coalition could promise a lie.

A proof isn’t a promise. It’s evidence. Swapping one for the other moves exactly one thing — but it’s the thing that matters most.

What changes, and what doesn't. A validity proof moves safety from the validators to math; liveness still rests on them.

Safety — the guarantee that nobody can forge a false ledger — stops depending on validator honesty and starts depending on mathematics. Liveness — the guarantee that the migration actually happens — still rests on the validators: a malicious set can refuse to produce the proof and stall. But refusing is all they can do. They can no longer forge. The worst outcome drops from “a fraudulent chain that looks real” to “no new chain at all.”

The idea

The old chain commits its exact ledger to a root — call it C — and that root is public: it’s in the block header that every node saw. The operator — whoever runs the migration: the party that builds the new chain from the snapshot and produces the proof (the prover in the diagram below), not a validator — ships a proof alongside the new chain’s genesis. The proof says:

“I know the full set of balances behind C, and the new genesis commits exactly those balances.”

Anyone booting or auditing the new chain checks that proof against the public root C — the one already sitting in the old chain’s final block header. No ledger, no validators: just C and the 128-byte proof.

The prover knows the whole ledger but hands over only a 128-byte proof and the few balances it chooses to disclose. The verifier checks it against public data alone.

Because the proof is sound, a tampered ledger is a dead end. Change one balance and it no longer commits to C — it commits to some other root — so there is simply no proof that verifies against the real, public C. The forgery fails at the math, before anyone has to trust or distrust a single validator.

What we built

We built the real thing over the actual halted-chain state from the last post: block #100, its twelve accounts and their true balances.

  • We commit those balances with a to a root C.
  • We prove, in over the curve, that we know the balances behind C — recomputing the commitment inside the circuit so the proof is worthless unless the balances are exactly right.
  • We selectively disclose three accounts (Alice, Bob, Charlie) as public, and keep the other nine hidden. That’s the zero-knowledge part earning its name: the proof convinces you the whole ledger is correct while revealing only what we choose.

Then we try to cheat: a malicious operator adds a billion to its own account and attempts to prove the tampered ledger against the same public C. Watch it fail.

The real prover and verifier over block #100. A 128-byte proof, disclosing Alice/Bob/Charlie and hiding the rest, verifies in ~2 ms. The tampered ledger commits to a different root, so its forged proof is rejected.
The real prover and verifier over block #100. A 128-byte proof, disclosing Alice/Bob/Charlie and hiding the rest, verifies in ~2 ms. The tampered ledger commits to a different root, so its forged proof is rejected.

A 128-byte proof, verified in about two milliseconds, that even a fully malicious validator set cannot forge. No signatures. No quorum. Just check the math.

Being honest about the edges

The last post earned trust by being precise about what “trust-minimized” did and didn’t mean. Same discipline here.

  • The commitment is a model. A real Substrate chain commits state in a Blake2 , which is expensive to prove. Our demo uses a SNARK-friendly commitment (a -style hash) computed over the same balances — the standard move for a chain that wants to be zk-verifiable. It’s a clean-room model of the mechanism, the same way the testbed here is a clean-room chain.
  • Groth16 needs a setup. The proving system we used requires a one-time per circuit. A production deployment would run a proper multi-party ceremony, or switch to a transparent system (a , or -family scheme) that needs no ceremony at all. The 128-byte, milliseconds-to-verify shape is representative either way.
  • Liveness is still validators. As the diagram said: the proof removes the power to forge, not the power to stall. And which block counts as the true head #100 is still a fact established by the chain’s finality — that’s inherent to any blockchain, and it’s the same assumption the chain always ran on.
  • A deeper version exists. We proved that the state behind a root is faithfully carried over. The stronger statement is a proof of the execution itself — that every block from genesis to #100 followed the rules — by running the whole runtime inside a . That’s a substantially larger undertaking, and it’s the general direction this class of proof points toward.

The through-line

Three posts, one arc. First we asked whether a chain could change a rule it’s not supposed to change, and halted it to find out. Then we carried its ledger across the gap in a way nobody had to take on faith — as long as they trusted the validators. Now even that’s gone.

A signature says trust us. A proof says check for yourself. For a chain whose whole reason to exist is removing the need to trust intermediaries, that’s not a nicety — it’s the point.