benediamond / anonymous-zether

A private payment system for Ethereum-based blockchains, with no trusted setup.
Other
16 stars 9 forks source link

Replace Nonce with something better ? #10

Open jennilee78 opened 3 years ago

jennilee78 commented 3 years ago

Basically, the functionality required can be summed as tx can be built now, but can be released/mined few blocks later.This would avoid the issue of continuously of recreating transactions and retrying and so on.This may also be necessary considering network propagation of tx/blocks etc. This will also be necessary to bring anonymous-zether to better cope with real life conditions. Right now any tx not mined in the next block has to recreated which will cause major issues in real life conditions.

This functionality is, tx can be mined in later blocks till it can be proven that wallet has not sent any another tx. though it may have received x transfers. in other words, epoch based nonce should be replaced with something better.

The above functionality can be achieved via

  1. open nonce, however it has to provably reveal sender.
  2. open nonce, do not fully reveal sender, but reveal the entire sender ring cryptographically ( ) . we need to increment entire sender ring nonces. but this will fail if someone else chooses same sender ring member as your tx. decrease privacy by a bit, simple to implement but not many benefits. Though collision probability will be less if blockchain has large number of users.
  3. somehow implement it cryptographically. best way possible.
  4. maybe prove cryptographically that this sender ring has not sent any tx between the time it has been made and it has been mined in the blockchain. this can be based on current blockchain state and state when tx was built. this may be possible. may be easy
  5. maybe an encrypted nonce with nizk proof without decreasing privacy ( it needs to be somehow done in a ring, so we do not reveal sender, but it may not be compatible with current design) !!!! still digging.

Thank for help.

benediamond commented 3 years ago

tx can be built now, but can be released/mined few blocks later

this is already possible. it sounds like what you want is to increase the epoch length. have you tried that? see the number 6 here https://github.com/benediamond/anonymous-zether/blob/c342073fa00458f8b4f9cb014f6bd81539fca8fe/packages/protocol/migrations/2_deploy_zsc.js#L8-L14 this means the epoch length is 6 seconds. you can make it 60 seconds, or 1 hour. if you want, you can also make it block-based, instead of time-based—i.e., epochs will last 10 blocks (for example). in this setting you'll be able to construct a transaction now and then send it later (or more specifically, any time before the current epoch ends).

i'm not sure i follow your suggestions, but this issue seems essentially inherent, as it's necessary that the account state can't change between when the proof is generated and when the proof is verified. how else do you achieve that, than using epochs?

jennilee78 commented 3 years ago

Thank you for response.Sorry for not being clear. let me try again. Controlling epoch length is not the problem, it can be set to any duration. but epoch length controls how many tx, wallets can send.. It is unfortunately 1 in anon zether. means 1 tx per epoch time frame. this means if we set epoch to 1 hr, then any wallet can only send 1 tx per hour.

Please consider this case, a blockchain which uses block based epochs ( just like ethereum 15 secs block-time). Now, in this case, there are 2 limitations in anon-zether

  1. there can be 1 tx generated every 15 secs
  2. since a tx can be generated any time, as you can see, most of the txs would need to regenerated/retried by wallet ( since wallet may be late, tx generation take some time, tx propagation takes time, tx verification takes time and so on)

the second limitation can be removed, using some smart consensus rules or by using nonce smartly. of course, it will induce some overheads in blockchain or tx but user experience will be much better.

I would like to see the capability in anon-zether to be able to verify that the sender has not sent any tx in the last N epochs. the blockchain can then check the last N blocks whether the nonces have been used and confirm what the tx says. but this needs simplification if its going to be used in a blockchain.

Moreover, the account model of anon-zether is powerful and can be used in quite different ways in a native chain. Consider this eg. a blockchain running with 15s block time. The blockchain only allows tx generation from state which was say 50 blocks old. this will induce a limit that any new amount received will be spendable after 50 blocks, however the user may spend his 50 block balance anytime. The blockchain would verify tx against 50 blocks old state and after successful verification, mine it. This is possible is zether because the tx is just a statement of what is changing.

However, a blockchain may reorganize at any point in time, say a 3 block reorganize occurs. in anon-zether case, hell happens,, however this does not occur in BTC or ETH. i know they re not private but people expect the same behavior. This hell breaking loose can only be saved, if we introduce nonce in some smart way.

If i am not clear, please say it, so i can try again. Thank you.

benediamond commented 3 years ago

