ZIP: 226
Title: Transfer and Burn of Zcash Shielded Assets
Owners: Pablo Kogan <pablo@qed-it.com>
        Vivek Arte <vivek@qed-it.com>
        Daira-Emma Hopwood <daira-emma@electriccoin.co>
        Jack Grigg <str4d@electriccoin.co>
Credits: Daniel Benarroch
         Aurelien Nicolas
         Deirdre Connolly
         Teor
Status: Draft
Category: Consensus
Created: 2022-05-01
License: MIT
Discussions-To: <https://github.com/zcash/zips/issues/618>
Pull-Request: <https://github.com/zcash/zips/pull/680>

Terminology

The key word "MUST" in this document is to be interpreted as described in BCP 14 1 when, and only when, it appears in all capitals.

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

The character § is used when referring to sections of the Zcash Protocol Specification. 23

The terms "Orchard" and "Action" in this document are to be interpreted as described in ZIP 224. 5

The terms "Asset" and "Custom Asset" in this document are to be interpreted as described in ZIP 227. 7

We define the following additional terms:

Abstract

This ZIP (ZIP 226) proposes the Orchard Zcash Shielded Assets (OrchardZSA) protocol, in conjunction with ZIP 227 7. The OrchardZSA protocol is an extension of the Orchard protocol that enables the issuance, transfer and burn of custom Assets on the Zcash chain. The issuance of such Assets is defined in ZIP 227 7, while the transfer and burn of such Assets is defined in this ZIP (ZIP 226). While the proposed OrchardZSA protocol is a modification to the Orchard protocol, it has been designed with adaptation to possible future shielded protocols in mind.

Motivation

None of the currently deployed Zcash transfer protocols support Custom Assets. Enabling multi-asset support on the Zcash chain will open the door for a host of applications, and enhance the ecosystem with application developers and Asset custody institutions for issuance and bridging purposes. This ZIP builds on the issuance mechanism introduced in ZIP 227 7.

Overview

In order to be able to represent different Assets, we need to define a data field that uniquely represents the Asset in question, which we call the Asset Identifier AssetId ⁣\mathsf{AssetId}\! . This Asset Identifier maps to an Asset Base AssetBase\mathsf{AssetBase} that is stored in OrchardZSA notes. These terms are formally defined in ZIP 227 7.

The Asset Identifier (via means of the Asset Digest and Asset Base) will be used to enforce that the balance of an Action Description 25 38 is preserved across Assets (see the Orchard Binding Signature 28), and by extension the balance of an Orchard transaction. That is, the sum of all the valuenet\mathsf{value^{net}} from each Action Description, computed as valueoldvaluenew ⁣\mathsf{value^{old}} - \mathsf{value^{new}}\! , must be balanced only with respect to the same Asset Identifier. This is especially important since we will allow different Action Descriptions to transfer notes of different Asset Identifiers, where the overall balance is checked without revealing which (or how many distinct) Assets are being transferred.

As was initially proposed by Jack Grigg and Daira-Emma Hopwood 39 40, we propose to make this happen by changing the value base point, VOrchard ⁣\mathcal{V}^{\mathsf{Orchard}}\! , in the Homomorphic Pedersen Commitment that derives the value commitment, cvnet ⁣\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 Identifiers for a given shielded protocol used in a transaction. We propose to make the Asset Base an auxiliary input to the proof for each Action statement 30, represented already as a point on the Pallas curve. The circuit then should check that the same Asset Base is used in the old note commitment and the new note commitment 35, and as the base point in the value commitment 34. This ensures (1) that the input and output notes are of the same Asset Base, and (2) that only Actions with the same Asset Base will balance out in the Orchard binding signature.

In order to ensure the security of the transfers, and as we will explain below, we are redefining input dummy notes 27 for Custom Assets, as we need to enforce that the AssetBase\mathsf{AssetBase} of the output note of that Split Action is the output of a valid ZSAValueBase\mathsf{ZSAValueBase} computation defined in ZIP 227 7.

We include the ability to pause the ZSA functionality, via a enableZSA\mathsf{enableZSA} boolean flag. When this flag is set to false, the proof will fail for any non-native Asset, making it impossible to perform transactions involving Custom Assets. When this flag is set to true, the circuit will allow transactions involving Custom Assets subject to the values of the enableSpendsOrchard\mathsf{enableSpendsOrchard} and enableOutputsOrchard\mathsf{enableOutputsOrchard} flags, similar to the vanilla Orchard setting.

Finally, in this ZIP we also describe the burn mechanism, which is a direct extension of the transfer mechanism. The burn process uses a similar mechanism to what is used in Orchard to unshield ZEC, by using the valueBalance\mathsf{valueBalance} of the Asset in question. Burning Assets is useful for many purposes, including bridging, and removing supply of Assets.

Privacy Implications

Specification

Most of the protocol is kept the same as the Orchard protocol released with NU5, except for the following.

Asset Identifiers

For every new Asset, there MUST be a new and unique Asset Identifier. Every Asset is defined by an Asset description, asset_desc ⁣\mathsf{asset\_desc}\! , which is a global byte string (scoped across all future versions of Zcash). From this Asset description and the issuance validating key of the issuer, the specific Asset Identifier, AssetId ⁣\mathsf{AssetId}\! , the Asset Digest, and the Asset Base (  ⁣AssetBase ⁣\!\mathsf{AssetBase}\! ) are derived as defined in ZIP 227 7.

This Asset Base will be the base point of the value commitment for the specific Custom Asset. Note that the Asset Base of the ZEC Asset will be kept as the original value base point, VOrchard ⁣\mathcal{V}^{\mathsf{Orchard}}\! .

Rationale for Asset Identifiers

In future network and protocol upgrades, the same Asset description string can be carried on, potentially mapping into a different shielded pool. In that case, nodes should know how to transform the Asset Identifier, the Asset Digest, and the Asset Base from one shielded pool to another, while ensuring there are no balance violations 3.

We prevent a potential malleability attack on the Asset Identifier by ensuring the output notes receive an Asset Base that exists on the global state.

Note Structure and Commitment

