<p>This ZIP describes a mechanism and format for disclosing information about shielded spends and outputs within a transaction. In the typical case, this means enabling a sender to present a proof that they transferred funds to a recipient's shielded address.</p>
<p>When a transaction involves only transparent addresses, proof-of-payment is simple: The sender provides the transaction ID, and the recipient examines the blockchain to confirm that the transaction was mined. A third party can also perform this verification if they know the transparent addresses of the involved parties.</p>
<p>However, if the transaction involves shielded addresses, the blockchain by itself does not contain enough information to allow a record of the payment to be reconstructed and verified:</p>
<sectionid="managing-contributions-for-an-event"><h3><spanclass="section-heading">Managing contributions for an event</span><spanclass="section-anchor"><arel="bookmark"href="#managing-contributions-for-an-event"><imgwidth="24"height="24"class="section-anchor"src="assets/images/section-anchor.png"alt=""></a></span></h3>
<p>Alice runs an event on behalf of Bob and Carol, who both agree to split the cost equally. Alice receives a single payment for half the amount, and wants proof of who it came from (so she knows which person to follow up with for the remaining amount). Carol can provide a payment disclosure that reveals to Alice:</p>
<p>Diana is a well-known individual with a public shielded payment address (for receiving donations). She runs a matching donation drive to the non-profit Totally Legit Bunnies, and wants to prove to her followers that she correctly matched their donations. Diana can create a payment disclosure, and post it to her social media account, that reveals:</p>
<p>Edward goes to CarsRFast to buy a Lamborghini, and sends funds from his shielded address to CarsRFast's transparent address. They can see a payment has been made, but claim that they have not received a payment from Edward. He can create a payment disclosure that reveals:</p>
<sectionid="shielded-withdrawals-from-an-exchange"><h3><spanclass="section-heading">Shielded withdrawals from an exchange</span><spanclass="section-anchor"><arel="bookmark"href="#shielded-withdrawals-from-an-exchange"><imgwidth="24"height="24"class="section-anchor"src="assets/images/section-anchor.png"alt=""></a></span></h3>
<p>CorpBux is an exchange with a transparent hot wallet, and enables customers to withdraw their funds to shielded addresses. They can create a payment disclosure, that they can give to their customers, that reveals:</p>
<li>The payment disclosure may disclose the contents of zero or more shielded outputs within a single transaction. (Zero outputs is useful for z2t transactions.)</li>
<li>Payment disclosures can only be created by a sender of the transaction, and are non-malleable (that is, no-one else can take one or more payment disclosures and construct a new one that they would not have been able to make independently).</li>
<li>A payment disclosure may be tied to a challenge, creating an interactive proof.</li>
<li>Senders are not required to remember any ephemeral data from the creation of a transaction in order to produce a payment disclosure for that transaction. (Performance may be improved if they do cache witness data for spent notes.)</li>
<p>The following functions used in this ZIP are defined in the Zcash protocol specification: <aid="footnote-reference-1"class="footnote_reference"href="#protocol">3</a></p>
<sectionid="payment-disclosure-data-structure"><h3><spanclass="section-heading">Payment disclosure data structure</span><spanclass="section-anchor"><arel="bookmark"href="#payment-disclosure-data-structure"><imgwidth="24"height="24"class="section-anchor"src="assets/images/section-anchor.png"alt=""></a></span></h3>
: A BIP 322 signature. <aid="footnote-reference-5"class="footnote_reference"href="#bip-0322">9</a>
<ul>
<li>TODO: <cite>zcashd</cite> currently only supports the legacy format defined in BIP 322. We may want to backport full BIP 322 support before having transparent input support in this ZIP, to ensure it does what we need.</li>
<li>TODO: BIP 322 specifies consensus rule checks as part of the signature verification process. We will likely need to migrate it over to an equivalent ZIP that specifies these for Zcash (which has a different set of script validation consensus rules).</li>
: The outgoing cipher key that allows this output to be recovered. <aid="footnote-reference-7"class="footnote_reference"href="#protocol-saplingencrypt">5</a></li>
<sectionid="creating-a-payment-disclosure"><h3><spanclass="section-heading">Creating a payment disclosure</span><spanclass="section-anchor"><arel="bookmark"href="#creating-a-payment-disclosure"><imgwidth="24"height="24"class="section-anchor"src="assets/images/section-anchor.png"alt=""></a></span></h3>
<li>[Optional] If an associated payment address was provided for this spend index, create a ZIP 304 signature proof for that payment address, <aid="footnote-reference-9"class="footnote_reference"href="#zip-0304">11</a> using
<li>TODO: Prepare BIP 322 signature inputs using <cite>msg</cite> as the <cite>message_data</cite>.</li>
</ul>
</li>
<li>Construct an unsigned payment disclosure from the disclosed Sapling outputs, and the above data for the Sapling spends and transparent inputs. Define the encoding of this as
<li>TODO: Create a BIP 322 signature using <cite>msg</cite> as the <cite>message_data</cite>.</li>
</ul>
</li>
<li>Return the payment disclosure as the combination of the unsigned payment disclosure and the set of <cite>spendAuthSig</cite> and transparent signature values.</li>
<sectionid="verifying-a-payment-disclosure"><h3><spanclass="section-heading">Verifying a payment disclosure</span><spanclass="section-anchor"><arel="bookmark"href="#verifying-a-payment-disclosure"><imgwidth="24"height="24"class="section-anchor"src="assets/images/section-anchor.png"alt=""></a></span></h3>
<sectionid="payment-disclosure-validity-in-uis"><h3><spanclass="section-heading">Payment disclosure validity in UIs</span><spanclass="section-anchor"><arel="bookmark"href="#payment-disclosure-validity-in-uis"><imgwidth="24"height="24"class="section-anchor"src="assets/images/section-anchor.png"alt=""></a></span></h3>
<p>If a sender elects, at transaction creation time, to use an
<spanclass="math">\(\mathsf{ovk}\)</span>
of
<spanclass="math">\(\bot\)</span>
for a specific Sapling output, then they are unable to subsequently create a payment disclosure that discloses that output. This maintains the semantics of
<spanclass="math">\(\mathsf{ovk}\)</span>
, in that the sender explicitly chose to lose the capability to recover that output.</p>
<p>Payment disclosures that prove Sapling spend authority are not required to reveal a sender address. This is because it is impossible: we can "prove" the transaction came from any of the diversified addresses linked to the spending key. Fundamentally, the "sender" of a transaction is anyone who has access to the corresponding spend authority; in the case of Sapling, a spend authority corresponds to multiple diversified addresses. In situations where a sender address is already known to the verifier of the payment disclosure (or publically), it may still be useful to have the option of linking the payment disclosure to that address.</p>
<sectionid="security-and-privacy-considerations"><h2><spanclass="section-heading">Security and Privacy Considerations</span><spanclass="section-anchor"><arel="bookmark"href="#security-and-privacy-considerations"><imgwidth="24"height="24"class="section-anchor"src="assets/images/section-anchor.png"alt=""></a></span></h2>
<p>When spending Sapling notes normally in transactions, wallets select a recent anchor to make the anonymity set of the spent note as large as possible. By contrast, Sapling spend authority in a payment disclosure is proven using the same anchor that was used in the transaction itself, instead of a recent anchor. We do this for efficency reasons:</p>
<ul>
<li>The anchor is already encoded in the transaction, so can be omitted from the payment disclosure encoding.</li>
<li>It is necessary to have a witness for each spent note that is being included in the payment disclosure. Using the same anchor means that the same witness can be used for the transaction spend and the payment disclosure, which in turn means that wallets that support payment disclosures only need to remember that witness, and do not need to continually update witnesses for spent notes in the off-chance that they might be used in a payment disclosure.</li>
</ul>
<p>There is no privacy benefit to selecting a more recent anchor; the anonymity set of the note was "fixed" by the original spend (which revealed that the note existed as of that anchor's height).</p>
<p>We require all payment disclosures to prove spend authority for at least one input, in order to simplify the verification UX. In particular, if payment disclosures without spends were considered valid, an invalid payment disclosure with invalid signatures (that would be shown as invalid by UIs) could be mutated into a payment disclosure that would be shown as valid by UIs, by stripping off the signatures. We do not believe that this prevents any useful use cases; meanwhile if someone is intent on obtaining Sapling output disclosures regardless of the validity of their source, they will do so without a common standard.</p>
<td><ahref="protocol/protocol.pdf#saplingdecryptovk">Zcash Protocol Specification, Version 2020.1.15. 4.17.3: Decryption using a Full Viewing Key (Sapling)</a></td>