# ZIP 316: Unified Addresses and Unified Viewing Keys

Status: Active, Withdrawn, Draft

Owners: Daira-Emma Hopwood, Nathan Wilcox, Jack Grigg, Sean Bowe, Kris Nuttycombe

Snapshot: a34cfc091434275120ff017c92c3b50d3cef623a

Source date: 2026-10-16T02:56:04+01:00

[Source revision](https://github.com/zcash/zips/commit/a34cfc091434275120ff017c92c3b50d3cef623a)

[Official source](https://zips.z.cash/zip-0316) · [Source file](https://github.com/zcash/zips/blob/a34cfc091434275120ff017c92c3b50d3cef623a/zips/zip-0316.rst) · [Discussion](https://github.com/zcash/zips/issues/482)

## Document parts

[Part 1](https://zip-tools-web.harpocrates.workers.dev/zip/316) · [Part 2](https://zip-tools-web.harpocrates.workers.dev/zip/316?part=2)

Reading part 2 of 2. Follow all parts for the complete proposal.

Producers MUST NOT include Items with Typecodes not permitted for the address type being produced, and MUST NOT generate UA/UVKs containing Items with typecodes that are Unassigned.

The guiding principle for `zu` addresses is that a `zu` address MUST NOT contain any Items whose interpretation in transaction construction could result in an unprivileged observer of the chain being able to distinguish transactions sent to addresses containing such Items from transactions sent to addresses that do not.

In contrast, a `tu` address MAY contain items whose interpretation in transaction construction could result in additional information being leaked on-chain. As such a user giving out a `tu` address should recognise that they may be giving up some privacy in transactions received at that address.

If a new Metadata Item type should not be allowed in `zu` addresses, it MUST be assigned in the MUST-understand Metadata range.

Experimental Typecodes ($\mathtt{0xFFFA}$ to $\mathtt{0xFFFF}$) are permitted at the discretion of wallets that have opted into the corresponding experiment as described in [Experimental Usage](/zip/316#experimental-usage); for `zu` addresses, such wallets are responsible for ensuring that the experiment does not compromise the privacy properties of `zu` addresses.

```
+-------------------+--------------------------------------+----+--------+--------+
| Typecode          | Description                          | R0 | R2 zu  | R2 tu  |
+===================+======================================+====+========+========+
| 0x00              | Transparent P2PKH                    | ✅ | ❌     | ✅     |
+-------------------+--------------------------------------+----+--------+--------+
| 0x01              | Transparent P2SH                     | ✅ | ❌     | ✅     |
+-------------------+--------------------------------------+----+--------+--------+
| 0x02              | Sapling                              | ✅ | ✅     | ✅     |
+-------------------+--------------------------------------+----+--------+--------+
| 0x03              | Orchard                              | ✅ | ✅     | ✅     |
+-------------------+--------------------------------------+----+--------+--------+
| 0x04..=0xBF       | Unassigned                           | ❌ | ❌     | ❌     |
+-------------------+--------------------------------------+----+--------+--------+
| 0xC0..=0xDF       | Non-MUST-understand Metadata         | ❌ | ❌     | ❌     |
+-------------------+--------------------------------------+----+--------+--------+
| 0xE0              | Address Expiry Height                | ❌ | ✅     | ✅     |
+-------------------+--------------------------------------+----+--------+--------+
| 0xE1              | Address Expiry Time                  | ❌ | ✅     | ✅     |
+-------------------+--------------------------------------+----+--------+--------+
| 0xE2..=0xFC       | Unassigned MUST-understand Metadata  | ❌ | ❌     | ❌     |
+-------------------+--------------------------------------+----+--------+--------+
| 0xFD..=0xFFF9     | Unassigned                           | ❌ | ❌     | ❌     |
+-------------------+--------------------------------------+----+--------+--------+
| 0xFFFA..=0xFFFF   | Experimental                         | ✅ | [1]    | ✅     |
+-------------------+--------------------------------------+----+--------+--------+
```

[1] See note above regarding experimental typecodes in `zu` addresses.

Additions to this registry are made via 2xxx-series ZIPs. This table will be updated by the ZIP Editors when such a ZIP transitions to `Proposed` status.

<a id="deriving-internal-keys"></a>

### Deriving Internal Keys

In addition to external addresses suitable for giving out to Senders, a wallet typically requires addresses for internal operations such as change and auto-shielding.

We desire the following properties for viewing authority of both shielded and transparent key trees:

- A holder of an FVK can derive external and internal IVKs, and external and internal $\mathsf{ovk}$ components.

- A holder of the external IVK cannot derive the internal IVK, or any of the $\mathsf{ovk}$ components.

- A holder of the external $\mathsf{ovk}$ component cannot derive the internal $\mathsf{ovk}$ component, or any of the IVKs.

For shielded keys, these properties are achieved by the one-wayness of $\mathsf{PRF^{expand}}$ and of $\mathsf{CRH^{ivk}}$ or $\mathsf{Commit^{ivk}}$ (for Sapling and Orchard respectively). Derivation of an internal shielded FVK from an external shielded FVK is specified in the "Sapling internal key derivation"<a id="fnref35"></a>
[35](#fn35) and "Orchard internal key derivation"<a id="fnref36"></a>
[36](#fn36) sections of ZIP 32.

To satisfy the above properties for transparent (P2PKH) keys, we derive the external and internal $\mathsf{ovk}$ components from the transparent FVK $(\mathsf{c}, \mathsf{pk})$ (described in [Encoding of Unified Full/Incoming Viewing Keys](/zip/316#encoding-of-unified-fullincoming-viewing-keys)) as follows:

- Let $I_\mathsf{ovk} = \mathsf{PRF^{expand}}_{\mathsf{LEOS2BSP}_{256}(\mathsf{c})}\big([\mathtt{0xd0}] \,||\, \mathsf{ser_P}(\mathsf{pk})\big)$ where $\mathsf{ser_P}(pk)$ is $33$ bytes, as specified in<a id="fnref37"></a>
  [37](#fn37).

- Let $\mathsf{ovk_{external}}$ be the first $32$ bytes of $I_\mathsf{ovk}$ and let $\mathsf{ovk_{internal}}$ be the remaining $32$ bytes of $I_\mathsf{ovk}$.

Since an external P2PKH FVK encodes the chain code and public key at the Account level, we can derive both external and internal child keys from it, as described in BIP 44<a id="fnref38"></a>
[38](#fn38). It is possible to derive an internal P2PKH FVK from the external P2PKH FVK (i.e. its parent) without having the external spending key, because child derivation at the Change level is non-hardened.

As of [Revision 2](/zip/316#Revision 2), to satisfy the above properties for transparent P2SH keys, we derive the external and internal $\mathsf{ovk}$ components from the P2SH FVK (described in [P2SH Viewing Key Items](/zip/316#P2SH Viewing Key Items)) as follows:

- Let $\mathsf{fvk\_ser}$ be the raw encoding of the P2SH Viewing Key Item (i.e. the concatenation of $\mathsf{template\_len}$, $\mathsf{template}$, $\mathsf{n\_keys}$, and the key information entries, as specified in [P2SH Viewing Key Items](/zip/316#P2SH Viewing Key Items)).

- Let $I_\mathsf{ovk} = \textsf{BLAKE2b-512}(\texttt{"ZIP316\_P2SH\_OVK\_"},\, \mathsf{fvk\_ser})$.

- Let $\mathsf{ovk_{external}}$ be the first $32$ bytes of $I_\mathsf{ovk}$ and let $\mathsf{ovk_{internal}}$ be the remaining $32$ bytes of $I_\mathsf{ovk}$.

Since a P2SH FVK encodes the keys, with their chain codes, at a level from which both external and internal child keys can be derived (via the `/**` multipath notation in the descriptor template), we can derive both external and internal P2SH addresses without having any spending key, because child derivation at the Change and Index levels is non-hardened.

<a id="deriving-a-uivk-from-a-ufvk"></a>

### Deriving a UIVK from a UFVK

As a consequence of the specification in [MUST-understand Typecodes](/zip/316#MUST-understand Typecodes), as of [Revision 2](/zip/316#Revision 2) a Consumer of a UFVK MUST understand the meaning of all "MUST-understand" Metadata Item Typecodes present in the UFVK in order to derive a UIVK from it.

If the source UFVK is Revision 2 then the derived UIVK SHOULD be Revision 2; if the source UFVK includes any Metadata Items then the derived UIVK MUST be Revision 2.

For Metadata Items recognised by the Consumer, the processing of the Item when deriving a UIVK is specified in the section or ZIP describing that Item.

The following derivations are applied to each component FVK:

- For a Sapling FVK, the corresponding Sapling IVK is obtained as specified in<a id="fnref39"></a>
  [39](#fn39).

- For an Orchard FVK, the corresponding Orchard IVK is obtained as specified in<a id="fnref40"></a>
  [40](#fn40).

- For a Transparent P2PKH FVK, the corresponding Transparent P2PKH IVK is obtained by deriving the child key with non-hardened index $0$ as described in<a id="fnref41"></a>
  [41](#fn41).

- For a P2SH FVK (as of [Revision 2](/zip/316#Revision 2)), the corresponding P2SH IVK is obtained by:
  
  
  
  1. Replacing each occurrence of `/**` in the descriptor template with `/*`.
  
  2. For each key in the key information vector, deriving the child key with non-hardened index $0$ (external chain) as described in <a id="fnref42"></a>
     [42](#fn42), and appending $0$ (non-hardened) to the key's derivation path.

In each case, the Typecode remains the same as in the FVK.

Items (including Metadata Items that are not "MUST-understand") that are unrecognised by a given Consumer, or that are specified in experiments that the user has not opted into (see [Experimental Usage](/zip/316#experimental-usage)), MUST be dropped when the Consumer derives a UIVK from a UFVK.

<a id="deriving-a-unified-address-from-a-uivk"></a>

### Deriving a Unified Address from a UIVK

As a consequence of the specification in [MUST-understand Typecodes](/zip/316#MUST-understand Typecodes), as of [Revision 2](/zip/316#Revision 2) a Consumer of a UIVK MUST understand the meaning of all "MUST-understand" Metadata Item Typecodes present in the UIVK in order to derive a Unified Address from it.

If the source UIVK is [Revision 2](/zip/316#Revision 2) then the derived Unified Address SHOULD be Revision 2; if the source UIVK includes any Metadata Items then the derived Unified Address MUST be Revision 2.

For Metadata Items recognised by the Consumer, the processing of the Item when deriving a Unified Address is specified in the section or ZIP describing that Item.

To derive a Unified Address from a UIVK we need to choose a diversifier index, which MUST be valid for all of the Viewing Key Types in the UIVK. That is,

- A Sapling diversifier index MUST generate a valid diversifier as defined in ZIP 32 section “Sapling diversifier derivation” <a id="fnref43"></a>
  [43](#fn43).

- A Transparent diversifier index MUST be in the range $0$ to $2^{31} - 1$ inclusive.

- There are no additional constraints on an Orchard diversifier index.

Note: A diversifier index of 0 may not generate a valid Sapling diversifier (with probability $1/2$). Some wallets (either prior to the deployment of ZIP 316, in violation of the above requirement, or because they do not include a Sapling component in their UAs) always generate a Transparent P2PKH address at diversifier index 0. Therefore, *all* Zcash wallets, whether or not they support Unified Addresses, MUST assume that there may be transparent funds associated with diversifier index 0 for each ZIP 32 account, even in cases where the wallet implementation would not generate a Unified Address with that index for a given account. This is necessary to ensure reliable recovery of funds if key material is imported between wallets.

The following derivations are applied to each component IVK using the diversifier index:

- For a Sapling IVK, the corresponding Sapling Receiver is obtained as specified in<a id="fnref44"></a>
  [44](#fn44).

- For an Orchard IVK, the corresponding Orchard Receiver is obtained as specified in<a id="fnref45"></a>
  [45](#fn45).

- For a Transparent P2PKH IVK, the diversifier index is used as a BIP 44 child key index at the Index level<a id="fnref46"></a>
  [46](#fn46) to derive the corresponding Transparent P2PKH Receiver. As is usual for derivations below the BIP 44 Account level, non-hardened (public) derivation<a id="fnref47"></a>
  [47](#fn47) MUST be used. The IVK is assumed to correspond to the extended public key for the external (non-change) element of the path. That is, if the UIVK was constructed correctly then the BIP 44 path of the Transparent P2PKH Receiver will be $m / 44' / \mathit{coin\_type\kern0.05em'} / \mathit{account\kern0.1em'} / 0 / \mathit{diversifier\_index}$.

- As of [Revision 2](/zip/316#Revision 2), for a Transparent P2SH IVK, the corresponding P2SH Receiver is obtained by:
  
  
  
  1. For each key in the key information vector, deriving the child key at the diversifier index using non-hardened BIP 32 public derivation <a id="fnref48"></a>
     [48](#fn48).
  
  2. Instantiating the descriptor template by substituting each `@N` placeholder with the corresponding derived public key, evaluating the resulting output descriptor<a id="fnref49"></a>
     [49](#fn49) to obtain the output script, and computing the HASH160 of the serialized script to produce the P2SH Receiver Encoding.

Items (including Metadata Items that are not "MUST-understand") that are unrecognised by a given Consumer, or that are specified in experiments that the user has not opted into (see [Experimental Usage](/zip/316#experimental-usage)), MUST be dropped when the Consumer derives a Unified Address from a UIVK.

See [Address Expiration Metadata](/zip/316#address-expiration-metadata) for discussion of potential linking of Diversified Unified Addresses via their metadata.

<a id="usage-of-outgoing-viewing-keys"></a>

### Usage of Outgoing Viewing Keys

When a Sender constructs a transaction that creates Sapling or Orchard notes, it uses an outgoing viewing key, as described in <a id="fnref50"></a>
[50](#fn50) and<a id="fnref51"></a>
[51](#fn51), to encrypt an outgoing ciphertext. Decryption with the outgoing viewing key allows recovering the sent note plaintext, including destination address, amount, and memo. The intention is that this outgoing viewing key should be associated with the source of the funds.

However, the specification of which outgoing viewing key should be used is left somewhat open in<a id="fnref52"></a>
[52](#fn52) and <a id="fnref53"></a>
[53](#fn53); in particular, it was unclear whether transfers should be considered as being sent from an address, or from a ZIP 32 account<a id="fnref54"></a>
[54](#fn54). The adoption of multiple shielded protocols that support outgoing viewing keys (i.e. Sapling and Orchard) further complicates this question, since from NU5 activation, nothing at the consensus level prevents a wallet from spending both Sapling and Orchard notes in the same transaction. (Recommendations about wallet usage of multiple pools will be given in ZIP 315<a id="fnref55"></a>
[55](#fn55).)

Here we refine the protocol specification in order to allow more precise determination of viewing authority for UFVKs.

A Sender will attempt to determine a "sending Account" for each transfer. The preferred approach is for the API used to perform a transfer to directly specify a sending Account. Otherwise, if the Sender can ascertain that all funds used in the transfer are from addresses associated with some Account, then it SHOULD treat that as the sending Account. If not, then the sending Account is undetermined.

The Sender also determines a "preferred sending protocol" —one of "transparent", "Sapling", or "Orchard"— corresponding to the most preferred Receiver Type (as given in [Encoding of Unified Addresses](/zip/316#encoding-of-unified-addresses)) of any funds sent in the transaction.

If the sending Account has been determined, then the Sender SHOULD use the external or internal $\mathsf{ovk}$ (according to the type of transfer), as specified by the preferred sending protocol, of the full viewing key for that Account (i.e. at the ZIP 32 Account level).

If the sending Account is undetermined, then the Sender SHOULD choose one of the addresses, restricted to addresses for the preferred sending protocol, from which funds are being sent (for example, the first one for that protocol), and then use the external or internal $\mathsf{ovk}$ (according to the type of transfer) of the full viewing key for that address.

<a id="jumbling"></a>

### Jumbling

Security goal (**near second preimage resistance**):

- An adversary is given $q$ Unified Addresses/Viewing Keys, generated honestly.

- The attack goal is to produce a “partially colliding” valid Unified Address/Viewing Key that:
  
  
  
  1. has a string encoding matching that of *one of* the input Addresses/Viewing Keys on some subset of characters (for concreteness, consider the first $n$ and last $m$ characters, up to some bound on $n+m$);
  
  2. is controlled by the adversary (for concreteness, the adversary knows *at least one* of the private keys of the constituent Addresses).

Security goal (**nonmalleability**):

- In this variant, part b) above is replaced by the meaning of the new Address/Viewing Key being “usefully” different than the one it is based on, even though the adversary does not know any of the private keys. For example, if it were possible to delete a shielded constituent Address from a UA leaving only a Transparent Address, that would be a significant malleability attack.

<a id="discussion"></a>

#### Discussion

There is a generic brute force attack against near second preimage resistance. The adversary generates UAs / UVKs at random with known keys, until one has an encoding that partially collides with one of the $q$ targets. It may be possible to improve on this attack by making use of properties of checksums, etc.

The generic attack puts an upper bound on the achievable security: if it takes work $w$ to produce and verify a UA/UVK, and the size of the character set is $c$, then the generic attack costs $\sim \frac{w \cdot c^{n+m}}{q}$.

There is also a generic brute force attack against nonmalleability. The adversary modifies the target UA/UVK slightly and computes the corresponding decoding, then repeats until the decoding is valid and also useful to the adversary (e.g. it would lead to the Sender using a Transparent Address). With $w$ defined as above, the cost is $w/p$ where $p$ is the probability that a random decoding is of the required form.

<a id="solution"></a>

#### Solution

We use an unkeyed 4-round Feistel construction to approximate a random permutation. (As explained below, 3 rounds would not be sufficient.)

Let $H_i$ be a hash personalized by $i$, with maximum output length $\ell_H$ bytes. Let $G_i$ be a XOF (a hash function with extendable output length) based on $H$, personalized by $i$.

Define $\ell^\mathsf{MAX}_M = (2^{16} + 1) \cdot \ell_H$. For the instantiation using BLAKE2b defined below, $\ell^\mathsf{MAX}_M = 4194368$.

Given input $M$ of length $\ell_M$ bytes such that $38 \leq \ell_M \leq \ell^\mathsf{MAX}_M$, define $\mathsf{F4Jumble}(M)$ by:

- let $\ell_L = \mathsf{min}(\ell_H, \mathsf{floor}(\ell_M/2))$

- let $\ell_R = \ell_M - \ell_L$

- split $M$ into $a$ of length $\ell_L$ bytes and $b$ of length $\ell_R$ bytes

- let $x = b \oplus G_0(a)$

- let $y = a \oplus H_0(x)$

- let $d = x \oplus G_1(y)$

- let $c = y \oplus H_1(d)$

- return $c \,||\, d$.

The inverse function $\mathsf{F4Jumble}^{-1}$ is obtained in the usual way for a Feistel construction, by observing that $r = p \oplus q$ implies $p = r \oplus q$.

The first argument to BLAKE2b below is the personalization.

We instantiate $H_i(u)$ by $\mathsf{BLAKE2b‐}(8\ell_L)(\texttt{“UA\_F4Jumble\_H”} \,||\,$ $[i, 0, 0], u),$ with $\ell_H = 64$.

We instantiate $G_i(u)$ as the first $\ell_R$ bytes of the concatenation of $[\mathsf{BLAKE2b‐}512(\texttt{“UA\_F4Jumble\_G”} \,||\, [i] \,||\,$ $\mathsf{I2LEOSP}_{16}(j), u) \textsf{ for } j \textsf{ from}$ $0 \textsf{ up to } \mathsf{ceiling}(\ell_R/\ell_H)-1]$.

![../rendered/assets/images/zip-0316-f4.png](https://raw.githubusercontent.com/zcash/zips/a34cfc091434275120ff017c92c3b50d3cef623a/rendered/assets/images/zip-0316-f4.png)
Diagram of 4-round unkeyed Feistel construction

(In practice the lengths $\ell_L$ and $\ell_R$ will be roughly the same until $\ell_M$ is larger than $128$ bytes.)

<a id="usage-for-unified-addresses-ufvks-and-uivks"></a>

#### Usage for Unified Addresses, UFVKs, and UIVKs

In order to prevent the generic attack against nonmalleability, there needs to be some redundancy in the encoding. Therefore, the Producer of a Unified Address, UFVK, or UIVK appends the HRP, padded to 16 bytes with zero bytes, to the raw encoding, then applies $\mathsf{F4Jumble}$ before encoding the result with Bech32m.

The Consumer rejects any Bech32m-decoded byte sequence that is less than 38 bytes or greater than $\ell^\mathsf{MAX}_M$ bytes; otherwise it applies $\mathsf{F4Jumble}^{-1}$. It rejects any result that does not end in the expected 16-byte padding, before stripping these 16 bytes and parsing the result.

<a id="rationale-for-length-restrictions"></a>

#### Rationale for length restrictions

Click to show/hide

A minimum input length to $\mathsf{F4Jumble}^{-1}$ of 38 bytes allows for the minimum size of a UA/UVK Item encoding to be 22 bytes including the typecode and length, taking into account 16 bytes of padding. This allows for a UA containing only a Transparent P2PKH Receiver:

- Transparent P2PKH Receiver Item:
  
  
  
  - 1-byte typecode
  
  - 1-byte encoding of length
  
  - 20-byte transparent address hash

$\ell^\mathsf{MAX}_M$ bytes is the largest input/output size supported by $\mathsf{F4Jumble}$.

Allowing only a Transparent P2PKH Receiver is consistent with dropping the requirement to have at least one shielded Item in Revision 2 UA/UVKs ([see rationale](#rationale-for-dropping-the-at-least-one-shielded-item-restriction)).

Note that Revision 0 of this ZIP specified a minimum input length to $\mathsf{F4Jumble}^{-1}$ of 48 bytes. Since there were no sets of UA/UVK Item Encodings valid in Revision 0 to which a byte sequence (after removal of the 16-byte padding) of length between 22 and 31 bytes inclusive could be parsed, the difference between the 38 and 48-byte restrictions is not observable, other than potentially affecting which error is reported. A Consumer supporting Revision 2 of this specification MAY therefore apply either the 48-byte or 38-byte minimum to Revision 0 UA/UVKs.

<a id="heuristic-analysis"></a>

#### Heuristic analysis

A 3-round unkeyed Feistel, as shown, is not sufficient:

![../rendered/assets/images/zip-0316-f3.png](https://raw.githubusercontent.com/zcash/zips/a34cfc091434275120ff017c92c3b50d3cef623a/rendered/assets/images/zip-0316-f3.png)
Diagram of 3-round unkeyed Feistel construction

Suppose that an adversary has a target input/output pair $(a \,||\, b, c \,||\, d)$, and that the input to $H_0$ is $x$. By fixing $x$, we can obtain another pair $((a \oplus t) \,||\, b', (c \oplus t) \,||\, d')$ such that $a \oplus t$ is close to $a$ and $c \oplus t$ is close to $c$. ($\!b'$ and $d'$ will not be close to $b$ and $d$, but that isn't necessarily required for a valid attack.)

A 4-round Feistel thwarts this and similar attacks. Defining $x$ and $y$ as the intermediate values in the first diagram above:

- if $(x', y')$ are fixed to the same values as $(x, y)$, then $(a', b', c', d') = (a, b, c, d)$;

- if $x' = x$ but $y' \neq y$, then the adversary is able to introduce a controlled $\oplus$-difference $a \oplus a' = y \oplus y'$, but the other three pieces $(b, c, d)$ are all randomized, which is sufficient;

- if $y' = y$ but $x' \neq x$, then the adversary is able to introduce a controlled $\oplus$-difference $d \oplus d' = x \oplus x'$, but the other three pieces $(a, b, c)$ are all randomized, which is sufficient;

- if $x' \neq x$ and $y' \neq y$, all four pieces are randomized.

Note that the size of each piece is at least 19 bytes.

It would be possible to make an attack more expensive by making the work done by a Producer more expensive. (This wouldn't necessarily have to increase the work done by the Consumer.) However, given that Unified Addresses may need to be produced on constrained computing platforms, this was not considered to be beneficial overall.

The padding contains the HRP so that the HRP has the same protection against malleation as the rest of the address. This may help against cross-network attacks, or attacks that confuse addresses with viewing keys.

<a id="efficiency"></a>

#### Efficiency

The cost is dominated by 4 BLAKE2b compressions for $\ell_M \leq 128$ bytes. A Revision 0 UA containing a Transparent Address, a Sapling Address, and an Orchard Address, would have $\ell_M = 128$ bytes. A UA containing a Sapling Address and an Orchard Address would have $\ell_M = 106$ bytes.

For longer UAs (when other Receiver Types are added) or UVKs, the cost increases to 6 BLAKE2b compressions for $128 < \ell_M \leq 192$, and 10 BLAKE2b compressions for $192 < \ell_M \leq 256$, for example. The maximum cost for which the algorithm is defined would be 196608 BLAKE2b compressions at $\ell_M = \ell^\mathsf{MAX}_M$ bytes.

A naïve implementation of the $\mathsf{F4Jumble}^{-1}$ function would require roughly $\ell_M$ bytes plus the size of a BLAKE2b hash state. However, it is possible to reduce this by streaming the $d$ part of the jumbled encoding three times from a less memory-constrained device. It is essential that the streamed value of $d$ is the same on each pass, which can be verified using a Message Authentication Code (with key held only by the Consumer) or collision-resistant hash function. After the first pass of $d$, the implementation is able to compute $y$; after the second pass it is able to compute $a$; and the third allows it to compute and incrementally parse $b$. The maximum memory usage during this process would be 128 bytes plus two BLAKE2b hash states.

Since this streaming implementation of $\mathsf{F4Jumble}^{-1}$ is quite complicated, we do not require all Consumers to support streaming. If a Consumer implementation cannot support UAs / UVKs up to the maximum length, it MUST nevertheless support UAs / UVKs with $\ell_M$ of at least $256$ bytes. Note that this effectively defines two conformance levels to this specification. A full implementation will support UAs / UVKs up to the maximum length.

<a id="dependencies"></a>

#### Dependencies

BLAKE2b, with personalization and variable output length, is the only external dependency.

<a id="related-work"></a>

#### Related work

[Eliminating Random Permutation Oracles in the Even–Mansour Cipher](https://www.iacr.org/cryptodb/data/paper.php?pubkey=218)

- This paper argues that a 4-round unkeyed Feistel is sufficient to replace a random permutation in the Even–Mansour cipher construction.

[On the Round Security of Symmetric-Key Cryptographic Primitives](https://www.iacr.org/archive/crypto2000/18800377/18800377.pdf)

[LIONESS](https://www.cl.cam.ac.uk/~rja14/Papers/bear-lion.pdf) is a similarly structured 4-round unbalanced Feistel cipher.

<a id="reference-implementation"></a>

## Reference implementation

Revision 0:

- [https://github.com/zcash/librustzcash/pull/352](https://github.com/zcash/librustzcash/pull/352)

- [https://github.com/zcash/librustzcash/pull/416](https://github.com/zcash/librustzcash/pull/416)

Revision 1 (Withdrawn):

- [https://github.com/zcash/librustzcash/pull/1135](https://github.com/zcash/librustzcash/pull/1135)

Revision 2 (Draft):

- [https://github.com/zcash/librustzcash/pull/2199](https://github.com/zcash/librustzcash/pull/2199)

<a id="acknowledgements"></a>

## Acknowledgements

The authors would like to thank Benjamin Winston, Zooko Wilcox, Francisco Gindre, Marshall Gaucher, Joseph Van Geffen, Brad Miller, Deirdre Connolly, Teor, Eran Tromer, Conrado Gouvêa, and Marek Bielik for discussions on the subject of Unified Addresses and Unified Viewing Keys.

<a id="changelog"></a>

## Changelog

[Revision 1](/zip/316#Revision 1) of this specification originally defined addresses with capabilities essentially equivalent to the `tu` encoding specified in [Revision 2](/zip/316#Revision 2); however, this specification was rejected by the community on the grounds that users should be able to gain some sense of the privacy implications of an address that they are sharing by visual inspection, which unified addresses inhibit in general. [Revision 2](/zip/316#Revision 2) proposes the `zu` and `tu` prefixes to provide such visual distinguisability while retaining the benefits related to supporting protocol upgrades and expiry metadata for both shielded-only and transparent-transfer-permitting address types.

<a id="references"></a>

## 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"](https://www.rfc-editor.org/info/bcp14)[↩︎](/zip/316#fnref1)

2. [Zcash Protocol Specification, Version 2023.4.0. Section 2: Notation](protocol/protocol.pdf#notation)[↩︎](/zip/316#fnref2)

3. [Zcash Protocol Specification, Version 2023.4.0. Section 5.6: Encodings of Addresses and Keys](protocol/protocol.pdf#addressandkeyencoding)[↩︎](/zip/316#fnref3)

4. [ZIP 224: Orchard Shielded Protocol](/zip/224)[↩︎](/zip/316#fnref4)

5. [ZIP 321: Payment Request URIs](/zip/321)[↩︎](/zip/316#fnref5)

6. [ZIP 321: Payment Request URIs](/zip/321)[↩︎](/zip/316#fnref6)

7. [Zcash Protocol Specification, Version 2023.4.0 or later](protocol/protocol.pdf)[↩︎](/zip/316#fnref7)

8. [BIP 32: Hierarchical Deterministic Wallets](https://github.com/bitcoin/bips/blob/master/bip-0032.mediawiki)[↩︎](/zip/316#fnref8)

9. [BIP 44: Multi-Account Hierarchy for Deterministic Wallets](https://github.com/bitcoin/bips/blob/master/bip-0044.mediawiki)[↩︎](/zip/316#fnref9)

10. [BIP 388: Wallet Policies for Descriptor Wallets](https://github.com/bitcoin/bips/blob/master/bip-0388.mediawiki)[↩︎](/zip/316#fnref10)

11. [BIP 350: Bech32m format for v1+ witness addresses](https://github.com/bitcoin/bips/blob/master/bip-0350.mediawiki)[↩︎](/zip/316#fnref11)

12. [Zcash Protocol Specification, Version 2023.4.0. Section 5.6.4.2: Orchard Raw Payment Addresses](protocol/protocol.pdf#orchardpaymentaddrencoding)[↩︎](/zip/316#fnref12)

13. [Zcash Protocol Specification, Version 2023.4.0. Section 5.6.3.1: Sapling Payment Addresses](protocol/protocol.pdf#saplingpaymentaddrencoding)[↩︎](/zip/316#fnref13)

14. [Transactions: P2SH Scripts — Bitcoin Developer Guide](https://developer.bitcoin.org/devguide/transactions.html#pay-to-script-hash-p2sh)[↩︎](/zip/316#fnref14)

15. [Transactions: P2PKH Script Validation — Bitcoin Developer Guide](https://developer.bitcoin.org/devguide/transactions.html#p2pkh-script-validation)[↩︎](/zip/316#fnref15)

16. [BIP 350: Bech32m format for v1+ witness addresses](https://github.com/bitcoin/bips/blob/master/bip-0350.mediawiki)[↩︎](/zip/316#fnref16)

17. [ZIP 32: Shielded Hierarchical Deterministic Wallets — Sapling helper functions](/zip/32#sapling-helper-functions)[↩︎](/zip/316#fnref17)

18. [Zcash Protocol Specification, Version 2025.6.0 [NU6.1 proposal]. Section 10: Change History — 2025.6.0](protocol/protocol.pdf#2025.6.0)[↩︎](/zip/316#fnref18)

19. [BIP 388: Wallet Policies for Descriptor Wallets](https://github.com/bitcoin/bips/blob/master/bip-0388.mediawiki)[↩︎](/zip/316#fnref19)

20. [BIP 388: Wallet Policies for Descriptor Wallets](https://github.com/bitcoin/bips/blob/master/bip-0388.mediawiki)[↩︎](/zip/316#fnref20)

21. [BIP 32: Hierarchical Deterministic Wallets](https://github.com/bitcoin/bips/blob/master/bip-0032.mediawiki)[↩︎](/zip/316#fnref21)

22. [BIP 44: Multi-Account Hierarchy for Deterministic Wallets](https://github.com/bitcoin/bips/blob/master/bip-0044.mediawiki)[↩︎](/zip/316#fnref22)

23. [BIP 32: Hierarchical Deterministic Wallets — Serialization Format](https://github.com/bitcoin/bips/blob/master/bip-0032.mediawiki#serialization-format)[↩︎](/zip/316#fnref23)

24. [Variable length integer. Bitcoin Wiki](https://en.bitcoin.it/wiki/Protocol_documentation#Variable_length_integer)[↩︎](/zip/316#fnref24)

25. [ZIP 48: Transparent Multisig Wallets](/zip/48)[↩︎](/zip/316#fnref25)

26. [ZIP 312: FROST for Spend Authorization Multisignatures](/zip/312)[↩︎](/zip/316#fnref26)

27. [ZIP 2005: Orchard Quantum Recoverability — Usage with FROST](/zip/2005#usagewithfrost)[↩︎](/zip/316#fnref27)

28. [ZIP 211: Disabling Addition of New Value to the Sprout Chain Value Pool](/zip/211)[↩︎](/zip/316#fnref28)

29. [Zcash Protocol Specification, Version 2023.4.0 or later](protocol/protocol.pdf)[↩︎](/zip/316#fnref29)

30. [ZIP 48: Transparent Multisig Wallets](/zip/48)[↩︎](/zip/316#fnref30)

31. [ZIP 0: ZIP Process](/zip/0)[↩︎](/zip/316#fnref31)

32. [ZIP 0: ZIP Process](/zip/0)[↩︎](/zip/316#fnref32)

33. [Zcash Protocol Specification, Version 2023.4.0. Section 5.4.1.6: DiversifyHash^Sapling and DiversifyHash^Orchard Hash Functions](protocol/protocol.pdf#concretediversifyhash)[↩︎](/zip/316#fnref33)

34. [ZIP 203: Transaction Expiry — Changes for Blossom](/zip/203#changes-for-blossom)[↩︎](/zip/316#fnref34)

35. [ZIP 32: Shielded Hierarchical Deterministic Wallets — Sapling internal key derivation](/zip/32#sapling-internal-key-derivation)[↩︎](#fnref35)

36. [ZIP 32: Shielded Hierarchical Deterministic Wallets — Orchard internal key derivation](/zip/32#orchard-internal-key-derivation)[↩︎](#fnref36)

37. [BIP 32: Hierarchical Deterministic Wallets — Conventions](https://github.com/bitcoin/bips/blob/master/bip-0032.mediawiki#conventions)[↩︎](#fnref37)

38. [BIP 44: Multi-Account Hierarchy for Deterministic Wallets — Path levels: Change](https://github.com/bitcoin/bips/blob/master/bip-0044.mediawiki#change)[↩︎](#fnref38)

39. [Zcash Protocol Specification, Version 2023.4.0. Section 4.2.2: Sapling Key Components](protocol/protocol.pdf#saplingkeycomponents)[↩︎](#fnref39)

40. [Zcash Protocol Specification, Version 2023.4.0. Section 4.2.3: Orchard Key Components](protocol/protocol.pdf#orchardkeycomponents)[↩︎](#fnref40)

41. [BIP 32: Hierarchical Deterministic Wallets — Child key derivation (CKD) functions: Public parent key → public child key](https://github.com/bitcoin/bips/blob/master/bip-0032.mediawiki#public-parent-key--public-child-key)[↩︎](#fnref41)

42. [BIP 32: Hierarchical Deterministic Wallets — Child key derivation (CKD) functions: Public parent key → public child key](https://github.com/bitcoin/bips/blob/master/bip-0032.mediawiki#public-parent-key--public-child-key)[↩︎](#fnref42)

43. [ZIP 32: Shielded Hierarchical Deterministic Wallets — Sapling diversifier derivation](/zip/32#sapling-diversifier-derivation)[↩︎](#fnref43)

44. [Zcash Protocol Specification, Version 2023.4.0. Section 4.2.2: Sapling Key Components](protocol/protocol.pdf#saplingkeycomponents)[↩︎](#fnref44)

45. [Zcash Protocol Specification, Version 2023.4.0. Section 4.2.3: Orchard Key Components](protocol/protocol.pdf#orchardkeycomponents)[↩︎](#fnref45)

46. [BIP 44: Multi-Account Hierarchy for Deterministic Wallets — Path levels: Index](https://github.com/bitcoin/bips/blob/master/bip-0044.mediawiki#index)[↩︎](#fnref46)

47. [BIP 32: Hierarchical Deterministic Wallets — Child key derivation (CKD) functions: Public parent key → public child key](https://github.com/bitcoin/bips/blob/master/bip-0032.mediawiki#public-parent-key--public-child-key)[↩︎](#fnref47)

48. [BIP 32: Hierarchical Deterministic Wallets — Child key derivation (CKD) functions: Public parent key → public child key](https://github.com/bitcoin/bips/blob/master/bip-0032.mediawiki#public-parent-key--public-child-key)[↩︎](#fnref48)

49. [BIP 380: Output Script Descriptors General Operation](https://github.com/bitcoin/bips/blob/master/bip-0380.mediawiki)[↩︎](#fnref49)

50. [Zcash Protocol Specification, Version 2023.4.0. Section 4.7.2: Sending Notes (Sapling)](protocol/protocol.pdf#saplingsend)[↩︎](#fnref50)

51. [Zcash Protocol Specification, Version 2023.4.0. Section 4.7.3: Sending Notes (Orchard)](protocol/protocol.pdf#orchardsend)[↩︎](#fnref51)

52. [Zcash Protocol Specification, Version 2023.4.0. Section 4.7.2: Sending Notes (Sapling)](protocol/protocol.pdf#saplingsend)[↩︎](#fnref52)

53. [Zcash Protocol Specification, Version 2023.4.0. Section 4.7.3: Sending Notes (Orchard)](protocol/protocol.pdf#orchardsend)[↩︎](#fnref53)

54. [ZIP 32: Shielded Hierarchical Deterministic Wallets — Specification: Wallet usage](/zip/32#specification-wallet-usage)[↩︎](#fnref54)

55. [ZIP 315: Best Practices for Wallet Handling of Multiple Pools](/zip/315)[↩︎](#fnref55)

## Citation relationships

Cites: [ZIP 0](https://zip-tools-web.harpocrates.workers.dev/zip/0), [ZIP 32](https://zip-tools-web.harpocrates.workers.dev/zip/32), [ZIP 48](https://zip-tools-web.harpocrates.workers.dev/zip/48), [ZIP 203](https://zip-tools-web.harpocrates.workers.dev/zip/203), [ZIP 211](https://zip-tools-web.harpocrates.workers.dev/zip/211), [ZIP 224](https://zip-tools-web.harpocrates.workers.dev/zip/224), [ZIP 312](https://zip-tools-web.harpocrates.workers.dev/zip/312), [ZIP 315](https://zip-tools-web.harpocrates.workers.dev/zip/315), [ZIP 321](https://zip-tools-web.harpocrates.workers.dev/zip/321), [ZIP 2005](https://zip-tools-web.harpocrates.workers.dev/zip/2005)

Cited by: [ZIP 32](https://zip-tools-web.harpocrates.workers.dev/zip/32), [ZIP 216](https://zip-tools-web.harpocrates.workers.dev/zip/216), [ZIP 224](https://zip-tools-web.harpocrates.workers.dev/zip/224), [ZIP 252](https://zip-tools-web.harpocrates.workers.dev/zip/252), [ZIP 315](https://zip-tools-web.harpocrates.workers.dev/zip/315), [ZIP 320](https://zip-tools-web.harpocrates.workers.dev/zip/320), [ZIP 321](https://zip-tools-web.harpocrates.workers.dev/zip/321), [ZIP 325](https://zip-tools-web.harpocrates.workers.dev/zip/325)