An OrchardZSA note differs from an Orchard note 24 by additionally including the Asset Base, AssetBase ⁣\mathsf{AssetBase}\! . So an OrchardZSA note is a tuple (d,pkd,v,AssetBase,ρ,ψ,rcm) ⁣(\mathsf{d}, \mathsf{pk_d}, \mathsf{v}, \mathsf{AssetBase}, \text{ρ}, \text{ψ}, \mathsf{rcm})\! , where

  • AssetBase:P\mathsf{AssetBase} : \mathbb{P}^* is the unique element of the Pallas group 36 that identifies each Asset in the Orchard protocol, defined as the Asset Base in ZIP 227 9, a valid group element that is not the identity and is not  ⁣\bot\! . The byte representation of the Asset Base is defined as asset_base:BY[P/8]:=LEBS2OSPP(reprP(AssetBase)) ⁣\mathsf{asset\_base} : \mathbb{B}^{\mathbb{Y}^{[\ell_{\mathbb{P}}/8]}} := \mathsf{LEBS2OSP}_{\ell_{\mathbb{P}}}(\mathsf{repr}_{\mathbb{P}}(\mathsf{AssetBase}))\! .
  • The remaining terms are as defined in §3.2 ‘Notes’ 24.

Note that the above assumes a canonical encoding, which is true for the Pallas group, but may not hold for future shielded protocols.

Let NoteOrchardZSA\mathsf{Note^{OrchardZSA}} be the type of a OrchardZSA note, i.e.

NoteOrchardZSA:=B[d]×KAOrchard.Public×{0..2value1}×P×FqP×FqP×NoteCommitOrchard.Trapdoor,\mathsf{Note^{OrchardZSA}} := \mathbb{B}^{[\ell_{\mathsf{d}}]} \times \mathsf{KA}^{\mathsf{Orchard}}.\mathsf{Public} \times \{0 .. 2^{\ell_{\mathsf{value}}} - 1\} \times \mathbb{P}^* \times \mathbb{F}_{q_{\mathbb{P}}} \times \mathbb{F}_{q_{\mathbb{P}}} \times \mathsf{NoteCommit^{Orchard}.Trapdoor},

where P\mathbb{P}^* is the Pallas group excluding the identity element, and the other types are as defined in §3.2 ‘Notes’ 24.

Non-normative note: The type and definition of the OrchardZSA note reflect that it is a tuple of all the components of an Orchard note, with the addition of the Asset Base into the tuple.

We define the note commitment scheme NoteCommitrcmOrchardZSA\mathsf{NoteCommit^{OrchardZSA}_{rcm}} as follows:

  • NoteCommitOrchardZSA:NoteCommitOrchard.Trapdoor\mathsf{NoteCommit}^{\mathsf{OrchardZSA}} : \mathsf{NoteCommit^{Orchard}.Trapdoor}\hspace{-1em} ×B[P]\hspace{1em}\times\, \mathbb{B}^{[\ell_{\mathbb{P}}]}\hspace{-1em} ×B[P]\hspace{1em}\times\, \mathbb{B}^{[\ell_{\mathbb{P}}]}\hspace{-1em} ×{0..2value1}\hspace{1em}\times\, \{0 .. 2^{\ell_{\mathsf{value}}} - 1\}\hspace{-1em} ×FqP\hspace{1em}\times\, \mathbb{F}_{q_{\mathbb{P}}}\hspace{-1em} ×FqP\hspace{1em}\times\, \mathbb{F}_{q_{\mathbb{P}}}\hspace{-1em} ×PNoteCommitOrchard.Output\hspace{1em}\times\, \mathbb{P}^* \to \mathsf{NoteCommit^{Orchard}.Output}

where P,P,qP\mathbb{P}, \ell_{\mathbb{P}}, q_{\mathbb{P}} are as defined for the Pallas curve 36, and where NoteCommitOrchard.{Trapdoor,Output}\mathsf{NoteCommit^{Orchard}.\{Trapdoor, Output\}} are as defined in §4.1.8 ‘Commitment’ 26. This uses the note commitment scheme defined in §5.4.8.4 ‘Sinsemilla Commitments’ 35 as follows:

