ZIP: XXX
Title: Orchard Shielded Asset (OSA) Transfers
Owners: Daniel Benarroch <[email protected]>
				Pablo Kogan <[email protected]>
Credits: Jack Grigg
				 Daira Hopwood
				 Shahaf Nacshon
				 Vivek Arte
				 Aurel Nicolas
Status: Draft
Category: Consensus
Created: 2022-05-16
License: MIT

Terminology

The key words "MUST" and "MAY" in this document are to be interpreted as described in RFC 2119. [1]

The term "network upgrade" in this document is to be interpreted as described in ZIP 200 [2].

The term "Orchard" in this document is to be interpreted as described in ZIP 224 [3].

We define the following additional terms:

Abstract

This ZIP does not aim to cover the issuance mechanism of the Zcash Shielded Assets (ZSA)

Motivation

One of the directions for unleashing Zcash’ potential is to enable a multi-asset protocol on chain.

Overview & Rationale

This ZIP specifies the transfer and burn mechanism of the Zcash Shielded Asset (ZSA)

In order to be able to represent different asset types in Orchard, one needs to define a new data field that uniquely represents the type of the asset in question, which we call $\mathsf{type}$.

It has to be done in a way that enforces the balance of an action description to be preserved, and by extension of an Orchard transaction. Mainly, the sum of all the $\mathsf{value^{net}}$, as $\mathsf{value^{old}-value^{new}}$, derived from each action description, must be balanced only with respect to the same asset type. This is specially important since we will allow different action descriptions to transfer notes of different asset types, where the overall balance is checked without revealing which assets (or how many different types) are being transferred.

As was initially proposed by Jack Grigg and Daira Hopwood, we propose to make this happen by changing the value base point, $\mathcal{V}^{\mathsf{Orchard}}_\mathsf{type}$, in the Homomorphic Pedersen Commitment that generates the value commitment, $\mathsf{cv^{net}}$, of the net value in an Orchard Action.

Because in a single transaction all value commitments are balanced, there must be as many different value base points as there are asset types in the transaction. We propose to make the $\mathsf{type}$ identifier an auxiliary input to the proof, represented already as a point in the Pallas curve. The circuit then should check that the same $\mathsf{type}$ is used in the old note commitment, in the new note commitment and in the value commitment as the base point of the value.

This ensures that (1) the input and output notes are of the same type, and (2) that only actions with the same asset type identifier will balance out in the binding and balance signature.

Furthermore, in order to properly support transfers, when there is a split of a note (in most situations), we would like to enforce that the second output note is also of a real asset type $\mathsf{type}$. In order to achieve this we will replace the dummy note mechanism in the Orchard protocol to a “proof of existing type”, where the input note of the second (or nth) Action in the split is a real input note, to be verified belonging in the Merkle Tree of past note commitments. This prevents specific attacks that would allow counterfeiting of funds.

Orchard Protocol Changes

Most of the protocol is kept the same as the Orchard protocol released with NU5, except the following that will most likely be updated with NU6.

Asset Types

In the OSA protocol, we include a new variable, the asset type identifier, $\mathsf{type}$, which is generated as a 32-byte string during issuance (as described in the Issuance ZIP). The $\mathsf{type}$ will then be publicly hashed into the corresponding group, in this case the Pallas curve, by using the $\mathsf{GroupHash}$ function. In fact, every OSA-note will contain the group element representation of the asset type identifier. This will enable a much more elegant and simple version of the circuit, as we will see.

We denote the string as $\mathsf{type}$ and we denote the same string as $\mathsf{type}_{\mathbb{G}}$ when mapped into a specific group.

In future network and protocol upgrades, the same asset type string can be carried on, with potentially a mapping into a different curve or group. In that case, the turnstile should know how to transform the asset type from one group to another one.

TODO: Serialization

Note Structure & Commitment

First, we need to adapt the components that define the assets, i.e.: notes. A ZSA note differs from an Orchard note by including the type of asset, $\mathsf{type}_\mathbb{P}$. So an ZSA note looks like:

$$ (\mathsf{g_d, pk_d, v, type_{\mathbb{P}}, \rho, \psi}) $$

Where $\mathsf{type}_\mathbb{P}$ is the unique random group element that identifies each asset in the ZSA anonymity pool. The generation of this value is done at issuance, and will be covered in the *Issuance ZIP*.

In this case, the note commitment, $\mathsf{NoteCommit^{Orchard}_{rcm}}$, changes its input, to include the asset type identifier in the input. The output will still be indistinguishable with the original Orchard ZEC note commitments, by definition. This implies that ZSA note commitments will be added to the same Orchard anonymity pool and Merkle Commitment Tree.

In essence, we have

$$ \mathsf{NoteCommit^{OSA}{rcm}(repr{\mathbb{P}}(g_d), repr_{\mathbb{P}}(pk_d), v, type_\mathbb{P}, \rho, \psi)} \in \{\mathsf{cm},\bot\} $$

The nullifier is generated in the same manner as in the Orchard protocol.

Value Commitment