since a tx can be generated any time, as you can see, most of the txs would need to regenerated/retried by wallet

i disagree with this. a good implementation will inspect how much time (or blocks) is left in the current epoch, and decide whether to send now or wait. if it decides there's enough time in the epoch to safely send now and still make it, it will send now. otherwise, it will wait. In a good implementation, there should be almost never a need to retry, unless transaction acceptance times are extremely variable, the epoch length is short, and the wallet is aggressive.

I would like to see the capability in anon-zether to be able to verify that the sender has not sent any tx in the last N epochs.

It sounds like this should be possible, though I don't immediately see a way to do it.

but even if you achieved this, i still don't see exactly what it gets you. indeed i have to say that i am having a hard time following your proposal. for example, the sentences

sender has not sent any tx in the last N epochs

and

the user may spend his 50 block balance anytime

seem to contradict each other.

there may be a better way to do this, but it's a difficult problem, and i haven't thought about it much, and this is not my main project at the moment. if you have a detailed suggestion, maybe you can write it up and i can take a look.

jennilee78 commented 3 years ago

Hi, Thanks for your reply. Sorry for my bad english. Assuming anon zether is deployed as native protocol, I am trying to study methods which will work when blockchain reorganizes. for eg. if 10 block reorganization happens, currently almost all the transactions in 10 blocks will revert (which will have to be reissued by user). This problem doesn't affect ethereum. However, i would like to reuse maximum number of transactions. One of the fixes to the above problem is to attach plaintext nonces with each account. on committing a transaction, they increment only for all senders (sender ring may be odd or even). But will only decrease little privacy for senders , as anyone could see who may be senders and who may be receivers. But this method needs to reveal cryptographically senders position which may be odd or even.

Can we somehow reveal sender or receivers position. assuming tx contains 8 accounts, 4 are senders and 4 are receivers. we would like to cryptographically reveal, odd or even position and nothing more ?

Thank you.

benediamond commented 3 years ago

Can we somehow reveal sender or receivers position. assuming tx contains 8 accounts, 4 are senders and 4 are receivers. we would like to cryptographically reveal, odd or even position and nothing more?

i think what you want is to leak the secret "parity" of the senders' and receivers' indices. I think this CAN be done. before I talk about how though, I will say that I am still mystified about your idea. Let's say the 4 possible senders are revealed, and you increment a nonce for each one.

  1. what if I'm not the real sender, but my nonce is incremented? could that prevent me from submitting a transaction? could one user DOS other users by submitting empty transactions containing them in the ring?
  2. what will be the maximum allowed nonce? 1 or something higher? if it's higher than 1, then how do you prevent people from overdrawing? the whole reason we use nonces is that the proofs are checked against the current account state, but the account changes (i.e., decrement for the sender) is buffered into the pending state (until rollover). if you allow multiple transactions before a rollover happens, then nothing prevents a sender from spending twice, and then having a negative account after rollover. i don't see how you plan to prevent this?
  3. i don't understand your concern about reorganizations. it seems to me that the issue is the same in ethereum vs. zether: any transactions which live on the orphan fork will be "reverted". i think we can assume that if there are re-orgs, then you abandon all hope of guarantee that transactions will be committed to the chain... right?

anyway. i will talk now about how to leak the parity. the "right" way to do this involves a significant rewrite, where instead of submitting 1 list of accounts, the sender submits 2 (senders and receivers). then there is a separate many-out-of-many proof done for the senders list and the receivers list. this would involve a massive rewrite of the code, so maybe you are interested in a "minimal" way to do it. though I haven't carefully checked the details / security, i think you can do the following thing. in the line https://github.com/benediamond/anonymous-zether/blob/c342073fa00458f8b4f9cb014f6bd81539fca8fe/packages/anonymous.js/src/prover/zether.js#L87 you can try changing a so that the a[0] and a[m] are 0, namely new BN(0).toRed(bn128.q). WARNING THAT THIS REDUCES PRIVACY!!!!!!!! then in line https://github.com/benediamond/anonymous-zether/blob/c342073fa00458f8b4f9cb014f6bd81539fca8fe/packages/protocol/contracts/ZetherVerifier.sol#L140 the verifier can inspect the values of proof.f[0] and proof.f[m]. Exactly one will equal anonAuxiliaries.w and the other will equal 0. if proof.f[0] == 0, then the secret parity is even. otherwise, it is odd.