EIP-7503: Zero-Knowledge Wormholes - Private Proof of Burn (PPoB)

Private Proof of Burn (PPoB)

By @keyvank and @irnb

While researching on privacy solutions and applications of ZKP, we discovered a technique, by which people can burn their digital asset (E.g ETH) by sending it to an unspendable address, and later build a ZK proof showing that some amount of tokens has been burnt in a transaction in an older block, without revealing the transaction. Why is it important? People can do plain EOA-to-EOA transfers which privately have impact in some other verifier smart-contract on the system.

Recap on Elliptic-Curve digital-signatures:

In Elliptic-Curve based digital signatures, normally there is a secret scalar $s$, from which a public-key is deriven (By multiplying the generator point with the scalar: $s \times G$)

A public-key is spendable if and only if its corresponding private-key $s$ exists. We can generate unspendable public-keys by generating random points on the curve. But how can other people be sure that a point is indeed random and not the result of calculating $s \times G$? We can generate points that are very unlikely to be spendable by using fancy-looking patterns in their $x$ coordinate. E.g: In case of Secp256k1 we can pick $x=123456789$ and calculate $y$ by putting it in the curve equation:


Because of the discrete logarithm problem, it’s practically impossible to calculate $s$ where $s \times G$ is equal with our point.

Let’s say $R$ is an unspendable public-key (Let’s call it the reference unspendable public-key). People can publicly burn their tokens by sending them to $R$, after doing so, others can indeed conclude that they have burnt their tokens, because they can all see the transactions and they know that $R$ is unspendable.

We can derive infinitely many provably-unspendable public-keys from a reference unspendable public-key

Let’s pick a random secret value $t$ and calculate a new point $D=R + t \times G$. We can prove that $D$ is also unspendable, because $log_G(D)=log_G(R + t \times G)=log_G(R) + t$, and since we can’t calculate $log_G(R)$, the public-key $D$ is also unspendable.

Obviously, $D$ is a completely new point that does not seem unspendable. We can convince others that $D$ is unspendable by revealing $t$, because then people can verify that $D$ is the result of adding some other point to $R$.

Using the help of Zero-Knowledge proofs, we can hide the value of $t$

We just need to prove that we know a secret value $t$ where $R + t \times G == D$. We can go even further. Given that we have access to the previous block hashes in our Ethereum smart-contracts, we can prove that some EOA-to-EOA transaction has happened in the previous blocks, burning some amount of token (It actually doesn’t need to be an EOA-to-EOA, and it also could be a ERC20-transfer).

Are there any applications?

We honestly are not sure whether there is an application for such a proof, but here are some random thoughts:

Imagine there is a ZKP verifier contract that verifies if someone has burnt some amount of USDT in the previous blocks (Nobody can’t detect that since it’s a very normal looking ERC-20 USDT transfer). Imagine we mint an equal amount of BUSDT (Burnt/Backed USDT?!) in case someone proves that he has burnt USDT (We prevent minting the same burnt coins again using the help of nullifiers). The number of BUSDTs in circulation will be equal with burnt USDTs and no one can find out the burners of those USDTs (Unless their reveal their secret $t$). So we can claim that BUSDT is secretly backed with USDTs, and thus backed with actual USD, with the difference that it can’t be frozen by the company behind the stablecoin.

Call-free Smart-Contract interactions

We can further extend the idea behind PPoB to support general-purpose smart-contract interactions. Suppose $m=hash(msg)$ is a message we want to send to a smart-contract, without ever calling it. We can add $m$ to our private key and send our funds to the message’s corresponding public-key: $g^{s+m}$

Later we can make a ZK proof that a transaction has happened, from an account that has $b$ amount of tokens, shouting the message $m$. $m$ can be a vote.

This way we can build contract-call-less votings/DAOs (Or anything similar), which anyone on Ethereum can participate in, without revealing their identities, just by doing normal-looking EOA-to-EOA transactions.

The message $m$ can be the calldata of a contract function.


This approach could lead to increased trust in stablecoins, as it provides a means of verifiable backing without relying on a centralized authority. This is brilliant.

1 Like

Exactly, but unfortunately, it’s a one-way cryptographic wormhole. The secondary token can never be converted back to the original token. (It’s like privately moving your asset to another universe, and there is no way back)

1 Like

I think the applications are yet to be fully contemplated, but IMO the USDT-BUSDT example is not a good one; since the BUSDTs are not redeemable, and also can not be transferred back to USDT (so that again be redeemable), and this renders them worthless.

1 Like

While I would rather see this as part of the base layer, one could create a WETH contract where withdraws required a proof of WETH burn to redeem for ETH, rather than returning the original WETH token(s).

This would be far less useful though as it is quite uncommon for people to send anything other than ETH to an otherwise empty account. Since you need gas to do anything, ETH is always the first (and sometimes only) thing sent to a new address.

1 Like

“we can prove that some EOA-to-EOA transaction has happened in the previous blocks”
How to prove ? Using EOA’s signature ?

1 Like

Given that we have the block-hashes of the previous blocks in EVM, we can feed it as a public-input to a ZK circuit, which verifies a Merkle-Patricia-Trie proof (Of the transaction-tree), convincing us that a specific transaction has been included in a block (Without showing the TX). We can additionally check the Tx’s signature but that’s not necessarily needed, since a transaction is only included when its signature is valid.

But how do ChainB know the previous block of ChainA, you can prove the tx is included in the block, but how to prove in ChainB that the block of ChianA exist indeed?

We currently only have the last 128 blockhashes in the EVM. There is a stagnant EIP somewhere that proposes storing all blockhashes in state, which would be necessary for this to work. Presumably if this went through then that EIP also would go through as a dependency.

This proposal is for within Ethereum only, not for cross-chain transfers. You burn some ETH on Ethereum, and then later you can mint an equivalent amount of ETH on Ethereum. The cleverness of this solution is that all accounts with ETH in them and no transactions are part of the anonymity set until the ETH moves.

1 Like

One downside of this strategy is that the anonymity set shrinks over time. If you mint at block 20,000,000, then your anonymity set is all accounts with ETH and no transactions where the ETH was transferred into the account after this change goes live and before block 20,000,000. However, over time the set of accounts where the ETH doesn’t move will trend towards only those which were actual burns, thus your anonymity set ends up (eventually) being similar to contract layer tools like Tornado.

The one exception is ETH that is mistakenly sent to a wrong address (e.g., typo). This ETH will stay in your anonymity set forever. Unfortunately for this protocol (and fortunately for everyone else) the number people who accidentally burn their ETH by sending to a non-existent account is quite small. Losing private keys is slightly more common, but still pretty rare and such accounts usually have transactions.

That being said, this protocol still provides some amount of plausible deniability in that you can claim that ETH you burned was either sent to a wrong address, you lost the keys, or you have the keys but are unwilling to share them. Unlike Tornado, burning your ETH through this protocol doesn’t give away that you used the protocol at all. Only withdrawing proves that you used the protocol in the past.

1 Like

If this is going to be implemented on the base layer, then I think the best option is to not rely on EVM-providen roots, and build and maintain an additional tree with a ZK-friendly hash function on Ethereum clients.

This is actually very convincing and sad, I thought the anonymity set would be bigger.

1 Like

I agree it is unfortunate. The plausible deniability is still incredibly valuable though. You don’t get that with tools like Tornado.

1 Like