Generally, what you want to hide is the correspondence between outputs and inputs. So, for example, say you send me one unit of currency and then I send one unit of currency to someone else. What we don't need to hide:
- You had one unit of currency to send.
- You wanted to send that one unit of currency somewhere.
- You no longer have the one unit of currency you had in step 1.
- I had one unit of currency.
- I want to send that one unit of currency somewhere.
- My transfer of one unit of currency will prevent me from sending one unit of currency that I could previous send.
What we don't want to reveal:
- The one unit of currency that I transferred is the same unit of currency that you transferred.
There are various cryptographic techniques that can be used to reveal the six things we do need to reveal without revealing the one thing we don't want to reveal. Zcash, for example, does this by having a person prove that they rendered unusable one output that they previously could have used without revealing which output they've rendered unusable. So if you send me one unit of zcash and I send one unit of zcash somewhere, it is not possible to connect the unit you send me with the unit I sent. All you know is that I previously had one unit of zcash I could send and now I do not, but it can be any unit of zcash send previously.