Hi. If I understand correct if I send a zec to my friend this takes the form of a note consisting of the amount I want to send and my friends shielded key. Then this note is
- encrypted to my friends public key so that only my friend can decrypt
- hashed + inserted into the merkle tree so my friend can later generate a joinsplit proof to spend it.
the second part makes sense to me, but as far as I understand its not actually enforced in the zk circuit that the ciphertext I provide in 1) is actually the correctly encrypted note (e.g. I could write in the ciphertext that my note contains 1000 zec even if its not true). Is this enforced some other way? Is it just assumed that I wouldn’t submit a wrong ciphertext with my note because then all I’m doing is basically throwing my own money away? Or did I get something wrong in my understanding?
That’s correct. If your ciphertext does not decrypt to a valid note, the recipient wallet will not recognize the funds. They will tell you that they haven’t received any money. If your wallet loses the plain note, these funds are essentially burned. It has happened in the past due to some bug. Fortunately, the wallet was just storing the plain note in an incorrect format and the funds could be recovered.
The value in particular is validated with the binding signature. If you use an invalid value then the signature will fail to validate and the transaction won’t be accepted.
Are you sure that the binding signature covers the ciphertext?
It doesn’t, I had the impression that when the OP asked about “submitting a wrong ciphertext” they meant “submitting a ciphertext for an invalid value”.
No I meant submitting an incorrect ciphertext for a valid note. Thanks to both of you guys though for answering my question
Authenticated encryption is used, so if you try to change the ciphertext, it will fail to decrypt.
To be sure that the contents of a note ciphertext are correct, i.e. that the note ciphertext does not lie about the value, the wallet must re-compute the note commitment, using the contents of the ciphertext, and check that it gets the same value as the commitment in the blockchain: https://zips.z.cash/protocol/protocol.pdf#decryptivk
Without this check, the wallet producing the note ciphertext could indeed lie about the value of the note. The ZK circuit (and balance and binding signature) checks that the value committed-to in the note commitment is correct, and then this check lets a wallet be sure that the value in the ciphertext is correct, even though the ZK circuit does not check the correctness of the ciphertext.