miksi 
From Esperanto, miksi (miks·i): to mingle, to blend, to mix, to shuffle
Ethereum mixer where all the computation & constructions are done offchain and then proved inside a zkSNARK to the Smart Contract (for the deposit and for the withdraw).
This means that the client builds a MerkleTree and makes all the needed computation, and then generates a zk-proof where proves that all the offchain computation is done following all the rules (no leaf deletion, only one leaf addition, correct leaf format).
This allows to use only ~325.000 gas for the deposit, and ~308.000 gas for the withdraw.
Warning: This repository is in a very early stage. The current version works, but is not finished and there are some improvements to be added.
WebApp to use miksi-core can be found at https://github.com/arnaucube/miksi-app
Circuits tests
npm run test-circuits
Smart Contracts tests
npm run test-sc
Compile circom circuit & generate Groth16 verifier contract
./compile-circuits.sh
Spec draft
Note: The spec & code is a work in progress, there are some pending works & improvements planned to do, and some diagrams for better explanation.
Deposit
All computation & constructions are done offchain and then proved inside a zkSNARK to the Smart Contract
- user generates a random
secret&nullifier - computes the
commitment, which is the Poseidon hash:commitment = H(coinCode, amount, secret, nullifier), where:coinCode: code that specifies which currency is being used (0==ETH)amount: the amount to be depositedsecret: random, privatenullifier: random
- get all the commitments from the SmartContract
- build the MerkleTree with the getted commitments
- add the new computed
commitmentinto the MerkleTree - generate zkSNARK proof, where is proving:
- prover knows the
secret&nullifierfor thecommitmentwhich is in a leaf in the merkletree - the transition from
RootOld(the current one in the Smart Contract) toRootNewhas been done following the rules (only one leaf addition, no leaf deletion, correct leaf format, etc)
- prover knows the
- user sends ETH to the smart contract
depositcall, together with the zkProof data - smart contract verifies the zkProof of the deposit, and if everything is ok stores the commitment & the new root
Deposit circuit can be found here.
Withdraw
All computation & constructions are done offchain and then proved inside a zkSNARK to the Smart Contract
- user gets all the commitments from the SmartContract
- build the MerkleTree with the getted commitments
- generate the siblings (merkle proof) for the
commitmentof which the user knows thesecret&nullifier - generate zkSNARK proof, where is proving:
- user knows a
secretfor a publicnullifier- whichcommitmentis in the MerkleTree - which MerkleTreerootis the one that knows the SmartContract - if the zkProof verification passes, and the nullifier was not already used, the Smart Contract sends the ETH to the specified address
Withdraw circuit can be found here.
Thanks
Miksi is possible thanks to circom, circomlib, wasmsnark, and thanks to the ideas about offchain computation validated with a zkSNARK in the Zexe paper.
