Zether is a work of Benedikt Bünz, (one of the author Bulletproofs paper), Dan Boneh and folks from Visa Research. This post is meant to give an overview of Zether without going into the math. I will try to write a follow up post with another interesting topic from this paper called Σ-Bullets.
Zether is a confidential (transaction amounts are hidden) and anonymous (transaction sender and receiver are hidden) payment mechanism on blockchains with the account model like Ethereum. Zether is implemented as a smart contract called Zether Smart Contract (ZSC) and has a token called Zether token (ZTH) that is transferred between Zether accounts which are ElGamal public keys. Thus Zether can be seen as a cryptocurrency deployed in an Ethereum smart contract ZSC with ZTH being the coin and the addresses being ElGamal public keys.
Existing payment mechanisms providing confidentiality and anonymity like Zcash, Monero, etc are based on the UTXO model. In their transactions, the sender creates a homomorphic commitment to the amount and also sends the opening of the commitment but is encrypted to the receiver as part of the transaction. In Zether, the amount is encrypted using (a variation of) Elgamal encryption and a proof is added to the transaction proving that the sender is doing a proper fund transfer (more on that later).
On a high level this is how a user interacts with Zether. Alice with Ethereum address
A creates an Elgamal key pair, (
pk) and sends a transaction enclosing
pk and depositing some ether in ZSC. ZSC will now create an account
pk with the equivalent amount of ZTH . Now Alice can send ZTH confidentially and anonymously to any other Zether account. To hide the amount Alice encrypts it. To hide her account (public key), Alice selects a set of other Zether accounts called anonymity set and hides her account in this set. To the blockchain, it looks like one of the accounts from that set made a transaction with hidden amount. Alice can also convert her ZTH tokens back to ether.
- Fund transaction. Used to fund a Zether account by depositing ether and specifying a Zether account (Elgamal public key). Anyone can fund a Zether account and fund repeatedly.
- Transfer transaction. Used to transfer ZTH from Zether account to another.
- Burn transaction. Used to convert all the ZTH associated with a Zether account back to ether in an Ethereum address.
- Elgamal encryption. An asymmetric encryption scheme. Secret key
skand public key
gˢᵏ. To encrypt message
m, choose a nonce
r, the ciphertext is (
m.pkʳ). To decrypt, compute
(gʳ)ˢᵏand divide by
m.pkʳto get the messsage
However, in Zether, to make this encryption additively homomorphic, the message is made the exponent, making the ciphertext (
gᵐ.pkʳ). It might seem that this makes decryption infeasible as
gᵐhas to be brute-forced but the decryption is only done by the recepient and the recepient will know the amounts being sent to him and thus have some idea of his balance. Thus decryption is not trivial but not too expensive either.
- Epoch. A setup parameter to have a notion of time, consists of
Some key ideas
- Pending incoming txns. In a UTXO model, every UTXO is like a coin and can be spent independently of other UTXOs as the blockchain can check whether the UTXO is spent or not. But in the account model, for transactions spending from an account, the blockchain needs to check whether the account has sufficient balance for the transaction. But if the transaction amount is hidden (and so are account balances), the blockchain needs a proof that the account has the sufficient balance. The proof that is given by the sender say Alice, corresponds to a particular state of her account. But what if Alice prepared a proof corresponding to her account state
ato be sent with her transfer transaction but before her transaction could get processed, Bob sent some money to Alice changing her account state to
b. When the blockchain processes Alice’s transaction, the proof will be invalid as her account state has changed. Zether handles this by not updating the receipient’s balance immediately but keeping all incoming transfers in a pending state which are eventually rolled over into the receipient’s account. Thus Zether keeps a pending txns queue for each account where it stores the incoming txns for that account.
But when should this rollover happen? Since there is no way to periodically trigger actions in smart contract, someone has to trigger this rollover and pay the fees. In Zether, the recepient triggers the rollover when it tries to do a transfer or burn transaction. So if Alice and Carol both sent ZTH to Bob, the transactions will stay in the pending state (and Bob’ account balance won’t change) unless Bob tries to send ZTH to someone or convert ZTH to ether through a burn txn.
- Replay protection with nonce. To avoid the proof being resused from a transfer transaction, the proof must contain a nonce. Ethereum implements this with associating a counter with each address and this counter serves as a nonce in a txn and increases with each txn by the address. This does not work with Zether as the if the sender changes nonce of its account only than it would differentiate the account in the anonymity set. And the sender cannot change the nonce of other accounts. Zether again uses zero knowledge proofs here; First each epoch is assigned (by the protocol) a base, say
h, the sender then uses the nonce
hˢᵏand proves that he has used a correct nonce for this epoch by proving knowledge of
hchanges with each epoch. A downside of this is that the sender can only send 1 transaction per epoch (she can receive more than one).
Overview of transactions
Say Alice, with account
P wants to send amount
x to Bob with account
- Confidential transaction. Alic encrypts the amount
xfor both public keys
C2and proves: i) Both
C2are valid ciphertexts and both encrypt
xis a positive value and in a range (doesn’t overflow) and iii) The remaining balance of
Pis positive and in a range.
The smart contract will then use
C2to update the balance of
- Anonymous transaction. Alice selects an anonymity set of
Q). Shen then rolls over the pending txns of all
naccounts before creating a proof so that the proof is created corresponding to the latest balance of accounts. The rollover needed to create the proof does not need a txn as Alice can query the contract for pending roll-overs and compute the rollover locally. The proof will fail if before this txn gets processed, anyone of the
naccount receives a txn thus changing their pending txn queue.
She then creates
C1, C2,…Cnof their balances (post roll-over) and proves: i) All
C1, C2, ..Cnare valid ciphertexts with one of them encrypting
x, one of them encrypting
-xand rest encrypting 0. ii)
xis positive and in a range. iii) The remaining balance of the ciphertext encrypting
xis positive and in a range. iv) A valid nonce is used.
The smart contract will then use the ciphertexts
C1, C2,…Cnto update the
naccounts. Balance of only 2 accounts will change as rest of the ciphertexts encrypt 0.
- A major limitation of Zether is that since every Ethereum transaction requires gas and gas can only be paid in Ether and by an Ethereum address, Zether transactions by the same Ethereum address are linked. One solution is that users should not reuse Ethereum addresses but this is cumbersome. Another option is user sending a txn with 0 gas price and miners charging fees in ZTH.
- Another challenge is ensuring that the transaction does get processed at the end of the current epoch since proofs are created corresponding to the balance of the current epoch. This can be difficult in a busy network.
- Similarly, during anonymous transfers, the sender needs to ensure that none of the accounts in the anonymity set receive a transfer in the current epoch.
The code for Zether (written by one of the paper authors) lives here and has tests though the Solidity code for smart contracts is missing. The authors however mention that they have implemented such a contract and mention gas cost, txn size, etc of various smart contract methods.