The Orchard Protocol uses a Sinsemilla-based Homomorphic Pedersen Commitment, as explained in [§5.4.8.3], which is instantiated as

$$ \mathsf{cv^{net}:=ValueCommit^{Orchard}_{rcv}(v^{net})}:= \mathsf{[v^{net}]}\mathcal{V}^{\mathsf{Orchard}}+ [\mathsf{rcv}]\mathcal{R}^{\mathsf{Orchard}} $$

Where $\mathsf{v^{net} = v^{old} - v^{new}}$ and

$$ \mathcal{V}^{\mathsf{Orchard}}:=\mathsf{GroupHash^{\mathbb{P}}}(\texttt{"z.cash:Orchard-cv", "v")} \\ \mathcal{R}^{\mathsf{Orchard}}:=\mathsf{GroupHash^{\mathbb{P}}}(\texttt{"z.cash:Orchard-cv", "r")} $$

In the case of the Orchard protocol, we see that the base points $\mathcal{V}^{\mathsf{Orchard}}$ and $\mathcal{R}^{\mathsf{Orchard}}$ are fixed for every value commitment, as the values represent the amount of ZEC being transferred.

In the case of the ZSA protocol, the value of different asset types in a given transaction will be committed using a different value base point. This enables the final balance of the transaction to be securely computed, such that each asset type is balanced independently, as the assets are not meant to be fungible. The value commitment then becomes

$$ \mathsf{cv^{net}:=ValueCommit^{OrchardType}{rcv}(v^{net}{type}, \mathcal{V}^{\mathsf{ZSA}}{\mathsf{type}})}:= \mathsf{[v^{net}{type}]}\mathcal{V}^{\mathsf{ZSA}}_{\mathsf{type}}+ [\mathsf{rcv}]\mathcal{R}^{\mathsf{Orchard}} $$

where $\mathsf{v^{net}{type}} = \mathsf{v^{old}{type} - v^{new}_{type}}$ and

$$ \mathcal{V}^{\mathsf{ZSA}}{\mathsf{type}}:=\mathsf{type\mathbb{P}}= \mathsf{GroupHash^{\mathbb{P}}}\texttt{("z.cash:Orchard-cv",type\_params)} \\ \mathcal{R}^{\mathsf{Orchard}}:=\mathsf{GroupHash^{\mathbb{P}}}\texttt{("z.cash:Orchard-cv", "r")} $$

In order to have the ZEC notes be equal, for compatibility between Orchard and ZSA transactions, the ZEC note will have the $\bot$ element for the $\mathsf{type}$, and $\mathcal{V}^{\mathsf{ZSA}}_{\mathsf{ZEC}} = \mathcal{V}^{\mathsf{Orchard}}$.

Value Balance Verification

Given $N+1$ types of assets being transferred, including the default ZEC, denote $m_j$ the number of actions of type $j$. In order to verify the balance of the different assets, the process is similar to that explained in §4.14 of the Zcash Specification.

First, it is important to note that for transfers, where the custom assets are strictly contained within the shielded ZSA pool (as no un-shielding is supported), there is only one type of value balance, that of ZEC, $\mathsf{v^{balanceOrchard}}$.

This way, we also ensure that the number of assets, nor their types will be revealed. The only exception to this is in the case that an asset is burnt, as we will see below.

In general, any transfer that stays strictly within the ZSA & Orchard anonymity pool will have that the net balance of the input and output values is zero, so no net amount of any type will be revealed anyway.

The prover can still sign the SIGHASH of the transaction using the binding signing key

$$ \mathsf{bsk} = \sum_{\mathsf{ \forall i,j}} \mathsf{rcv_{i,j}} $$

For all the types $j \in \{0,...,N\}$ and the respective number of actions (or $\mathsf{cv}$ commitments) $i \in \{0,...,m_j\}$.

Then we have that the verifier computes

$$ \mathsf{bvk = (\sum cv_i^{net})} - \mathsf{ ValueCommit_0^{Orchard}(v^{balanceOrchard})} \\ = \sum \mathsf{rcv_{i,j}^{net}}\mathcal{R}^{\mathsf{Orchard}} $$

And uses it to verify the binding signature, as described in §4.14 of the Zcash Specification, by verifying the bindingSignature on the SIGHASH message.

