You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

85 lines
4.4 KiB

3 years ago
  1. # miksi [![Test](https://github.com/miksi-labs/miksi-core/workflows/Test/badge.svg)](https://github.com/miksi-labs/miksi-core/actions?query=workflow%3ATest)
  2. Ethereum zk mixer where all the computation & constructions are done offchain and then proved inside a zkSNARK to the smart-contract (both to *deposit* and *withdraw*).
  3. ## Overview
  4. *From Esperanto, **miksi** (miks·i): to mingle, to blend, to mix, to shuffle*
  5. The client builds a MerkleTree, carries out the required computation, and then generates a zk-proof proving that the offchain computation has been done correctly (no leaf deletion, and only one correctly formatted leaf addition).
  6. This approach requires only `~325.000 gas` to *deposit* (compared to `~1M gas` for an onchain computation approach) , and `~308.000 gas` to *withdraw*.
  7. These gas savings come from the fact that we don't need to carry out the MerkleTree computations onchain. Instead, we prove the correctness of these offchain computations inside the snark proof, and verify this proof onchain. It's much cheaper to verify the proof than to carry out the necessary computations onchain.
  8. ![](miksi-logo00-small.png)
  9. **Warning:** This repository is in a very early stage. The current version works, but is not finished. There are some improvements in the works.
  10. The WebApp to use miksi-core can be found at https://github.com/arnaucube/miksi-app, and a live-demo with the smart contract deployed at Goerli Ethereum testnet can be used here: https://arnaucube.github.io/miksi-app/
  11. ## Run
  12. - Circuits tests
  13. ```
  14. npm run test-circuits
  15. ```
  16. - Smart Contracts tests
  17. ```
  18. npm run test-sc
  19. ```
  20. - javascript lib tests
  21. ```
  22. npm run test
  23. ```
  24. - Compile circom circuit & generate Groth16 verifier contract
  25. ```
  26. ./compile-circuits.sh
  27. ```
  28. ## Spec draft
  29. **Note:** Both the spec and the code are works in progress. There are some pending improvements in the works, and some diagrams are needed to better explain things.
  30. ### Deposit
  31. *All computations and constructions are done offchain and then proved inside a zkSNARK to the smart-contract*
  32. From the depositer's perspective, the interface facilitates the following flow:
  33. 1. Generate a random `secret` & `nullifier`
  34. 2. Compute the `commitment`, which is the Poseidon hash: `commitment = H(coinCode, amount, secret, nullifier)`, where:
  35. - `coinCode`: code that specifies which currency is being used (`0`==ETH)
  36. - `amount`: the amount to be deposited
  37. - `secret`: random, private
  38. - `nullifier`: random
  39. 3. Fetch all the commitments from the smart-contract
  40. 4. Build the MerkleTree with the fetched commitments
  41. 5. Add the newly computed `commitment` to the MerkleTree
  42. 6. Generate a zkSNARK proof, which proves:
  43. - you know the `secret` & `nullifier` for the `commitment` contained in the leaf you've just added to the MerkleTree
  44. - the transition from `RootOld` (the current one in the smart-contract) to `RootNew` has been done following the rules (no leaf deletion, and only one correctly formatted leaf addition, etc.)
  45. 7. Send ETH to the smart-contract `deposit` call, together with the zkProof data
  46. Once these steps have been carried out, the smart-contract verifies the zkProof of the deposit, and if everything checks out ok, stores the commitment and the new root.
  47. The deposit circuit can be found [here](https://github.com/miksi-labs/miksi-core/blob/master/circuits/deposit.circom).
  48. ### Withdraw
  49. *As before, all computations and constructions are done offchain and then proved inside a zkSNARK to the Smart Contract*
  50. From the withdrawer's perspective, the interface facilitates the following flow:
  51. 1. Fetch all the commitments from the smart-contract
  52. 2. Build the MerkleTree with the fetched commitments
  53. 3. Generate the siblings (merkle proof) for the `commitment` whose `secret` & `nullifier` you know
  54. 4. Generate a zkSNARK proof, which proves:
  55. - you know a `secret` for a `nullifier` you reveal, whose `commitment` is in a MerkleTree with `root` matching the one stored in the smart-contract
  56. If the zkProof verification passes, and the nullifier has not already been used, the smart-contract sends the ETH to the specified address.
  57. The withdraw circuit can be found [here](https://github.com/miksi-labs/miksi-core/blob/master/circuits/withdraw.circom).
  58. # Thanks
  59. Miksi is made possible thanks to [circom](https://github.com/iden3/circom), [circomlib](https://github.com/iden3/circomlib), [wasmsnark](https://github.com/iden3/wasmsnark), and the ideas developed in the [Zexe paper](https://eprint.iacr.org/2018/962.pdf).