This post is the readable version. The full paper with the 9-dimension framework and 27 citations, lives here.
Ok picture this.
You live in a nice, secure house. The locks are good. Best locks as a matter of fact.
Then one day a locksmith knocks on your door and says: "We found a way to pick them last week. You should replace them ASAP."
Yer normal person would respond: "Ok, replace the locks. Let's make it our weekend project."
Blockchain response: "Uhhhh so the locks are actually load-bearing. And also they're welded onto the door. And replacing them requires a governance vote across 10,000 independent node operators, three security audits, a six-month transition period, and we still haven't figured out what to do with the 400 million doors that were already opened using the old lock model. We'll get back to you."
This is the world we live in. And it's about to matter a lot.
+++++++++++++++++++++++
MD5 was broken in 2004 but it was still in production certificates until 2012. Eight years of running around with passwords that can be decrypted with the right algorithm.
SHA-1 was theoretically dead in 2005. Then practically dead in 2017 when researchers actually demonstrated a collision. It took years of coordination across browsers, certificate authorities, and server operators to fully remove.
RSA-1024 was deprecated by NIST in 2011. But it was still running in enterprise systems a decade later.
This isn't negligence on the part of cryptographers and engineers, but simple migration friction. Knowing your primitive is broken is the easy part. Actually being capable of swapping it out without burning everything down… now that's the hard part. And da danki haz observed that different systems have wildly different abilities to do this.
The technical term for this ability is cryptographic agility. Some systems have a lot of it. And some really good, currently secure systems have very little of it.
The problem is that blockchain and ZK systems are built differently. And when you try to migrate the cryptography in an immutable ledger system, you run into a class of problems that didn't exist before.
TLS has set the bar since 1999
TLS is the protocol behind every HTTPS connection you've ever made. It is ancient by internet standards. It has been upgraded approximately one million times.
The reason it survives repeated upgrades is embarrassingly simple: the algorithm selection happens during the handshake. Before any actual communication, client and server have a little chat: "hey what ciphers do you support?" "oh I support these five, which ones do you have?" "cool, let's use this one."
And believe it or not, that exchange is the whole game. If you need to retire a broken algorithm, you just stop advertising it in the handshake, periodt. If you need to add a new one, you add it to the list. The rest of the protocol doesn't care. It just does whatever the handshake decided.
The algorithm is a mere parameter at the negotiation layer.
TLS 1.3 dropped over 300 weak cipher suite options. Got rid of RC4, 3DES, export ciphers. Hardened the handshake so that an attacker can't force you onto a weaker option — which yes, people tried. POODLE downgraded connections to SSL 3.0. FREAK forced export-grade RSA. LOGJAM targeted weak Diffie-Hellman.
The whole history of TLS attacks is basically "here's a way to abuse the flexibility we gave you" and TLS's response is always "ok we made the flexibility less flexible in that specific way."
Its high agility made hundreds of migrations painless. It's simple. But by God, it works.
“Hold my beer” - ZK rollups
A ZK rollup works like this: transactions happen offchain, a cryptographic proof is generated proving the transactions were valid, that proof gets submitted to an onchain verifier contract, then the verifier contract checks the proof and finalizes everything.
The security of the whole system rests on that verifier contract. All roads lead to the verifier.
Now the verifier contract is deployed onchain. It implements a specific proof verification system, be it Groth16, PLONK, or STARK, at the bytecode level. It is designed to be immutable, which is good for protocol security, but what if a component of your proving system needs to change?
Well, here's what that will look like:
Design and implement the new proof system
Get a security audit on the new verifier circuit (several months, $200K–$500K)
If you're Groth16-based, you need a new trusted setup ceremony. So, weeks of coordination across multiple independent parties who each generate and then destroy secret randomness (but this probably won’t happen in the next migration, but that’s for another post)
Deploy the new verifier contract to L1
Run a governance process to update the bridge to recognize the new verifier
Migrate all your prover infrastructure to produce proofs under the new system
Figure out what to do with every proof ever submitted under the old system, because the new verifier cannot verify them and you kind of need to be able to validate historical state??
Pray
No major ZK rollup has completed a full proof system migration in production. As in, it has never happened. We're not talking about something that's been done a few times slowly but something that has never been done once.
The algorithm in this case, lies in the contract, which is in the execution layer. Unfortunately the execution layer was designed to be immutable.
But should you move verifiers outside contracts?
The reason ZK rollups ended up like this is not stupidity. It's tradeoffs.
You want onchain verification because it gives you trustless finality. Any full node can verify the proof independently. Nobody has to trust the rollup operator, and that’s the whole point. Moving verification offchain or behind an abstraction layer reintroduces trust assumptions that ZK rollups were specifically designed to eliminate.
The cost of that decision is that the algorithm is baked in. It seemed worth paying at the time, and honestly, for the goals of the system, it kind of was? They were solving a scalability problem, not planning for a 30-year cryptographic lifecycle.
But when you look closely at why ZK circuits are so hard to migrate, there are actually two different problems bundled together. So don't mix them up or it will lead to bad conclusions.
Problem one: architectural rigidity. This is fixable.
The verifier contract being the migration bottleneck is a design choice. A danki suggestion: build a verifier registry onchain that maps proof system identifiers to verifier contract addresses, and have the bridge call the appropriate verifier per batch. This separates what is being verified from which algorithm does the verifying. You keep trustless onchain verification but add algorithmic flexibility above it.
Now the absence of a specified transition protocol for historical proofs is also just a thing nobody has written down yet. When you migrate from Verifier A to Verifier B, what happens to proofs submitted under A? How long does the old verifier stay callable? What's the sunset timeline? The problem is known in the engineering community. The specification does not exist. But I believe it's fixable.
Problem two: mathematical rigidity. This is not fixable with engineering.
A ZK circuit is a constraint system defined over a specific finite field. The field is not a parameter. It is present in every single constraint in the circuit A circuit built for the curve BN254 like the ones used in Groth16 and PLONK, does not call BN254. It exists in the algebraic universe defined by BN254's scalar field.
Every field arithmetic operation is an expression in that universe. Every hash gadget is optimized for that field. Every elliptic curve operation is defined by that curve.
If you want to migrate to a different algebraic universe say, one that isn't broken by Shor's algorithm. You're gonna have to rewrite every constraint in the circuit from scratch. The field size determines the size of every arithmetic operation. The hash function determines the structure of every Merkle proof gadget. Dis, you can’t parameterize.
Making ZK circuits algebraically agnostic isn't an engineering sprint. It's an open research problem. The answer to "how do you fix ZK's mathematical rigidity" is not at all "better refactoring", it's "what would a proof system designed for agility even look like." Nobody has built that in production. It's an active research area.
As I’ve said, this distinction matters: if you're a rollup team and you conflate the two, you either get false confidence ("we can just upgrade the contract, it'll be fine") or false despair ("cryptographic migration is impossible for us"). Neither is true. The architectural stuff is fixable now. The mathematical stuff requires a different kind of work.
Actually the scarier problem is your Ethereum address
Your Ethereum address is computed like this:
address = keccak256(pubkey)[12:]
Take not that your address is a hash of your public key. The identity is derived from the cryptographic primitive.
In TLS, your identity lives in a certificate. Your certificate gets reissued when you migrate to a new algorithm but your organizational identity stays the same. The primitive merely attests to the identity but it doesn't constitute the identity.
In Ethereum, the primitive is the identity. If you migrate from ECDSA to a post-quantum signature scheme, you generate a new keypair, which gives you a new address. That new address is a clean slate without your old token balances, history, binded identity, nothing.
For a regular user this is already bad. For a smart contract it's worse: a contract's address is derived from its deployment transaction. You literally cannot change it without redeploying, and redeployment does not inherit state.
And the migration paths that currently exist for Ethereum's quantum vulnerability:
Account abstraction (EIP-7702) lets your account verify post-quantum signatures. Great! But your address is still derived from an ECDSA key. The quantum vulnerability in the identity layer is untouched. I don't have a proposed solution for this yet, but give da danki some time.
New precompiles for ML-DSA / SLH-DSA lets smart contracts call PQC verification natively. Also great! But the address is still ECDSA-derived. So, also unresolved.
Protocol-level hard fork replacing ECDSA is the only option that actually solves it. If addresses derive from PQC keys, the identity coupling problem is gone.
But a caveat: this would be the most expensive migration event in Ethereum's history. Because you’d be coordinating a validator-level hard fork that affects every single Ethereum user. And there is no ratified specification for how the transition would work. If Ethereum picks this path they need to answer questions like:
What's the dual-acceptance window?
What's the ECDSA sunset timeline?
What does account migration look like?
And if you're choosing this path, the time to specify the transition protocol is now, even though execution is years away. A specification is cheap. A specification during a crisis with a shortened quantum timeline is not. If quantum computers arrive faster than expected and the spec doesn't exist, the coordination problem becomes very difficult under time pressure.
So what do you actually do
If you are building something that needs to survive longer than three years:
Don't put your cryptographic primitive at the execution layer. Put it where negotiation happens. If you're building a ZK protocol, think about the verifier registry early. Way easier to design in than to bolt on after the fact.
Write down your state continuity protocol before you need it. What happens to your historical cryptographic artifacts when you migrate? Where does the old verifier live? What's the sunset? These things are easier to specify in advance but it could f- things up to retrofit during a migration event.
Know what primitives your system depends on and where. In ZK circuits specifically, the dependencies are often invisible at the API level and pervasive at the constraint level. This is the kind of thing you'd want to enumerate before you start planning a migration, not during one. Tooling for this barely exists, so if you're working on ZK you might want to think about it now.
Take harvest-now-decrypt-later seriously. Danki was hacked last week. By a RAT. And… nothing happened. Which made me think about schemes like this. Have they copied my hot wallet vault? Well it doesn't matter coz I'm comparatively too broke for this effort. But for escrows, governance, vesting contracts… it will be very worth it.
Know whether your problem is architectural or mathematical. Because the response to each is completely different. One is a sprint. One is a research program.
+++++++++++++++++++++++
The thing that keeps me up about this — and I promise I have other things that keep me up, I'm not that far gone — is that the infrastructure we've been building for the last five years was optimized for the right things. Correctness. Performance. Trustlessness. Those are genuinely the right things to optimize for.
But there’s tradeoff between "the system is maximally correct right now" and "the system can survive being wrong about what correct means in ten years." And that tradeoff was often not made explicitly. It was made by default, so maybe it’s time to be explicit about this.
After all, you don't find out how agile your system is when everything works. You find out the moment you have to change it.

