I am a user, I want to use Miximus, I have tokens or Ether which I want to convert into anonymised tokens. How do I do this?
Once my tokens have been anonymised I need to withdraw them again, to convert them back to the original tokens or Ether that I originally deposited. I should also be able to give these anonymised tokens to other people, without revealing that it was I that deposited them. As a user, should it be possible to lose access to my anonymised tokens even though I still have the private key for my Ethereum account?
We need to make a proof of concept application which uses Miximus and allows users to do common tasks, like deposit, withdraw, transfer etc.
There is JavaScript code which uses node-ffi and web3 to perform deposits/withdraws: https://github.com/HarryR/ethsnarks-miximus/blob/master/solidity/test/TestMiximus.js
And Python code to use the native module to create proofs: https://github.com/HarryR/ethsnarks-miximus/blob/master/python/test/test_miximus.py
Using either of these, can a proof-of-concept application be created that allows people to use Miximus more easily?
How does this work as a command-line application?
The command-line app needs to connect to an Ethereum full node, it needs to store state, provide a mechanism for converting currency into anonymised tokens, and provide a mechanism for converting the anonymous tokens back in to the original currency.
e.g.
$ miximus deposit 10 ETH
- Deposited
$ miximus balance
- 10 ETH
$ miximus send 5 ETH <my-friend>
- Sent
$ miximus balance
- 5 ETH
Then as
$ miximus balance
- 3 ETH
$ miximus withdraw 3 ETH
- Withdrawn 3 ETH
$ miximus balance
- 0 ETH
Then as me again:
$ miximus withdraw 5 ETH
- Withdrawn 5 ETH
$ miximus balance
- None
There is a problem with this 'ideal user flow' - at any given point in time you know exactly what your balance is, you can send money to others, and withdraw an arbitrary amount. This matches the account model of Ethereum (and most other wallets) by creating a useful abstraction regardless of the number of underlying transactions, for example with Bitcoin you have N UXTOs which represent your balance.
This makes anonymity difficult because with a UXTO model your account can be correlated to determine the exact value of a transfer - e.g. if I do 10 transactions with a fixed coin size of 1ETH then 'they' know I'm sending 10 ETH to somebody.
Technical Challenges
How do you have an account-style model with anonymous tokens?
Following on from ZCash you need a split and join circuit, in addition to an arbitrary value for the transactions.
For example, you deposit 10 ETH, you now have a single token worth 10 ETH. You can then transfer 5 ETH to a friend by using a 'split transaction' where you take a single input and output two new coins. To receive the coins you need to use a Join transaction to combine your current balance with the new input. If 100 people send coins to you, you'd need to perform 100 join transactions to collect it all into a single account.
The alternative is a UXTO model where your available funds exist as separate coins, however in that case if you had denominations of 0.3, 0.5 and 0.2 you'd have to create a join transaction with 3 inputs and 1 output. This becomes a problem when the circuit is of a fixed size.
Compromise between usable and perfect
In a perfect world the zkSNARK circuit could join an unlimited number of inputs into an unlimited number of outputs, this is technically possible if you were to process the merkle tree update for spendable coins within the circuit - but that limits everybody to 1 transaction per block otherwise everybody else gets rejected due to conflicts.
What is the worst case though?
I am a user, I want to use Miximus, I have tokens or Ether which I want to convert into anonymised tokens. How do I do this?
Once my tokens have been anonymised I need to withdraw them again, to convert them back to the original tokens or Ether that I originally deposited. I should also be able to give these anonymised tokens to other people, without revealing that it was I that deposited them. As a user, should it be possible to lose access to my anonymised tokens even though I still have the private key for my Ethereum account?
We need to make a proof of concept application which uses Miximus and allows users to do common tasks, like deposit, withdraw, transfer etc.
There is JavaScript code which uses node-ffi and web3 to perform deposits/withdraws: https://github.com/HarryR/ethsnarks-miximus/blob/master/solidity/test/TestMiximus.js
And Python code to use the native module to create proofs: https://github.com/HarryR/ethsnarks-miximus/blob/master/python/test/test_miximus.py
Using either of these, can a proof-of-concept application be created that allows people to use Miximus more easily?
How does this work as a command-line application?
The command-line app needs to connect to an Ethereum full node, it needs to store state, provide a mechanism for converting currency into anonymised tokens, and provide a mechanism for converting the anonymous tokens back in to the original currency.
e.g.
Then as
Then as me again:
There is a problem with this 'ideal user flow' - at any given point in time you know exactly what your balance is, you can send money to others, and withdraw an arbitrary amount. This matches the account model of Ethereum (and most other wallets) by creating a useful abstraction regardless of the number of underlying transactions, for example with Bitcoin you have N UXTOs which represent your balance.
This makes anonymity difficult because with a UXTO model your account can be correlated to determine the exact value of a transfer - e.g. if I do 10 transactions with a fixed coin size of 1ETH then 'they' know I'm sending 10 ETH to somebody.
Technical Challenges
How do you have an account-style model with anonymous tokens?
Following on from ZCash you need a split and join circuit, in addition to an arbitrary value for the transactions.
For example, you deposit 10 ETH, you now have a single token worth 10 ETH. You can then transfer 5 ETH to a friend by using a 'split transaction' where you take a single input and output two new coins. To receive the coins you need to use a Join transaction to combine your current balance with the new input. If 100 people send coins to you, you'd need to perform 100 join transactions to collect it all into a single account.
The alternative is a UXTO model where your available funds exist as separate coins, however in that case if you had denominations of 0.3, 0.5 and 0.2 you'd have to create a join transaction with 3 inputs and 1 output. This becomes a problem when the circuit is of a fixed size.
Compromise between usable and perfect
In a perfect world the zkSNARK circuit could join an unlimited number of inputs into an unlimited number of outputs, this is technically possible if you were to process the merkle tree update for spendable coins within the circuit - but that limits everybody to 1 transaction per block otherwise everybody else gets rejected due to conflicts.
What is the worst case though?