NoteCommitrcmOrchardZSA(gd,pkd,v,ρ,ψ,AssetBase):={NoteCommitrcmOrchard(gd,pkd,v,ρ,ψ), ⁣ ⁣if AssetBase=VOrchardcmZSA ⁣ ⁣otherwise\mathsf{NoteCommit^{OrchardZSA}_{rcm}}(\mathsf{g_d}\star, \mathsf{pk_d}\star, \mathsf{v}, \text{ρ}, \text{ψ}, \mathsf{AssetBase}) := \begin{cases} \mathsf{NoteCommit^{Orchard}_{rcm}}(\mathsf{g_d}\star, \mathsf{pk_d}\star, \mathsf{v}, \text{ρ}, \text{ψ}), &\!\!\text{if } \mathsf{AssetBase} = \mathcal{V}^{\mathsf{Orchard}} \\ \mathsf{cm_{ZSA}} &\!\!\text{otherwise} \end{cases}

where:

  • cmZSA:=SinsemillaHashToPoint(“z.cash:ZSA-NoteCommit-M”,\mathsf{cm_{ZSA}} := \mathsf{SinsemillaHashToPoint}(\texttt{“z.cash:ZSA-NoteCommit-M”},\hspace{-6em} gdpkdI2LEBSP64(v)I2LEBSPbaseOrchard(ρ)\hspace{6em}\mathsf{g_{d}\star} \,||\, \mathsf{pk_{d}\star} \,||\, \mathsf{I2LEBSP_{64}(v)} \,||\, \mathsf{I2LEBSP}_{\ell^{\mathsf{Orchard}}_{\mathsf{base}}}(\text{ρ})\hspace{-6em} I2LEBSPbaseOrchard(ψ)asset_base)\hspace{6em}\,||\, \mathsf{I2LEBSP}_{\ell^{\mathsf{Orchard}}_{\mathsf{base}}}(\text{ψ}) \,||\, \mathsf{asset\_base})\hspace{-4em} +  [rcm]GroupHashP(“z.cash:Orchard-NoteCommit-r”,“”)\hspace{4em}\,+\; [\mathsf{rcm}]\,\mathsf{GroupHash}^{\mathbb{P}}(\texttt{“z.cash:Orchard-NoteCommit-r”}, \texttt{“”})

Note that reprP\mathsf{repr}_{\mathbb{P}} and GroupHashP\mathsf{GroupHash}^{\mathbb{P}} are as defined for the Pallas curve 36, baseOrchard\ell^{\mathsf{Orchard}}_{\mathsf{base}} is as defined in §5.3 ‘Constants’ 32, and I2LEBSP\mathsf{I2LEBSP} is as defined in §5.1 ‘Integers, Bit Sequences, and Endianness’ 31.

The nullifier is generated in the same manner as in the Orchard protocol §4.16 ‘Computing ρ values and Nullifiers’ 29.

The OrchardZSA note plaintext also includes the Asset Base asset_base:B[P]\mathsf{asset\_base} : \mathbb{B}^{[\ell_{\mathbb{P}}]} in addition to the components in the Orchard note plaintext 37. The explicit encoding of the note plaintext is provided in ZIP 230 18.

The explicit order of addition of the note commitments to the note commitment tree is specified in ZIP 227 11.

Rationale for Note Commitment

In the OrchardZSA protocol, the instance of the note commitment scheme, NoteCommitrcmOrchardZSA ⁣\mathsf{NoteCommit^{OrchardZSA}_{rcm}}\! , differs from the Orchard note commitment NoteCommitrcmOrchard\mathsf{NoteCommit^{Orchard}_{rcm}} in that for Custom Assets, the Asset Base will be added as an input to the commitment computation. In the case where the Asset is the ZEC Asset, the commitment is computed identically to the Orchard note commitment, without making use of the ZEC Asset Base as an input. As we will see, the nested structure of the Sinsemilla-based commitment 35 allows us to add the Asset Base as a final recursive step.

The note commitment output is still indistinguishable from the original Orchard ZEC note commitments, by definition of the Sinsemilla hash function 33. OrchardZSA note commitments will therefore be added to the same Orchard Note Commitment Tree. In essence, we have:

NoteCommitrcmOrchardZSA(reprP(gd),reprP(pkd),v,ρ,ψ,AssetBase)NoteCommitOrchard.Output\mathsf{NoteCommit^{OrchardZSA}_{rcm}}(\mathsf{repr}_{\mathbb{P}}(\mathsf{g_d}), \mathsf{repr}_{\mathbb{P}}(\mathsf{pk_d}), \mathsf{v}, \text{ρ}, \text{ψ}, \mathsf{AssetBase}) \in \mathsf{NoteCommit^{Orchard}.Output}

This definition can be viewed as a generalization of the Orchard note commitment, and will allow maintaining a single commitment instance for the note commitment, which will be used both for pre-ZSA Orchard and OrchardZSA notes.

Value Commitment

In the case of the OrchardZSA protocol, the value of different Asset Identifiers in a given transaction will be committed using a different value base point. The value commitment becomes:

cvnet:=ValueCommitrcvOrchardZSA(AssetBaseAssetId,vAssetIdnet)=[vAssetIdnet]AssetBaseAssetId+[rcv]ROrchard\mathsf{cv^{net}} := \mathsf{ValueCommit^{OrchardZSA}_{rcv}}(\mathsf{AssetBase_{AssetId}}, \mathsf{v^{net}_{AssetId}}) = [\mathsf{v^{net}_{AssetId}}]\,\mathsf{AssetBase_{AssetId}} + [\mathsf{rcv}]\,\mathcal{R}^{\mathsf{Orchard}}

where vAssetIdnet=vAssetIdoldvAssetIdnew\mathsf{v^{net}_{AssetId}} = \mathsf{v^{old}_{AssetId}} - \mathsf{v^{new}_{AssetId}} such that

  • vAssetIdold\mathsf{v^{old}_{AssetId}} and vAssetIdnew\mathsf{v^{new}_{AssetId}} are the values of the old and new notes of Asset Identifier AssetId\mathsf{AssetId} respectively,
  • AssetBaseAssetId\mathsf{AssetBase_{AssetId}} is defined in ZIP 227 7, and
  • ROrchard:=GroupHashP(“z.cash:Orchard-cv”,“r”) ⁣\mathcal{R}^{\mathsf{Orchard}} := \mathsf{GroupHash^{\mathbb{P}}}(\texttt{“z.cash:Orchard-cv”}, \texttt{“r”})\! , as in the Orchard protocol.

For ZEC, we define AssetBaseAssetId:=VOrchard\mathsf{AssetBase}_{\mathsf{AssetId}} := \mathcal{V}^{\mathsf{Orchard}} so that the value commitment for ZEC notes is computed identically to the Orchard protocol deployed in NU5 5. As such ValueCommitrcvOrchard(v)\mathsf{ValueCommit^{Orchard}_{rcv}}(\mathsf{v}) as defined in 5 is used as ValueCommitrcvOrchardZSA(VOrchard,v)\mathsf{ValueCommit^{OrchardZSA}_{rcv}}(\mathcal{V}^{\mathsf{Orchard}}, \mathsf{v}) here.

Rationale for Value Commitment

The Orchard Protocol uses a Homomorphic Pedersen Commitment 34 to perform the value commitment, with fixed base points VOrchard\mathcal{V}^{\mathsf{Orchard}} and ROrchard\mathcal{R}^{\mathsf{Orchard}} as the values represent the amount of ZEC being transferred.

The use of different value base points for different Assets enables the final balance of the transaction to be securely computed, such that each Asset Identifier is balanced independently, which is required as different Assets are not meant to be mutually fungible.

Burn Mechanism

The burn mechanism is a transparent extension to the transfer protocol that enables a specific amount of any Custom Asset to be "destroyed" by the holder. The burn mechanism does NOT send Assets to a non-spendable address, it simply reduces the total number of units of a given Custom Asset in circulation. It is enforced at the consensus level, by using an extension of the value balance mechanism used for ZEC Assets. Burning makes it globally provable that a given amount of a Custom Asset has been destroyed. Note that the OrchardZSA Protocol does not allow for the burning of the Native Asset (i.e. ZEC or TAZ).

In the OrchardZSA Transaction Structure, there is now an assetBurn\mathsf{assetBurn} set. For every Custom Asset (represented by its AssetBase ⁣\mathsf{AssetBase}\! ) that is burnt in the transaction, the sender adds to assetBurn\mathsf{assetBurn} the tuple (AssetBase,v) ⁣(\mathsf{AssetBase}, \mathsf{v})\! , where v\mathsf{v} is the amount of the Custom Asset the sender wants to burn. We denote by LL the cardinality of the assetBurn\mathsf{assetBurn} set in a transaction.

As described in Value Balance Verification, this provides the information for the validator of the transaction to compute the value commitment with the corresponding Asset Base. This ensures that the values are all balanced out on a per-Asset basis in the transaction.

Additional Consensus Rules for the assetBurn set

  1. It MUST be the case that for every (AssetBase,v)assetBurn,AssetBaseVOrchard ⁣(\mathsf{AssetBase}, \mathsf{v}) \in \mathsf{assetBurn}, \mathsf{AssetBase} \neq \mathcal{V}^{\mathsf{Orchard}}\! . That is, the Native Asset is not allowed to be burnt by this mechanism.
  2. It MUST be that for every (AssetBase,v)assetBurn,v0 ⁣(\mathsf{AssetBase}, \mathsf{v}) \in \mathsf{assetBurn}, \mathsf{v} \neq 0\! .
  3. There MUST be no duplication of Custom Assets in the assetBurn\mathsf{assetBurn} set. That is, every AssetBase\mathsf{AssetBase} has at most one entry in assetBurn ⁣\mathsf{assetBurn}\! .

The other consensus rule changes for the OrchardZSA protocol are specified in ZIP 227 10.

Note: The transparent protocol will not be changed with this ZIP to adapt to a multiple Asset structure. This means that unless future consensus rules changes do allow it, unshielding will not be possible for Custom Assets.

Value Balance Verification

In order to verify the balance of the different Assets, the verifier MUST perform a similar process as for the Orchard protocol 28, with the addition of the burn information.

For a total of nn Actions in a transfer, the prover MUST still sign the SIGHASH transaction hash using the binding signature key bsk=i=1nrcvi ⁣\mathsf{bsk} = \sum_{i=1}^{n} \mathsf{rcv}_i\! .

The verifier MUST compute the value balance verification equation:

bvk=(i=1ncvinet)ValueCommit0OrchardZSA(VOrchard,vbalanceOrchard)(AssetBase,v)assetBurnValueCommit0OrchardZSA(AssetBase,v)\mathsf{bvk} = (\sum_{i=1}^{n} \mathsf{cv}^{\mathsf{net}}_i) - \mathsf{ValueCommit_0^{OrchardZSA}(\mathcal{V}^{\mathsf{Orchard}}, v^{balanceOrchard})} - \sum_{(\mathsf{AssetBase}, \mathsf{v}) \in \mathsf{assetBurn}} \mathsf{ValueCommit_0^{OrchardZSA}}(\mathsf{AssetBase}, \mathsf{v})

After computing bvk ⁣\mathsf{bvk}\! , the verifier MUST use it to verify the binding signature on the SIGHASH transaction hash.

Rationale for Value Balance Verification

We assume nn Actions in a transfer. Out of these nn Actions, we further distinguish (for the sake of clarity) between Actions related to ZEC and Actions related to Custom Assets. We denote by SZEC{1..n}S_{\mathsf{ZEC}} \subseteq \{1 .. n\} the set of indices of Actions that are related to ZEC, and by SCA={1..n}SZECS_{\mathsf{CA}} = \{1 .. n\} \setminus S_{\mathsf{ZEC}} the set of indices of Actions that are related to Custom Assets.

The right hand side of the value balance verification equation can be expanded to:

((iSZECcvinet)+(jSCAcvjnet))([vbalanceOrchard]VOrchard+[0]ROrchard)((AssetBase,v)assetBurn[v]AssetBase+[0]ROrchard)((\sum_{i \in S_{\mathsf{ZEC}}} \mathsf{cv}^{\mathsf{net}}_i) + (\sum_{j \in S_{\mathsf{CA}}} \mathsf{cv}^{\mathsf{net}}_j)) - ([\mathsf{v^{balanceOrchard}}]\,\mathcal{V}^{\mathsf{Orchard}} + [0]\,\mathcal{R}^{\mathsf{Orchard}}) - (\sum_{(\mathsf{AssetBase}, \mathsf{v}) \in \mathsf{assetBurn}} [\mathsf{v}]\,\mathsf{AssetBase} + [0]\,\mathcal{R}^{\mathsf{Orchard}})

This equation contains the balance check of the Orchard protocol 28. With ZSA, transfer Actions for Custom Assets must also be balanced across Asset Bases. All Custom Assets are contained within the shielded pool, and cannot be unshielded via a regular transfer. Custom Assets can be burnt, the mechanism for which reveals the amount and identifier of the Asset being burnt, within the assetBurn\mathsf{assetBurn} set. As such, for a correctly constructed transaction, we will get jSCAcvjnet(AssetBase,v)assetBurn[v]AssetBase=jSCA[rcvjnet]ROrchard ⁣\sum_{j \in S_{\mathsf{CA}}} \mathsf{cv}^{\mathsf{net}}_j - \sum_{(\mathsf{AssetBase}, \mathsf{v}) \in \mathsf{assetBurn}} [\mathsf{v}]\,\mathsf{AssetBase} = \sum_{j \in S_{\mathsf{CA}}} [\mathsf{rcv}^{\mathsf{net}}_j]\,\mathcal{R}^{\mathsf{Orchard}}\! .

When the Asset is not being burnt, the net balance of the input and output values is zero, and there will be no addition to the assetBurn\mathsf{assetBurn} vector. Therefore, the relationship between bvk\mathsf{bvk} and bsk\mathsf{bsk} will hold if and only if, per Custom Asset, the sum of the net values of the relevant Actions equals the corresponding vk\mathsf{v}_k value (or equals 00 if that Asset is not in the assetBurn\mathsf{assetBurn} set), and for ZEC, the sum of the net values of the relevant Actions equals the vbalanceOrchard\mathsf{v^{balanceOrchard}} value.

As in the Orchard protocol, the binding signature verification key, bvk ⁣\mathsf{bvk}\! , will only be valid (and hence verify the signature correctly), as long as the committed values sum to zero. In contrast, in this protocol, the committed values must sum to zero per Asset Base, as the Pedersen commitments add up homomorphically only with respect to the same value base point.

Split Notes

A Split Input is a copy of a previously issued input note (that is, a note that has previously been included in the Merkle tree), with the following changes:

  • A split_flag\mathsf{split\_flag} boolean is set to 1.
  • The value of the note is replaced with the value 0 during the computation of the value commitment.

Input notes are sometimes split in two (or more) output notes, as in most cases, not all the value in a single note is sent to a single output.

When the number of input notes of a particular Asset Base is smaller than the required number of output notes for the same Asset Base, the sender creates Split Inputs of the same Asset Base as padding for the input-less Actions. Note that we do not care about whether the previously issued note copied to create a Split Input is owned by the sender, or whether it was nullified before.

Wallets and other clients have to choose from the following to ensure the Asset Base is preserved for the output note of a Split Action:

  1. The Split Input note could be another note containing the same Asset Base that is being spent by this transaction (but not by this Split Input).
  2. The Split Input note could be a different unspent note containing the same Asset Base (note that the note will not actually be spent).
  3. The Split Input note could be an already spent note containing the same Asset Base (note that by zeroing the value in the circuit, we prevent double spending).

For Split Notes, the nullifier is generated as follows:

nfold=ExtractP([(PRFnknfOrchard(ρold)+ψnf)modqP]KOrchard+cmold+LOrchard)\mathsf{nf_{old}} = \mathsf{Extract}_{\mathbb{P}} ([(\mathsf{PRF^{nfOrchard}_{nk}} (\text{ρ}^{\mathsf{old}}) + \text{ψ}^{\mathsf{nf}}) \bmod q_{\mathbb{P}}]\,\mathcal{K}^\mathsf{Orchard} + \mathsf{cm^{old}} + \mathcal{L}^\mathsf{Orchard})

where ψnf\text{ψ}^{\mathsf{nf}} is sampled uniformly at random on FqP ⁣\mathbb{F}_{q_{\mathbb{P}}}\! , KOrchard\mathcal{K}^{\mathsf{Orchard}} is the Orchard Nullifier Base as defined in §4.16 ‘Computing ρ values and Nullifiers’ 29, and LOrchard:=GroupHashP(“z.cash:Orchard”,“L”) ⁣\mathcal{L}^{\mathsf{Orchard}} := \mathsf{GroupHash^{\mathbb{P}}}(\texttt{“z.cash:Orchard”}, \texttt{“L”})\! .

Rationale for Split Notes

In the Orchard protocol, since each Action represents an input and an output, the transaction that wants to send one input to multiple outputs must have multiple inputs. The Orchard protocol gives dummy spend notes 27 to the Actions that have not been assigned input notes.

The Orchard technique requires modification for the OrchardZSA protocol with multiple Asset Identifiers, as the output note of the split Actions cannot contain just any Asset Base. We must enforce it to be an actual output of a GroupHash computation (in fact, we want it to be of the same Asset Base as the original input note, but the binding signature takes care that the proper balancing is performed). Without this enforcement the prover could input a multiple (or linear combination) of an existing Asset Base, and thereby attack the network by overflowing the ZEC value balance and hence counterfeiting ZEC funds.

Therefore, for Custom Assets we enforce that every input note to an OrchardZSA Action must be proven to exist in the set of note commitments in the note commitment tree. We then enforce this real note to be “unspendable” in the sense that its value will be zeroed in split Actions and the nullifier will be randomized, making the note not spendable in the specific Action. Then, the proof itself ensures that the output note is of the same Asset Base as the input note. In the circuit, the split note functionality will be activated by a boolean private input to the proof (aka the split_flag\mathsf{split\_flag} boolean). This ensures that the value base points of all output notes of a transfer are actual outputs of a GroupHash, as they originate in the Issuance protocol which is publicly verified.

Note that the Orchard dummy note functionality remains in use for ZEC notes, and the Split Input technique is used in order to support Custom Assets.

Circuit Statement

Every OrchardZSA Action statement is closely similar to the Orchard Action statement 30, except for a few additions that ensure the security of the Asset Identifier system. We detail these changes below.

All modifications in the Circuit are detailed in 41.

Asset Base Equality

The following constraints must be added to ensure that the input and output note are of the same AssetBase ⁣\mathsf{AssetBase}\! :

  • The Asset Base, AssetBase ⁣\mathsf{AssetBase}\! , for the note is witnessed once, as an auxiliary input.
  • In the Old note commitment integrity constraint in the Orchard Action statement 30, NoteCommitrcmoldOrchard(reprP(gdold),reprP(pkdold),vold,ρold,ψold)\mathsf{NoteCommit^{Orchard}_{rcm^{old}}}(\mathsf{repr}_{\mathbb{P}}(\mathsf{g_d^{old}}), \mathsf{repr}_{\mathbb{P}}(\mathsf{pk_d^{old}}), \mathsf{v^{old}}, \text{ρ}^{\mathsf{old}}, \text{ψ}^{\mathsf{old}}) is replaced with NoteCommitrcmoldOrchardZSA(reprP(gdold),reprP(pkdold),vold,ρold,ψold,AssetBase) ⁣\mathsf{NoteCommit^{OrchardZSA}_{rcm^{old}}}(\mathsf{repr}_{\mathbb{P}}(\mathsf{g_d^{old}}), \mathsf{repr}_{\mathbb{P}}(\mathsf{pk_d^{old}}), \mathsf{v^{old}}, \text{ρ}^{\mathsf{old}}, \text{ψ}^{\mathsf{old}}, \mathsf{AssetBase})\! .
  • In the New note commitment integrity constraint in the Orchard Action statement 30, NoteCommitrcmnewOrchard(reprP(gdnew),reprP(pkdnew),vnew,ρnew,ψnew)\mathsf{NoteCommit^{Orchard}_{rcm^{new}}}(\mathsf{repr}_{\mathbb{P}}(\mathsf{g_d^{new}}), \mathsf{repr}_{\mathbb{P}}(\mathsf{pk_d^{new}}), \mathsf{v^{new}}, \text{ρ}^{\mathsf{new}}, \text{ψ}^{\mathsf{new}}) is replaced with NoteCommitrcmnewOrchardZSA(reprP(gdnew),reprP(pkdnew),vnew,ρnew,ψnew,AssetBase) ⁣\mathsf{NoteCommit^{OrchardZSA}_{rcm^{new}}}(\mathsf{repr}_{\mathbb{P}}(\mathsf{g_d^{new}}), \mathsf{repr}_{\mathbb{P}}(\mathsf{pk_d^{new}}), \mathsf{v^{new}}, \text{ρ}^{\mathsf{new}}, \text{ψ}^{\mathsf{new}}, \mathsf{AssetBase})\! .

To make the evaluation of the note commitment easier, we add a boolean is_native_asset\mathsf{is\_native\_asset} as an auxiliary witness. We also add some constraints to verify that this variable is activated (i.e. is_native_asset=1 ⁣\mathsf{is\_native\_asset} = 1\! ) if the Asset Base is equal to VOrchard\mathcal{V}^{\mathsf{Orchard}} and this variable is not activated (i.e. is_native_asset=0 ⁣\mathsf{is\_native\_asset} = 0\! ) if the Asset Base is not equal to VOrchard ⁣\mathcal{V}^{\mathsf{Orchard}}\! .

The enableZSA\mathsf{enableZSA} Flag

The following constraints must be added to disable transactions involving Custom Assets when the enableZSA\mathsf{enableZSA} flag is set to false:

  • if enableZSA\mathsf{enableZSA} is not activated (i.e. enableZSA=0 ⁣\mathsf{enableZSA} = 0\! ), then constrain is_native_asset=1 ⁣\mathsf{is\_native\_asset} = 1\! , since the AsssetBase\mathsf{AsssetBase} must be equal to the native asset.

Value Commitment Correctness

The following constraints must be added to ensure that the value commitment is computed using the witnessed Asset Base:

  • The fixed-base multiplication constraint between the value and the value base point of the value commitment, cv ⁣\mathsf{cv}\! , is replaced with a variable-base multiplication between the two.
  • The witness to the value base point (as defined in the asset base equation) is the auxiliary input AssetBase ⁣\mathsf{AssetBase}\! .

Asset Identifier Consistency for Split Actions

Senders must not be able to change the Asset Base for the output note in a Split Action. We do this via the following constraints:

  • The Value Commitment Integrity should be changed:
    • Replace the input note value by a generic value, v ⁣\mathsf{v}'\! , as cvnet=ValueCommitrcvOrchardZSA(AssetBase,vvnew)\mathsf{cv^{net}} = \mathsf{ValueCommit_rcv^{OrchardZSA}}(\mathsf{AssetBase}, \mathsf{v}' - \mathsf{v^{new}})
  • Add a boolean split_flag\mathsf{split\_flag} variable as an auxiliary witness. This variable is to be activated split_flag=1\mathsf{split\_flag} = 1 if the Action in question has a Split Input and split_flag=0\mathsf{split\_flag} = 0 if the Action is actually spending an input note:
    • If split_flag=1\mathsf{split\_flag} = 1 then constrain v=0\mathsf{v}' = 0 otherwise constrain v=vold\mathsf{v}' = \mathsf{v^{old}} from the auxiliary input.
    • If split_flag=1\mathsf{split\_flag} = 1 then constrain is_native_asset=0\mathsf{is\_native\_asset} = 0 because split notes are only available for Custom Assets.
  • The Merkle Path Validity should check the existence of the note commitment as usual (and not like with dummy notes):
    • Check for all notes except dummy notes that (path,pos)(\mathsf{path}, \mathsf{pos}) is a valid Merkle path of depth MerkleDepthOrchard ⁣\mathsf{MerkleDepth^{Orchard}}\! , from cmold\mathsf{cm^{old}} to the anchor rtOrchard ⁣\mathsf{rt^{Orchard}}\! .
    • The new constraint is (vold=0is_native_asset=1)It is a dummy note(ValidMerklePath)The Merkle Path is valid ⁣\underbrace{(\mathsf{v^{old}} = 0 \land \mathsf{is\_native\_asset} = 1)}_\text{It is a dummy note} \lor \underbrace{(\mathsf{Valid\,Merkle\,Path})}_\text{The Merkle Path is valid}\! .
  • The Nullifier Integrity will be changed to prevent the identification of notes as defined in the Split Notes section.

