Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Implement the withdrawDeposit function in the Mixer contract #2

Open
AntoineRondelet opened this issue Jun 27, 2018 · 9 comments
Open
Assignees

Comments

@AntoineRondelet
Copy link
Owner

No description provided.

@AntoineRondelet
Copy link
Owner Author

[WIP]
This function has been implemented as forward (echoing the fact that the recipient does not withdraw his funds, but instead, provides a proof showing that he knows the secret to compute one "unspent" commitment in the tree, to create another payment for someone else).

Further testing on the forward function is required before closing this issue...

@AntoineRondelet AntoineRondelet self-assigned this Jul 4, 2018
@barryWhiteHat
Copy link

Ping me when you have described this a little more ;-)

@AntoineRondelet
Copy link
Owner Author

Here is a bit more information about it @barryWhiteHat :)

If Bob "receives Alice's payment" (he can withdraw from the tree), but would like to pay someone through the Mixer without depositing one ether; he can "forward" Alice's payment to someone else. By doing so, he needs to provide a proof (like a normal withdrawal), but also, a new commitment to insert in the tree. Instead, of being credited of 1ether, the proof is verified, and the new commitment is appended to the tree ONLY IF the proof is valid. He has now "spent" his commitment (the corresponding nullifier has been revealed), in order to append a new leaf in the Merkle Tree.

The idea is to avoid to withdraw, and then deposit in case where Bob knows the secret of a an "unspent commitment in the tree" (for which the nullifier has not been revealed)

@HarryR
Copy link

HarryR commented Jul 10, 2018

The longer the value stays within the contract the more secure it is IMO, think of it as a single step WithdrawThenDeposit, so internal transfers can be made without revealing the identity of either party?

Some background notes from me on another project: clearmatics/mobius#15

@AntoineRondelet
Copy link
Owner Author

AntoineRondelet commented Jul 10, 2018

If we have:

  • Alice doing a deposit to append a commitment for Bob in the three (-1 ether on her balance, +1 on the contract balance)
  • Bob receiving the secret and having the nullifier, from Alice (assuming a secure channel)

If Bob; wants to pay Charlie 1ether, then he doesn't have to proceed to a desposit, he can just use the fact that he possess the information required to generate a proof that he "controls" a commitment in the three binded to an unspent nullifier.
By calling the "forward" function he can pay Charlie appending a new leaf in the tree.

The idea is just to avoid modifying the public balances too often (if we can get rid of these -1ether on sender balance, +1ether on contract's balance during deposit, and -1 contract balance, +1 recipient balance, I think it'd be better, as we'd remove one source of leakage of information)

so internal transfers can be made without revealing the identity of either party?

Hum... the sender needs to call the contract from a founded address so, his identity is still going to be leaked (we'll know that Bob did a payment to someone because his address called the "forward" function). Moreover, looking at the ways the nullifiers are generated for now (addressReceiver || salt), when Bob calls the "forward" function to pay Charlie, his discloses the nullifier that basically leaks his identity. Furthermore, Alice, who has appended the commitment in the merkle tree to pay Bob, also knows the salt of the nullifier, so she knows that Bob is paying someone using the payment he received from her (however, she can't track further because she didn't generated the nullifier for Charlie).

I guess the solution to this problem would be to generate commitments and nullifiers like they do in ZeroCash: The creation of the commitment takes the recipient's public key as argument so that sender can create a new coin for the recipient (by "binding" it to its public key), but, the nullifier is only computable by the recipient, by using a PRF (PRF(sk, randomness)). That way Alice should not be able to track when Bob "forwards" her payment to someone else because she has no way to generate the nullifier.
Doing so would require quite some new stuffs in the code base however..

@HarryR
Copy link

HarryR commented Jul 10, 2018

There are 3 problems I'm thinking of:

  1. Hiding total values, e.g. so you cannot see transfer of value on a ledger, only total input and total output from the bubble of secrecy
  2. Hiding the actors submitting the transactions, so you cannot correlate events by the same person (working on solution for this at the mo using Whisper, alternatively waiting for account abstraction)
  3. Protocol doesn't leak long-term keys of each participant in any public information

The idea is just to avoid modifying the public balances too often (if we can get rid of these -1ether on sender balance, +1ether on contract's balance during deposit, and -1 contract balance, +1 recipient balance, I think it'd be better, as we'd remove one source of leakage of information)

Yup, the forward function does this 👍 It means you don't have to bounce ether into a real account then back into the mixer.

That solves problem 1.

Moreover, looking at the ways the nullifiers are generated for now (addressReceiver || salt), when Bob calls the "forward" function to pay Charlie, his discloses the nullifier that basically leaks his identity.

This could be any key that Bob controls, not just his permanent / long-term address, as long as he can supply a signature from that address that verifies to the same address via ecrecover.

e.g. instead of supplying the nullifier (address || salt) you provide the salt and the (v,r,s) components of an ECDSA signature, then the nullifier is constructed using the address that ecrecover returns.

That kinda solves problem 3 and you end up with a coin that only the owner of that one-time-key can spend.

@HarryR
Copy link

HarryR commented Jul 10, 2018

But what if you wanted to use denominations that aren't 1 ether? e.g. you can deposit any amount, transfer any amount to anybody, and withdraw any amount?

That would require coin splitting, and coins of arbitrary value, where the values aren't known when being transferrer around - only that the sum of (inputs-outputs) >= 0.

@barryWhiteHat
Copy link

I think if we want to provide private transactions of arbitrary size we need to move off chain. Otherwise it will be too expensive for the majority of people to use. Since we can use snarks to do confirm multiple transfers in a single transaction. It seems like a really nice way to encourage widespread adoption of private transactions.

That is my current research goal. I think that miximus is good to provide on chain anonymous coins, id and signals. But in order to get any kind of adoption and there for reasonable anonymity set we need to move off chain.

@barryWhiteHat
Copy link

Also sorry for my delayed response. I have just been super busy.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

3 participants