As in the Orchard protocol, the binding signature verification key, $\mathsf{bvk}$ , will only be valid (and hence verify the signature correctly, as long as all the value commitments (and corresponding value balances) are equal to zero. In contrast, in this protocol, the value commitments only cancel out per asset type, as the Pedersen commitments add up homomorphically only with respect to the same value base point.

Note Splitting

One of the key functionalities in a UTXO based protocol is the fact that input notes are usually split in two output notes, as usually, not all the value in a single note is sent to a single output. This is called a 1-to-many (Orchard) transaction. In order to cope with this today, the input note of the second action is a “dummy spend note”, as described in §4.8.3, which means that the whole input note is “faked” inside of the proof.

This, however, brings some issues when it comes to adding multiple asset types, as the output note of the split Actions cannot be of any asset type, it must be enforced to be an actual output of a GroupHash computation. If not, then the prover could essentially input a multiple (or linear combination of) an existing type, with the goal to attack the network by overflowing the ZEC value balance and hence counterfeiting ZEC funds.

In order to prevent this, we make some modifications to the circuit. Specifically we remove the dummy note functionality and we enforce that every input note to an ZSA Action must be proven to exist in the set of note commitments in the Merkle Tree. We then enforce this real note to be “dummy” in the sense that its value will be zeroed in split Actions. Then, the proof itself ensures that the output note is of the same type as the input note, even in the split Actions

Note that this is enough to create a chain of induction that ensures that all output notes of a transfer are actual outputs of a GroupHash, preventing any malleability attacks, as they originate in the Issuance protocol, which is publicly verified. Furthermore, we do not care about whether the note is owned by the sender, or whether it was nullified before.

The specific circuit changes are presented below.

Consensus Changes & Backward Compatibility

These changes in the protocol do not entail any consensus changes. The ZSA protocol will be backward-compatible with existing ZEC notes. This is achieved by supporting both ZEC and ZSA notes in the ZSA circuit.

Circuit Statement

The advantage of this method, with respect to the circuit statement y that every Action statement is kept almost identical to the Orchard statement, except for a few changes. See §4.17.4 of the Zcash Specification for comparison.

The following constraints must be added to ensure that the input and output note are of the same type:

The following constraints must be added to ensure that the value commitment is computed using the witnessed type, as represented in the notes

The following constraints must be added to prevent senders from inputting a different asset type in the consequent actions of the split:

The following constraints must be added to enable backwards compatibility with the Orchard ZEC notes.

The old note commitment is computed using a “rolling-aggregate” sinsemilla commitment. This means that the commitment is computed by adding new chunks or windows to the accumulated value. This method will be used in order to maintain a single commitment instance for the old note commitment, that will be used both for Orchard ZEC notes and for ZSA notes. The original Orchard ZEC notes will be conserved and not actually be converted into ZSA notes, as we will always need to compute them.

Burn Mechanism (WIP)

The burn mechanism may be needed for off-boarding the wrapped assets from the chain, or enabling advanced tokenomics on native tokens. It is part of the Issuance/Burn protocol, but given that it can be seen as an extension of the Transfer protocol, we add it here for readability.

In essence, the burn mechanism is a transparent / revealing extension to the transfer protocol that enables a specific amount of any asset type to be sent into “oblivion”. Our burn mechanism does NOT send assets to a non-spendable address, it simply reduces the total number of assets in circulation at the consensus level. It is enforced at the consensus level, by using an extension of the value balance mechanism used for ZEC assets.

First, contrary to the strict transfer transaction, we allow the sender to include a valueBalvalueBalance_typeance_type variable for every asset type that is being burnt. As we will show in the transaction structure, this is separate from the regular valueBalance^Orchard that is the default transparent value for the ZEC asset.

For every custom asset that is burnt, we add to the assetBurn vector the tuple (valueBalance_type, type_P) such that the validator of the transaction can compute the value commitment with the corresponding value base point of that asset. This ensures that the values are all balanced out with respect to the asset types in the transfer.

$$ \mathsf{assetBurn = [(v^{type^j}, type_\mathbb{P}^j)}|0 < j \leq N, \forall j \textit{ s.t. }\mathsf{v^{type^j}\neq 0}] $$

The value balances for each asset type in assetBurn represents the amount of that asset type that is being burnt. In the case of ZEC, the value balance represents either the transaction fee, or the amount of ZEC changing anonymity pools (to Sapling or Transparent).

Finally, the validator needs to verify the Balance and Binding Signature by adding the value balances for all assets, as committed using their respective types as the value base point of the Pedersen Commitment. This is done as follows

$$ \mathsf{bvk = (\sum cv_i^{net})} - \mathsf{ ValueCommit_0^{Orchard}(v^{balanceOrchard})} \\ -\sum_{0 < j \leq N, \forall j \textit{ s.t. }\mathsf{v^{type^j}\neq 0}} \mathsf{Value Commit_0^{OrchardType}(v^{type^j}, type^j_\mathbb{P}) } \\ = \sum \mathsf{rcv_{i,j}^{net}}\mathcal{R}^{\mathsf{Orchard}} $$

In the case that the balance of all the action values related to a specific asset will be zero, there will be no value added to the vector. This way, the number of assets, nor their types will be revealed, except in the case that an asset is burnt.

<aside> 👀 Note: Even if this mechanism allows having transparent ↔  shielded asset transfers in theory, the transparent protocol will not be changed with this ZIP to adapt to a multiple asset structure. This means that unless consensus rules do allow it in principle, the unshielding should not be possible.

</aside>

In order to properly manage a bridge with another chain, the issuer will have a denominated on-chain address in order for users to send a value 0 note of the type they are burning that will include in the memo field the specific address or information needed to withdraw the funds from the bridge on the other chain.

ZSA Transaction Structure

Similar to NU5 transaction structure, with the following modifications:

Bytes Name Data Type Description