Backwards Compatibility with ZEC Notes

The input note in the old note commitment integrity check must either include an Asset Base (OrchardZSA note) or not (pre-ZSA Orchard note). If the note is a pre-ZSA Orchard note, the note commitment is computed in the original Orchard fashion 26. If the note is an OrchardZSA note, the note commitment is computed as defined in the Note Structure and Commitment section.

OrchardZSA Transaction Structure

The transaction format for v6 transactions is described in ZIP 230 15. The ZSA-related changes in v6 include:

  • updates to the transaction structure 16 and the sighash digest computation 20;
  • new note plaintext formats for both Sapling and Orchard outputs 17, with corresponding changes to the note decryption algorithms for incoming and outgoing viewing keys 22.

Changes to ZIP 248

This ZIP proposes to register the OrchardZSA bundle type in the V6 transaction bundle type registry defined in ZIP 248 20:

BundleType mValuePoolDeltas mEffectBundles mAuthBundles Bundle kind
TBD OrchardZSA
OrchardZSA Effecting Data
Bytes Name Data Type Description
varies nActionGroupsOrchard compactSize The number of Action Group descriptions in vActionGroupsOrchard.
varies vActionGroupsOrchard ActionGroupOrchardEffecting[nActionGroupsOrchard] A sequence of ActionGroupOrchardEffecting descriptions, encoded as per ActionGroupOrchardEffecting.
ActionGroupOrchardEffecting
Bytes Name Data Type Description
varies nActionsOrchard compactSize The number of Action descriptions in vActionsOrchard. This MUST have a value strictly greater than 0.
372 × nActionsOrchard vActionsOrchard OrchardZSAEffecting[nActionsOrchard] A sequence of OrchardZSA Action descriptions in the Action Group.
1 flagsOrchard byte As defined in §7.1 ‘Transaction Encoding and Consensus’ [#protocol-txnencoding]_.
32 anchorOrchard byte[32] As defined in §7.1 ‘Transaction Encoding and Consensus’ [#protocol-txnencoding]_.
4 nAGExpiryHeight uint32 A block height in the range {1 .. 499999999} after which any transaction including this Action Group cannot be mined, or 0 if this Action Group places no constraint on transaction expiry.
varies nAssetBurn compactSize The number of Assets burnt.
40 × nAssetBurn vAssetBurn AssetBurn[nAssetBurn] A sequence of Asset Burn descriptions, encoded per OrchardZSA Asset Burn Description.

The encodings of OrchardZSAEffecting and AssetBurn are described below.

  • If the value of nAGExpiryHeight is nonzero, it MUST be consistent with the nExpiryHeight of the overall transaction.
  • In NU7, nExpiryHeight MUST be set to 0; this restriction is expected to be lifted in a future network upgrade.
Rationale for nAGExpiryHeight

We introduce the nAGExpiryHeight field in this transaction format in order to be forward compatible with Swaps over ZSAs, as proposed in ZIP 228 6. For the OrchardZSA protocol, which does not make use of an additional expiry height for transactions, we set the value of nAGExpiryHeight to be 0 by consensus. This serves as a default value to represent the situation where there is no expiry, analogous to the convention adopted for nExpiryHeight in ZIP 203 [#zip-0203].

Rationale for including Burn fields inside OrchardZSA Action Groups

Note that the bundle format includes the burn fields of the transaction inside the OrchardZSA Action Group rather than at the transaction level. This is a design choice that considers the future scenario where Action Groups may be generated by different parties before being bundled together into a transaction. In such a scenario, the individual parties can burn Assets of their choice in their corresponding Action Groups. Maintaining the burn fields at the transaction level would provide the ability to burn Assets only to the party performing the bundling of the Action Groups.

OrchardZSAEffecting
Bytes Name Data Type Description
32 cv byte[32] A value commitment to the net value of the input note minus the output note.
32 nullifier byte[32] The nullifier of the input note.
32 rk byte[32] The randomized validating key for this Action.
32 cmx byte[32] The x ⁣x\! -coordinate of the note commitment for the output note.
32 ephemeralKey byte[32] An encoding of an ephemeral Pallas public key.
132 encCiphertext byte[132] The encrypted contents of the note plaintext.
80 outCiphertext byte[80] The encrypted contents of the byte string created by concatenation of the transmission key with the ephemeral secret key.
OrchardZSA Asset Burn Description

System Message: INFO/1 (<stdin> line 480) orchardzsa-asset-burn-description-1

Duplicate implicit target name: "orchardzsa asset burn description".

An OrchardZSA Asset Burn description is encoded as an instance of an AssetBurn type:

Bytes Name Data Type Description
32 AssetBase byte[32] For the OrchardZSA protocol, this is the encoding of the Asset Base AssetBaseOrchard ⁣\mathsf{AssetBase^{Orchard}}\! .
8 valueBurn uint64 The amount being burnt. The value is checked by consensus to be non-zero.
OrchardZSA Authorizing Data

The authorizing data for the OrchardZSA bundle contains the proofs and signatures that authorize the actions. The per-action-group data parallels the structure of the effecting data.

System Message: ERROR/3 (<stdin> line 502)

Malformed table.

+-----------------------------+----------------------------------+------------------------------------------------------+---------------------------------------------------------------------+
| Bytes                       | Name                             | Data Type                                            | Description                                                         |
+=============================+==================================+======================================================+=====================================================================+
| varies                      |``vActionGroupsOrchardAuth``      |``ActionGroupOrchardAuthorizing[nActionGroupsOrchard]``|Authorizing data for each Action Group, in the same order as         |
|                             |                                  |                                                      |``vActionGroupsOrchard`` in the effecting data.                      |
+-----------------------------+----------------------------------+------------------------------------------------------+---------------------------------------------------------------------+
|``64``                       |``bindingSigOrchard``             |``byte[64]``                                          |An Orchard binding signature on the SIGHASH transaction hash.        |
+-----------------------------+----------------------------------+------------------------------------------------------+---------------------------------------------------------------------+
  • The value of nActionGroupsOrchard is not re-encoded in the authorizing data; it is taken from the corresponding effecting data.
  • The field bindingSigOrchard is present if and only if nActionGroupsOrchard>0 ⁣\mathtt{nActionGroupsOrchard} > 0\! .
ActionGroupOrchardAuthorizing

System Message: ERROR/3 (<stdin> line 520)

Malformed table.

+-----------------------------+--------------------------+----------------------------------------+---------------------------------------------------------------------+
| Bytes                       | Name                     | Data Type                              | Description                                                         |
+=============================+==========================+========================================+=====================================================================+
|``varies``                   |``sizeProofsOrchard``     |``compactSize``                         |Length in bytes of ``proofsOrchard``. Value is                       |
|                             |                          |                                        |:math:`2720 + 2272 \cdot \mathtt{nActionsOrchard}\!`.                |
+-----------------------------+--------------------------+----------------------------------------+---------------------------------------------------------------------+
|``sizeProofsOrchard``        |``proofsOrchard``         |``byte[sizeProofsOrchard]``             |Encoding of aggregated zk-SNARK proofs for OrchardZSA Actions       |
|                             |                          |                                        |in this Action Group.                                                |
+-----------------------------+--------------------------+----------------------------------------+---------------------------------------------------------------------+
|``64 * nActionsOrchard``     |``vSpendAuthSigsOrchard`` |``byte[64 * nActionsOrchard]``          |Authorizing signatures for each OrchardZSA Action in this            |
|                             |                          |                                        |Action Group.                                                        |
+-----------------------------+--------------------------+----------------------------------------+---------------------------------------------------------------------+
  • The value of nActionsOrchard is not re-encoded in the authorizing data; it is taken from the corresponding ActionGroupOrchardEffecting.
  • The proofs aggregated in proofsOrchard, and the elements of vSpendAuthSigsOrchard, each have a 1:1 correspondence to the elements of vActionsOrchard in the corresponding ActionGroupOrchardEffecting and MUST be ordered such that the proof or signature at a given index corresponds to the OrchardZSAEffecting at the same index.

The OrchardZSA bundle has value pool deltas (transfers move value in and out of the transparent transaction value pool), effecting data (the OrchardZSA actions and burn information), and authorizing data (the proofs and binding signature).

A transaction MUST NOT contain both an Orchard bundle (type 3) and an OrchardZSA bundle. The OrchardZSA bundle replaces the Orchard bundle for transactions that transfer Custom Assets.

Implications for Wallets

The following requirements on wallets are specified and motivated in ZIP 230 19:

  • All wallets should switch to sending only v6 transactions once NU7 has activated. The main consequence of not doing so relevant to ZSAs, is that users would not obtain the privacy benefit of indistinguishability between native and non-native assets in the Orchard shielded pool, because v5 transactions can only transact in the native ZEC asset. For other consequences see ZIP 230.
  • All wallets should be ready to receive funds in outputs of v6 transactions as soon as ZSAs activate — in particular to support decrypting note plaintexts with lead-byte 0x03\mathtt{0x03} 17. The consequence of not doing so would be that funds sent to Orchard addresses of a wallet without this support could be temporarily inaccessible, until the wallet is upgraded to fully support v6 and to rescan outputs since v6 activation.

Modifications to Digest Algorithms

The OrchardZSA bundle contributes to the transaction identifier and signature digest via the effects_bundles_digest and auth_bundles_digest defined in ZIP 248 20.

The OrchardZSA bundle's value pool deltas (for both ZEC and Custom Assets) are committed via value_pool_deltas_digest. The OrchardZSA effecting data (actions and burn information) is committed via effects_bundles_digest. The OrchardZSA authorizing data (proofs and binding signature) is committed via auth_bundles_digest.

Transaction Fees

The fee mechanism for the upgrades proposed in this ZIP will follow the mechanism described in ZIP 317 for the OrchardZSA protocol upgrade, and are described in ZIP 227 14.

Backward Compatibility

In order to have backward compatibility with the ZEC notes, we have designed the circuit to support both ZEC and OrchardZSA notes. As we specify above, there are three main reasons we can do this:

  • Note commitments for ZEC notes will remain the same, while note commitments for Custom Assets will be computed taking into account the AssetBase\mathsf{AssetBase} value as well.
  • The existing Orchard shielded pool will continue to be used for the new OrchardZSA notes post the upgrade.
  • The value commitment is abstracted to allow for the value base-point as a variable private input to the proof.
  • The ZEC-based Actions will still include dummy input notes, whereas the OrchardZSA Actions will include split input notes and will not include dummy input notes.

Deployment

The Zcash Shielded Assets protocol is scheduled to be deployed in Network Upgrade 7 (NU7). This ZIP currently assumes that this will be the case.

Test Vectors

Reference Implementation

References

1 Information on BCP 14 — "RFC 2119: Key words for use in RFCs to Indicate Requirement Levels" and "RFC 8174: Ambiguity of Uppercase vs Lowercase in RFC 2119 Key Words"
2 ZIP 200: Network Upgrade Mechanism
3 ZIP 209: Prohibit Negative Shielded Chain Value Pool Balances
4 ZIP 203: Transaction Expiry
5 ZIP 224: Orchard
6 ZIP 228: Asset Swaps for Zcash Shielded Assets
7 ZIP 227: Issuance of Zcash Shielded Assets
8 ZIP 227: Issuance of Zcash Shielded Assets — Specification: Global Issuance State
9 ZIP 227: Issuance of Zcash Shielded Assets — Specification: Asset Identifier
10 ZIP 227: Issuance of Zcash Shielded Assets — Specification: Consensus Rule Changes
11 ZIP 227: Issuance of Zcash Shielded Assets — Addition to the Note Commitment Tree
12 ZIP 227: Issuance of Zcash Shielded Assets — TxId Digest - Issuance
13 ZIP 227: Issuance of Zcash Shielded Assets — Authorizing Data Commitment
14 ZIP 227: Issuance of Zcash Shielded Assets — OrchardZSA Fee Calculation
15 ZIP 230: Version 6 Transaction Format
16 ZIP 230: Version 6 Transaction Format — Transaction Format
17 ZIP 230: Version 6 Transaction Format — Note Plaintexts
18 ZIP 230: Version 6 Transaction Format — Orchard Note Plaintext
19 ZIP 230: Version 6 Transaction Format — Implications for Wallets
20 ZIP 248: Extensible Transaction Format
21 ZIP 307: Light Client Protocol for Payment Detection
22 ZIP 2005: Quantum Recoverability
23 Zcash Protocol Specification, Version 2025.6.2 [NU6.1] or later.
24 Zcash Protocol Specification, Version 2025.6.2 [NU6.1]. Section 3.2: Notes
25 Zcash Protocol Specification, Version 2025.6.2 [NU6.1]. Section 3.7: Action Transfers and their Descriptions
26 Zcash Protocol Specification, Version 2025.6.2 [NU6.1]. Section 4.1.8: Commitment
27 Zcash Protocol Specification, Version 2025.6.2 [NU6.1]. Section 4.8.3: Dummy Notes (Orchard)
28 Zcash Protocol Specification, Version 2025.6.2 [NU6.1]. Section 4.14: Balance and Binding Signature (Orchard)
29 Zcash Protocol Specification, Version 2025.6.2 [NU6.1]. Section 4.16: Computing ρ values and Nullifiers
30 Zcash Protocol Specification, Version 2025.6.2 [NU6.1]. Section 4.18.4: Action Statement (Orchard)
31 Zcash Protocol Specification, Version 2025.6.2 [NU6.1]. Section 5.1: Integers, Bit Sequences, and Endianness
32 Zcash Protocol Specification, Version 2025.6.2 [NU6.1]. Section 5.3: Constants
33 Zcash Protocol Specification, Version 2025.6.2 [NU6.1]. Section 5.4.1.9: Sinsemilla hash function
34 Zcash Protocol Specification, Version 2025.6.2 [NU6.1]. Section 5.4.8.3: Homomorphic Pedersen commitments (Sapling and Orchard)
35 Zcash Protocol Specification, Version 2025.6.2 [NU6.1]. Section 5.4.8.4: Sinsemilla commitments
36 Zcash Protocol Specification, Version 2025.6.2 [NU6.1]. Section 5.4.9.6: Pallas and Vesta
37 Zcash Protocol Specification, Version 2025.6.2 [NU6.1]. Section 5.5: Encodings of Note Plaintexts and Memo Fields
38 Zcash Protocol Specification, Version 2025.6.2 [NU6.1]. Section 7.5: Action Description Encoding and Consensus
39 User-Defined Assets and Wrapped Assets
40 Comment on Generalized Value Commitments
41 Modifications to the Orchard circuit for the OrchardZSA Protocol

Docutils System Messages

System Message: ERROR/3 (<stdin> line 407)

Too many autonumbered footnote references: only 0 corresponding footnotes available.

System Message: ERROR/3 (<stdin> line 407) footnote-reference-60

Unknown target name: "protocol-txnencoding".

System Message: ERROR/3 (<stdin> line 410) footnote-reference-61

Unknown target name: "protocol-txnencoding".