zips/zip-0316.html

1014 lines
87 KiB
HTML
Raw Permalink Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

<!DOCTYPE html>
<html>
<head>
<title>ZIP 316: Unified Addresses and Unified Viewing Keys</title>
<meta charset="utf-8" />
<script src="https://cdn.jsdelivr.net/npm/mathjax@3/es5/tex-mml-chtml.js?config=TeX-AMS-MML_HTMLorMML"></script>
<meta name="viewport" content="width=device-width, initial-scale=1"><link rel="stylesheet" href="css/style.css"></head>
<body>
<section>
<pre>ZIP: 316
Title: Unified Addresses and Unified Viewing Keys
Owners: Daira Hopwood &lt;daira@electriccoin.co&gt;
Nathan Wilcox &lt;nathan@electriccoin.co&gt;
Taylor Hornby &lt;taylor@electriccoin.co&gt;
Jack Grigg &lt;jack@electriccoin.co&gt;
Sean Bowe &lt;sean@electriccoin.co&gt;
Kris Nuttycombe &lt;kris@electriccoin.co&gt;
Ying Tong Lai &lt;yingtong@electriccoin.co&gt;
Status: Final
Category: Standards / RPC / Wallet
Created: 2021-04-07
License: MIT
Discussions-To: &lt;<a href="https://github.com/zcash/zips/issues/482">https://github.com/zcash/zips/issues/482</a>&gt;</pre>
<section id="terminology"><h2><span class="section-heading">Terminology</span><span class="section-anchor"> <a rel="bookmark" href="#terminology"><img width="24" height="24" class="section-anchor" src="assets/images/section-anchor.png" alt=""></a></span></h2>
<p>The key words "MUST", "MUST NOT", and "SHOULD" in this document are to be interpreted as described in RFC 2119. <a id="id1" class="footnote_reference" href="#rfc2119">1</a></p>
<p>The terms below are to be interpreted as follows:</p>
<dl>
<dt>Recipient</dt>
<dd>A wallet or other software that can receive transfers of assets (such as ZEC) or in the future potentially other transaction-based state changes.</dd>
<dt>Producer</dt>
<dd>A wallet or other software that can create an Address (in which case it is normally also a Recipient) or a Viewing Key.</dd>
<dt>Consumer</dt>
<dd>A wallet or other software that can make use of an Address or Viewing Key that it is given.</dd>
<dt>Sender</dt>
<dd>A wallet or other software that can send transfers of assets, or other consensus state side-effects defined in future. Senders are a subset of Consumers.</dd>
<dt>Receiver</dt>
<dd>The necessary information to transfer an asset to a Recipient that generated that Receiver using a specific Transfer Protocol. Each Receiver is associated unambiguously with a specific Receiver Type, identified by an integer Typecode.</dd>
<dt>Receiver Encoding</dt>
<dd>An encoding of a Receiver as a byte sequence.</dd>
<dt>Viewing Key</dt>
<dd>The necessary information to view information about payments to an Address, or (in the case of a Full Viewing Key) from an Address. An Incoming Viewing Key can be derived from a Full Viewing Key, and an Address can be derived from an Incoming Viewing Key.</dd>
<dt>Viewing Key Encoding</dt>
<dd>An encoding of a Viewing Key as a byte sequence.</dd>
<dt>Metadata Encoding</dt>
<dd>An encoding of metadata that is not a Receiver or Viewing Key, but may affect the interpretation of the overall Unified Address/Viewing Key.</dd>
<dt>Item</dt>
<dd>An Receiver Encoding, Viewing Key Encoding, or Metadata Encoding.</dd>
<dt>Legacy Address</dt>
<dd>A Transparent, Sprout, or Sapling Address.</dd>
<dt>Unified Address (or UA)</dt>
<dd>A Unified Address combines multiple Receiver (and optionally Metadata) items.</dd>
<dt>Unified Full Viewing Key (or UFVK)</dt>
<dd>A Unified Full Viewing Key combines multiple Full Viewing Key (and optionally Metadata) items.</dd>
<dt>Unified Incoming Viewing Key (or UIVK)</dt>
<dd>A Unified Incoming Viewing Key combines multiple Incoming Viewing Key (and optionally Metadata) items.</dd>
<dt>Unified Viewing Key</dt>
<dd>Either a Unified Full Viewing Key or a Unified Incoming Viewing Key.</dd>
<dt>Address</dt>
<dd>Either a Legacy Address or a Unified Address.</dd>
<dt>Transfer Protocol</dt>
<dd>A specification of how a Sender can transfer assets to a Recipient. For example, the Transfer Protocol for a Sapling Receiver is the subset of the Zcash protocol required to successfully transfer ZEC using Sapling Spend/Output Transfers as specified in the Zcash Protocol Specification. (A single Zcash transaction can contain transfers of multiple Transfer Protocols. For example a t→z transaction that shields to the Sapling pool requires both Transparent and Sapling Transfer Protocols.)</dd>
<dt>Address Encoding</dt>
<dd>The externally visible encoding of an Address (e.g. as a string of characters or a QR code).</dd>
</dl>
<p>Notation for sequences, conversions, and arithmetic operations follows the Zcash protocol specification <a id="id2" class="footnote_reference" href="#protocol-notation">3</a>.</p>
</section>
<section id="abstract"><h2><span class="section-heading">Abstract</span><span class="section-anchor"> <a rel="bookmark" href="#abstract"><img width="24" height="24" class="section-anchor" src="assets/images/section-anchor.png" alt=""></a></span></h2>
<p>This proposal defines Unified Addresses, which bundle together Zcash Addresses of different types in a way that can be presented as a single Address Encoding. It also defines Unified Viewing Keys, which perform a similar function for Zcash viewing keys.</p>
</section>
<section id="motivation"><h2><span class="section-heading">Motivation</span><span class="section-anchor"> <a rel="bookmark" href="#motivation"><img width="24" height="24" class="section-anchor" src="assets/images/section-anchor.png" alt=""></a></span></h2>
<p>Up to and including the Canopy network upgrade, Zcash supported the following Payment Address types:</p>
<ul>
<li>Transparent Addresses (P2PKH and P2SH)</li>
<li>Sprout Addresses</li>
<li>Sapling Addresses</li>
</ul>
<p>Each of these has its own Address Encodings, as a string and as a QR code. (Since the QR code is derivable from the string encoding as described in <a id="id3" class="footnote_reference" href="#protocol-addressandkeyencoding">8</a>, for many purposes it suffices to consider the string encoding.)</p>
<p>The Orchard proposal <a id="id4" class="footnote_reference" href="#zip-0224">24</a> adds a new Address type, Orchard Addresses.</p>
<p>The difficulty with defining new Address Encodings for each Address type, is that end-users are forced to be aware of the various types, and in particular which types are supported by a given Consumer or Recipient. In order to make sure that transfers are completed successfully, users may be forced to explicitly generate Addresses of different types and re-distribute encodings of them, which adds significant friction and cognitive overhead to understanding and using Zcash.</p>
<p>The goals for a Unified Address standard are as follows:</p>
<ul>
<li>Simplify coordination between Recipients and Consumers by removing complexity from negotiating Address types.</li>
<li>Provide a “bridging mechanism” to allow shielded wallets to successfully interact with conformant Transparent-Only wallets.</li>
<li>Allow older conformant wallets to interact seamlessly with newer wallets.</li>
<li>Enable users of newer wallets to upgrade to newer transaction technologies and/or pools while maintaining seamless interactions with counterparties using older wallets.</li>
<li>Facilitate wallets to assume more sophisticated responsibilities for shielding and/or migrating user funds.</li>
<li>Allow wallets to potentially develop new transfer mechanisms without underlying protocol changes.</li>
<li>Support abstractions corresponding to a Unified Address that provide the functionality of Full Viewing Keys and Incoming Viewing Keys.</li>
<li>Provide forward compatibility that is standard for all wallets across a range of potential future features. Some examples might include Layer 2 features, cross-chain interoperability and bridging, and decentralized exchange.</li>
<li>Allow for Metadata items to be included in Unified Addresses/Viewing Keys in order to provide future extensibility.</li>
<li>The standard should work well for Zcash today and upcoming potential upgrades, and also anticipate even broader use cases down the road such as cross-chain functionality.</li>
</ul>
</section>
<section id="requirements"><h2><span class="section-heading">Requirements</span><span class="section-anchor"> <a rel="bookmark" href="#requirements"><img width="24" height="24" class="section-anchor" src="assets/images/section-anchor.png" alt=""></a></span></h2>
<section id="overview"><h3><span class="section-heading">Overview</span><span class="section-anchor"> <a rel="bookmark" href="#overview"><img width="24" height="24" class="section-anchor" src="assets/images/section-anchor.png" alt=""></a></span></h3>
<p>Unified Addresses specify multiple methods for payment to a Recipient's Wallet. The Sender's Wallet can then non-interactively select the method of payment.</p>
<p>Importantly, any wallet can support Unified Addresses, even when that wallet only supports a subset of payment methods for receiving and/or sending.</p>
<p>Despite having some similar characteristics, the Unified Address standard is orthogonal to Payment Request URIs <a id="id5" class="footnote_reference" href="#zip-0321">26</a> and similar schemes. Since Payment Requests encode addresses as alphanumeric strings, no change to ZIP 321 is required in order to use Unified Addresses in Payment Requests.</p>
</section>
<section id="concepts"><h3><span class="section-heading">Concepts</span><span class="section-anchor"> <a rel="bookmark" href="#concepts"><img width="24" height="24" class="section-anchor" src="assets/images/section-anchor.png" alt=""></a></span></h3>
<p>Wallets follow a model <em>Interaction Flow</em> as follows:</p>
<ol type="1">
<li>A Producer <em>generates</em> an Address.</li>
<li>The Producer <em>encodes</em> the Address.</li>
<li>The Producer wallet or human user <em>distributes</em> this Address Encoding, This ZIP leaves distribution mechanisms out of scope.</li>
<li>A Consumer wallet or user <em>imports</em> the Address Encoding through any of a variety of mechanisms (QR Code scanning, Payment URIs, cut-and-paste, or “in-band” protocols like <code>Reply-To</code> memos).</li>
<li>A Consumer wallet <em>decodes</em> the Address Encoding and performs validity checks.</li>
<li>(Perhaps later in time) if the Consumer wallet is a Sender, it can execute a transfer of ZEC (or other assets or protocol state changes) to the Address.</li>
</ol>
<p>Encodings of the same Address may be distributed zero or more times through different means. Zero or more Consumers may import Addresses. Zero or more of those (that are Senders) may execute a Transfer. A single Sender may execute multiple Transfers over time from a single import.</p>
<p>Steps 1 to 5 inclusive also apply to Interaction Flows for Unified Full Viewing Keys and Unified Incoming Viewing Keys.</p>
</section>
<section id="addresses"><h3><span class="section-heading">Addresses</span><span class="section-anchor"> <a rel="bookmark" href="#addresses"><img width="24" height="24" class="section-anchor" src="assets/images/section-anchor.png" alt=""></a></span></h3>
<p>A Unified Address (or UA for short) combines one or more Receivers.</p>
<p>When new Transport Protocols are introduced to the Zcash protocol after Unified Addresses are standardized, those should introduce new Receiver Types but <em>not</em> different Address types outside of the UA standard. There needs to be a compelling reason to deviate from the standard, since the benefits of UA come precisely from their applicability across all new protocol upgrades.</p>
</section>
<section id="receivers"><h3><span class="section-heading">Receivers</span><span class="section-anchor"> <a rel="bookmark" href="#receivers"><img width="24" height="24" class="section-anchor" src="assets/images/section-anchor.png" alt=""></a></span></h3>
<p>Every Wallet must properly <em>parse</em> a Unified Address or Unified Viewing Key containing unrecognized Items.</p>
<p>A Wallet may process unrecognized Items by indicating to the user their presence or similar information for usability or diagnostic purposes.</p>
</section>
<section id="transport-encoding"><h3><span class="section-heading">Transport Encoding</span><span class="section-anchor"> <a rel="bookmark" href="#transport-encoding"><img width="24" height="24" class="section-anchor" src="assets/images/section-anchor.png" alt=""></a></span></h3>
<p>The string encoding is “opaque” to human readers: it does <em>not</em> allow visual identification of which Receivers or Receiver Types are present.</p>
<p>The string encoding is resilient against typos, transcription errors, cut-and-paste errors, unanticipated truncation, or other anticipated UX hazards.</p>
<p>There is a well-defined encoding of a Unified Address (or UFVK or UIVK) as a QR Code, which produces QR codes that are reasonably compact and robust.</p>
<p>There is a well-defined transformation between the QR Code and string encodings in either direction.</p>
<p>The string encoding fits into ZIP-321 Payment URIs <a id="id6" class="footnote_reference" href="#zip-0321">26</a> and general URIs without introducing parse ambiguities.</p>
<p>The encoding must support sufficiently many Recipient Types to allow for reasonable future expansion.</p>
<p>The encoding must allow all wallets to safely and correctly parse out unrecognized Receiver Types well enough to ignore them.</p>
</section>
<section id="transfers"><h3><span class="section-heading">Transfers</span><span class="section-anchor"> <a rel="bookmark" href="#transfers"><img width="24" height="24" class="section-anchor" src="assets/images/section-anchor.png" alt=""></a></span></h3>
<p>When executing a Transfer the Sender selects a Receiver via a Selection process.</p>
<p>Given a valid UA, Selection must treat any unrecognized Item as though it were absent.</p>
<ul>
<li>This property is crucial for forward compatibility to ensure users who upgrade to newer protocols / UAs don't lose the ability to smoothly interact with older wallets.</li>
<li>This property is crucial for allowing Transparent-Only UA-Conformant wallets to interact with newer shielded wallets, removing a disincentive for adopting newer shielded wallets.</li>
<li>This property also allows Transparent-Only wallets to upgrade to shielded support without re-acquiring counterparty UAs. If they are re-acquired, the user flow and usability will be minimally disrupted.</li>
</ul>
</section>
<section id="experimental-usage"><h3><span class="section-heading">Experimental Usage</span><span class="section-anchor"> <a rel="bookmark" href="#experimental-usage"><img width="24" height="24" class="section-anchor" src="assets/images/section-anchor.png" alt=""></a></span></h3>
<p>Unified Addresses and Unified Viewing Keys must be able to include Receivers and Viewing Keys of experimental types, possibly alongside non-experimental ones. These experimental Receivers or Viewing Keys must be used only by wallets whose users have explicitly opted into the corresponding experiment.</p>
</section>
<section id="viewing-keys"><h3><span class="section-heading">Viewing Keys</span><span class="section-anchor"> <a rel="bookmark" href="#viewing-keys"><img width="24" height="24" class="section-anchor" src="assets/images/section-anchor.png" alt=""></a></span></h3>
<p>A Unified Full Viewing Key (resp. Unified Incoming Viewing Key) can be used in a similar way to a Full Viewing Key (resp. Incoming Viewing Key) as described in the Zcash Protocol Specification <a id="id7" class="footnote_reference" href="#protocol-nu5">2</a>.</p>
<p>For a Transparent P2PKH Address that is derived according to BIP 32 <a id="id8" class="footnote_reference" href="#bip-0032">27</a> and BIP 44 <a id="id9" class="footnote_reference" href="#bip-0044">30</a>, the nearest equivalent to a Full Viewing Key or Incoming Viewing Key for a given BIP 44 account is an extended public key, as defined in the section “Extended keys” of BIP 32. Therefore, UFVKs and UIVKs should be able to include such extended public keys.</p>
<p>A wallet should support deriving a UIVK from a UFVK, and a Unified Address from a UIVK.</p>
</section>
<section id="open-issues-and-known-concerns"><h3><span class="section-heading">Open Issues and Known Concerns</span><span class="section-anchor"> <a rel="bookmark" href="#open-issues-and-known-concerns"><img width="24" height="24" class="section-anchor" src="assets/images/section-anchor.png" alt=""></a></span></h3>
<p>Privacy impacts of transparent or cross-pool transactions, and the associated UX issues, will be addressed in ZIP 315 (in preparation).</p>
</section>
</section>
<section id="specification"><h2><span class="section-heading">Specification</span><span class="section-anchor"> <a rel="bookmark" href="#specification"><img width="24" height="24" class="section-anchor" src="assets/images/section-anchor.png" alt=""></a></span></h2>
<section id="encoding-of-unified-addresses"><h3><span class="section-heading">Encoding of Unified Addresses</span><span class="section-anchor"> <a rel="bookmark" href="#encoding-of-unified-addresses"><img width="24" height="24" class="section-anchor" src="assets/images/section-anchor.png" alt=""></a></span></h3>
<p>Rather than defining a Bech32 string encoding of Orchard Shielded Payment Addresses, we instead define a Unified Address format that is able to encode a set of Receivers of different types. This enables the Consumer of a Unified Address to choose the Receiver of the best type it supports, providing a better user experience as new Receiver Types are added in the future.</p>
<p>Assume that we are given a set of one or more Receiver Encodings for distinct types. That is, the set may optionally contain one Receiver of each of the Receiver Types in the following fixed Priority List:</p>
<ul>
<li>Typecode
<span class="math">\(\mathtt{0x03}\)</span>
— an Orchard raw address as defined in <a id="id10" class="footnote_reference" href="#protocol-orchardpaymentaddrencoding">10</a>;</li>
<li>Typecode
<span class="math">\(\mathtt{0x02}\)</span>
— a Sapling raw address as defined in <a id="id11" class="footnote_reference" href="#protocol-saplingpaymentaddrencoding">9</a>;</li>
<li>Typecode
<span class="math">\(\mathtt{0x01}\)</span>
— a Transparent P2SH address, <em>or</em> Typecode
<span class="math">\(\mathtt{0x00}\)</span>
— a Transparent P2PKH address.</li>
</ul>
<p>If, and only if, the user of a Producer or Consumer wallet explicitly opts into an experiment as described in <a href="#experimental-usage">Experimental Usage</a>, the specification of the experiment MAY include additions to the above Priority List (such additions SHOULD maintain the intent of preferring more recent shielded protocols).</p>
<p>We say that a Receiver Type is “preferred” over another when it appears earlier in this Priority List (as potentially modified by experiments).</p>
<p>The Sender of a payment to a Unified Address MUST use the Receiver of the most preferred Receiver Type that it supports from the set.</p>
<p>For example, consider a wallet that supports sending funds to Orchard Receivers, and does not support sending to any Receiver Type that is preferred over Orchard. If that wallet is given a UA that includes an Orchard Receiver and possibly other Receivers, it MUST send to the Orchard Receiver.</p>
<p>The raw encoding of a Unified Address is a concatenation of
<span class="math">\((\mathtt{typecode}, \mathtt{length}, \mathtt{addr})\)</span>
encodings of the consituent Receivers, in ascending order of Typecode:</p>
<ul>
<li>
<span class="math">\(\mathtt{typecode} : \mathtt{compactSize}\)</span>
— the Typecode from the above Priority List;</li>
<li>
<span class="math">\(\mathtt{length} : \mathtt{compactSize}\)</span>
— the length in bytes of
<span class="math">\(\mathtt{addr};\)</span>
</li>
<li>
<span class="math">\(\mathtt{addr} : \mathtt{byte[length]}\)</span>
— the Receiver Encoding.</li>
</ul>
<p>The values of the
<span class="math">\(\mathtt{typecode}\)</span>
and
<span class="math">\(\mathtt{length}\)</span>
fields MUST be less than or equal to
<span class="math">\(\mathtt{0x2000000}.\)</span>
(The limitation on the total length of encodings described below imposes a smaller limit for
<span class="math">\(\mathtt{length}\)</span>
in practice.)</p>
<p>A Receiver Encoding is the raw encoding of a Shielded Payment Address, or the
<span class="math">\(160\!\)</span>
-bit script hash of a P2SH address <a id="id12" class="footnote_reference" href="#p2sh">35</a>, or the
<span class="math">\(160\!\)</span>
-bit validating key hash of a P2PKH address <a id="id13" class="footnote_reference" href="#p2pkh">34</a>.</p>
<p>Let <code>padding</code> be the Human-Readable Part of the Unified Address in US-ASCII, padded to 16 bytes with zero bytes. We append <code>padding</code> to the concatenated encodings, and then apply the
<span class="math">\(\mathsf{F4Jumble}\)</span>
algorithm as described in <a href="#jumbling">Jumbling</a>. (In order for the limitation on the
<span class="math">\(\mathsf{F4Jumble}\)</span>
input size to be met, the total length of encodings MUST be at most
<span class="math">\(\ell^\mathsf{MAX}_M - 16\)</span>
bytes, where
<span class="math">\(\ell^\mathsf{MAX}_M\)</span>
is defined in <a href="#jumbling">Jumbling</a>.) The output is then encoded with Bech32m <a id="id14" class="footnote_reference" href="#bip-0350">33</a>, ignoring any length restrictions. This is chosen over Bech32 in order to better handle variable-length inputs.</p>
<p>To decode a Unified Address Encoding, a Consumer MUST use the following procedure:</p>
<ul>
<li>Decode using Bech32m, rejecting any address with an incorrect checksum.</li>
<li>Apply
<span class="math">\(\mathsf{F4Jumble}^{-1}\)</span>
(this can also reject if the input is not in the correct range of lengths).</li>
<li>Let <code>padding</code> be the Human-Readable Part, padded to 16 bytes as for encoding. If the result ends in <code>padding</code>, remove these 16 bytes; otherwise reject.</li>
<li>Parse the result as a raw encoding as described above, rejecting the entire Unified Address if it does not parse correctly.</li>
</ul>
<p>For Unified Addresses on Mainnet, the Human-Readable Part (as defined in <a id="id15" class="footnote_reference" href="#bip-0350">33</a>) is “<code>u</code>”. For Unified Addresses on Testnet, the Human-Readable Part is “<code>utest</code>”.</p>
<p>A wallet MAY allow its user(s) to configure which Receiver Types it can send to. It MUST NOT allow the user(s) to change the order of the Priority List used to choose the Receiver Type, except by opting into experiments.</p>
</section>
<section id="encoding-of-unified-full-incoming-viewing-keys"><h3><span class="section-heading">Encoding of Unified Full/Incoming Viewing Keys</span><span class="section-anchor"> <a rel="bookmark" href="#encoding-of-unified-full-incoming-viewing-keys"><img width="24" height="24" class="section-anchor" src="assets/images/section-anchor.png" alt=""></a></span></h3>
<p>Unified Full or Incoming Viewing Keys are encoded and decoded analogously to Unified Addresses. A Consumer MUST use the decoding procedure from the previous section. For Viewing Keys, a Consumer will normally take the union of information provided by all contained Receivers, and therefore the Priority List defined in the previous section is not used.</p>
<p>For each FVK Type or IVK Type currently defined in this specification, the same Typecode is used as for the corresponding Receiver Type in a Unified Address. Additional FVK Types and IVK Types MAY be defined in future, and these will not necessarily use the same Typecode as the corresponding Unified Address.</p>
<p>The following FVK or IVK Encodings are used in place of the
<span class="math">\(\mathtt{addr}\)</span>
field:</p>
<ul>
<li>An Orchard FVK or IVK Encoding, with Typecode
<span class="math">\(\mathtt{0x03},\)</span>
is is the raw encoding of the Orchard Full Viewing Key or Orchard Incoming Viewing Key respectively.</li>
<li>A Sapling FVK Encoding, with Typecode
<span class="math">\(\mathtt{0x02},\)</span>
is the encoding of
<span class="math">\((\mathsf{ak}, \mathsf{nk}, \mathsf{ovk}, \mathsf{dk})\)</span>
given by
<span class="math">\(\mathsf{EncodeExtFVKParts}(\mathsf{ak}, \mathsf{nk}, \mathsf{ovk}, \mathsf{dk})\)</span>
, where
<span class="math">\(\mathsf{EncodeExtFVKParts}\)</span>
is defined in <a id="id16" class="footnote_reference" href="#zip-0032-sapling-helper-functions">14</a>. This SHOULD be derived from the Extended Full Viewing Key at the Account level of the ZIP 32 hierarchy.</li>
<li>A Sapling IVK Encoding, also with Typecode
<span class="math">\(\mathtt{0x02},\)</span>
is an encoding of
<span class="math">\((\mathsf{dk}, \mathsf{ivk})\)</span>
given by
<span class="math">\(\mathsf{I2LEOSP}_{88}(\mathsf{dk})\,||\,\mathsf{I2LEOSP}_{256}(\mathsf{ivk}).\)</span>
</li>
<li>There is no defined way to represent a Viewing Key for a Transparent P2SH Address in a UFVK or UIVK (because P2SH Addresses cannot be diversified in an unlinkable way). The Typecode
<span class="math">\(\mathtt{0x01}\)</span>
MUST NOT be included in a UFVK or UIVK by Producers, and MUST be treated as unrecognized by Consumers.</li>
<li>For Transparent P2PKH Addresses that are derived according to BIP 32 <a id="id17" class="footnote_reference" href="#bip-0032">27</a> and BIP 44 <a id="id18" class="footnote_reference" href="#bip-0044">30</a>, the FVK and IVK Encodings have Typecode
<span class="math">\(\mathtt{0x00}.\)</span>
Both of these are encodings of the chain code and public key
<span class="math">\((\mathsf{c}, \mathsf{pk})\)</span>
given by
<span class="math">\(\mathsf{c}\,||\,\mathsf{ser_P}(\mathsf{pk})\)</span>
. (This is the same as the last 65 bytes of the extended public key format defined in section “Serialization format” of BIP 32 <a id="id19" class="footnote_reference" href="#bip-0032-serialization-format">28</a>.) However, the FVK uses the key at the Account level, i.e. at path
<span class="math">\(m / 44' / coin\_type' / account'\)</span>
, while the IVK uses the external (non-change) child key at the Change level, i.e. at path
<span class="math">\(m / 44' / coin\_type' / account' / 0\)</span>
.</li>
</ul>
<p>The Human-Readable Parts (as defined in <a id="id20" class="footnote_reference" href="#bip-0350">33</a>) of Unified Viewing Keys are defined as follows:</p>
<ul>
<li><code>uivk</code>” for Unified Incoming Viewing Keys on Mainnet;</li>
<li><code>uivktest</code>” for Unified Incoming Viewing Keys on Testnet;</li>
<li><code>uview</code>” for Unified Full Viewing Keys on Mainnet;</li>
<li><code>uviewtest</code>” for Unified Full Viewing Keys on Testnet.</li>
</ul>
<section id="rationale-for-address-derivation"><h4><span class="section-heading">Rationale for address derivation</span><span class="section-anchor"> <a rel="bookmark" href="#rationale-for-address-derivation"><img width="24" height="24" class="section-anchor" src="assets/images/section-anchor.png" alt=""></a></span></h4>
<p>The design of address derivation is designed to maintain unlinkability between addresses derived from the same UIVK, to the extent possible. (This is only partially achieved if the UA contains a Transparent P2PKH Address, since the on-chain transaction graph can potentially be used to link transparent addresses.)</p>
<p>Note that it may be difficult to retain this property for Metadata Items, and this should be taken into account in the design of such Items.</p>
</section>
</section>
<section id="requirements-for-both-unified-addresses-and-unified-viewing-keys"><h3><span class="section-heading">Requirements for both Unified Addresses and Unified Viewing Keys</span><span class="section-anchor"> <a rel="bookmark" href="#requirements-for-both-unified-addresses-and-unified-viewing-keys"><img width="24" height="24" class="section-anchor" src="assets/images/section-anchor.png" alt=""></a></span></h3>
<ul>
<li>A Unified Address or Unified Viewing Key MUST contain at least one shielded item (Typecodes
<span class="math">\(\mathtt{0x02}\)</span>
and
<span class="math">\(\mathtt{0x03}\)</span>
). The rationale is that the existing P2SH and P2PKH transparent-only address formats, and the existing P2PKH extended public key format, suffice for representing transparent items and are already supported by the existing ecosystem.</li>
<li>The
<span class="math">\(\mathtt{typecode}\)</span>
and
<span class="math">\(\mathtt{length}\)</span>
fields are encoded as
<span class="math">\(\mathtt{compactSize}.\)</span>
<a id="id21" class="footnote_reference" href="#bitcoin-compactsize">36</a> (Although existing Receiver Encodings and Viewing Key Encodings are all less than 256 bytes and so could use a one-byte length field, encodings for experimental types may be longer.)</li>
<li>Within a single UA or UVK, all HD-derived Receivers, FVKs, and IVKs SHOULD represent an Address or Viewing Key for the same account (as used in the ZIP 32 or BIP 44 Account level).</li>
<li>For Transparent Addresses, the Receiver Encoding does not include the first two bytes of a raw encoding.</li>
<li>There is intentionally no Typecode defined for a Sprout Shielded Payment Address or Sprout Incoming Viewing Key. Since it is no longer possible (since activation of ZIP 211 in the Canopy network upgrade <a id="id22" class="footnote_reference" href="#zip-0211">23</a>) to send funds into the Sprout chain value pool, this would not be generally useful.</li>
<li>Consumers MUST ignore constituent Items with Typecodes they do not recognize.</li>
<li>Consumers MUST reject Unified Addresses/Viewing Keys in which the same Typecode appears more than once, or that include both P2SH and P2PKH Transparent Addresses, or that contain only a Transparent Address.</li>
<li>Consumers MUST reject Unified Addresses/Viewing Keys in which <em>any</em> constituent Item does not meet the validation requirements of its encoding, as specified in this ZIP and the Zcash Protocol Specification <a id="id23" class="footnote_reference" href="#protocol-nu5">2</a>.</li>
<li>Consumers MUST reject Unified Addresses/Viewing Keys in which the constituent Items are not ordered in ascending Typecode order. Note that this is different to priority order, and does not affect which Receiver in a Unified Address should be used by a Sender.</li>
<li>There MUST NOT be additional bytes at the end of the raw encoding that cannot be interpreted as specified above.</li>
<li>If the encoding of a Unified Address/Viewing Key is shown to a user in an abridged form due to lack of space, at least the first 20 characters MUST be included.</li>
</ul>
<section id="rationale-for-item-ordering"><h4><span class="section-heading">Rationale for item ordering</span><span class="section-anchor"> <a rel="bookmark" href="#rationale-for-item-ordering"><img width="24" height="24" class="section-anchor" src="assets/images/section-anchor.png" alt=""></a></span></h4>
<p>The rationale for requiring Items to be canonically ordered by Typecode is that it enables implementations to use an in-memory representation that discards ordering, while retaining the same round-trip serialization of a UA / UVK (provided that unrecognized items are retained).</p>
</section>
<section id="rationale-for-showing-at-least-the-first-20-characters"><h4><span class="section-heading">Rationale for showing at least the first 20 characters</span><span class="section-anchor"> <a rel="bookmark" href="#rationale-for-showing-at-least-the-first-20-characters"><img width="24" height="24" class="section-anchor" src="assets/images/section-anchor.png" alt=""></a></span></h4>
<p>Showing fewer than 20 characters of a UA/UVK would potentially allow practical attacks in which the adversary constructs another UA/UVK that matches in the characters shown. When a UA/UVK is abridged it is preferable to show a prefix rather than some other part, both for a more consistent user experience across wallets, and because security analysis of the cost of partial UA/UVK matching attacks is more complicated if checksum characters are included in the characters that are compared.</p>
</section>
</section>
<section id="adding-new-types"><h3><span class="section-heading">Adding new types</span><span class="section-anchor"> <a rel="bookmark" href="#adding-new-types"><img width="24" height="24" class="section-anchor" src="assets/images/section-anchor.png" alt=""></a></span></h3>
<p>It is intended that new Receiver Types and Viewing Key Types SHOULD be introduced either by a modification to this ZIP or by a new ZIP, in accordance with the ZIP Process <a id="id24" class="footnote_reference" href="#zip-0000">13</a>.</p>
<p>For experimentation prior to proposing a ZIP, experimental types MAY be added using the reserved Typecodes
<span class="math">\(\mathtt{0xFFFA}\)</span>
to
<span class="math">\(\mathtt{0xFFFF}\)</span>
inclusive. This provides for six simultaneous experiments, which can be referred to as experiments A to F. This should be sufficient because experiments are expected to be reasonably short-term, and should otherwise be either standardized in a ZIP (and allocated a Typecode outside this reserved range) or discontinued.</p>
<p>New types SHOULD maintain the same distinction between FVK and IVK authority as existing types, i.e. an FVK is intended to give access to view all transactions to and from the address, while an IVK is intended to give access only to view incoming payments (as opposed to change).</p>
</section>
<section id="metadata-items"><h3><span class="section-heading">Metadata Items</span><span class="section-anchor"> <a rel="bookmark" href="#metadata-items"><img width="24" height="24" class="section-anchor" src="assets/images/section-anchor.png" alt=""></a></span></h3>
<p>Typecodes
<span class="math">\(\mathtt{0xE0}\)</span>
to
<span class="math">\(\mathtt{0xFC}\)</span>
inclusive are reserved to indicate Metadata Items other than Receivers or Viewing Keys. These items MAY affect the overall interpretation of the UA / UVK (for example, by specifying an expiration date).</p>
<p>Since Metadata Items are not Receivers, they MUST NOT be selected by a Sender when choosing a Receiver to send to, and since they are not Viewing Keys, they MUST NOT provide additional authority to view information about transactions.</p>
<p>Currently no Metadata Types are defined. New Metadata Types SHOULD be introduced either by a modification to this ZIP or by a new ZIP, in accordance with the ZIP Process <a id="id25" class="footnote_reference" href="#zip-0000">13</a>.</p>
</section>
<section id="deriving-internal-keys"><h3><span class="section-heading">Deriving Internal Keys</span><span class="section-anchor"> <a rel="bookmark" href="#deriving-internal-keys"><img width="24" height="24" class="section-anchor" src="assets/images/section-anchor.png" alt=""></a></span></h3>
<p>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.</p>
<p>We desire the following properties for viewing authority of both shielded and transparent key trees:</p>
<ul>
<li>A holder of an FVK can derive external and internal IVKs, and external and internal
<span class="math">\(\mathsf{ovk}\)</span>
components.</li>
<li>A holder of the external IVK cannot derive the internal IVK, or any of the
<span class="math">\(\mathsf{ovk}\)</span>
components.</li>
<li>A holder of the external
<span class="math">\(\mathsf{ovk}\)</span>
component cannot derive the internal
<span class="math">\(\mathsf{ovk}\)</span>
component, or any of the IVKs.</li>
</ul>
<p>For shielded keys, these properties are achieved by the one-wayness of
<span class="math">\(\mathsf{PRF^{expand}}\)</span>
and of
<span class="math">\(\mathsf{CRH^{ivk}}\)</span>
or
<span class="math">\(\mathsf{Commit^{ivk}}\)</span>
(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="id26" class="footnote_reference" href="#zip-0032-sapling-internal-key-derivation">17</a> and "Orchard internal key derivation" <a id="id27" class="footnote_reference" href="#zip-0032-orchard-internal-key-derivation">19</a> sections of ZIP 32.</p>
<p>To satisfy the above properties for transparent (P2PKH) keys, we derive the external and internal
<span class="math">\(\mathsf{ovk}\)</span>
components from the transparent FVK
<span class="math">\((\mathsf{c}, \mathsf{pk})\)</span>
(described in <a href="#encoding-of-unified-full-incoming-viewing-keys">Encoding of Unified Full/Incoming Viewing Keys</a>) as follows:</p>
<ul>
<li>Let
<span class="math">\(I_\mathsf{ovk} = \mathsf{PRF^{expand}}_{\mathsf{LEOS2BSP}_{256}(\mathsf{c})}\big([\mathtt{0xd0}] \,||\, \mathsf{ser_P}(\mathsf{pk})\big)\)</span>
where
<span class="math">\(\mathsf{ser_P}(pk)\)</span>
is
<span class="math">\(33\)</span>
bytes, as specified in <a id="id28" class="footnote_reference" href="#bip-0032-serialization-format">28</a>.</li>
<li>Let
<span class="math">\(\mathsf{ovk_{external}}\)</span>
be the first
<span class="math">\(32\)</span>
bytes of
<span class="math">\(I_\mathsf{ovk}\)</span>
and let
<span class="math">\(\mathsf{ovk_{internal}}\)</span>
be the remaining
<span class="math">\(32\)</span>
bytes of
<span class="math">\(I_\mathsf{ovk}\)</span>
.</li>
</ul>
<p>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="id29" class="footnote_reference" href="#bip-0044-path-change">31</a>. 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.</p>
</section>
<section id="deriving-a-uivk-from-a-ufvk"><h3><span class="section-heading">Deriving a UIVK from a UFVK</span><span class="section-anchor"> <a rel="bookmark" href="#deriving-a-uivk-from-a-ufvk"><img width="24" height="24" class="section-anchor" src="assets/images/section-anchor.png" alt=""></a></span></h3>
<p>The following derivations are applied to each component FVK:</p>
<ul>
<li>For a Sapling FVK, the corresponding Sapling IVK is obtained as specified in <a id="id30" class="footnote_reference" href="#protocol-saplingkeycomponents">4</a>.</li>
<li>For an Orchard FVK, the corresponding Orchard IVK is obtained as specified in <a id="id31" class="footnote_reference" href="#protocol-orchardkeycomponents">5</a>.</li>
<li>For a Transparent P2PKH FVK, the corresponding Transparent P2PKH IVK is obtained by deriving the child key with non-hardened index
<span class="math">\(0\)</span>
as described in <a id="id32" class="footnote_reference" href="#bip-0032-public-to-public">29</a>.</li>
</ul>
<p>In each case, the Typecode remains the same as in the FVK.</p>
<p>Items (including Metadata Items) that are unrecognized by a given Consumer, or that are specified in experiments that the user has not opted into (see <a href="#experimental-usage">Experimental Usage</a>), MUST be dropped when deriving a UIVK from a UFVK.</p>
</section>
<section id="deriving-a-unified-address-from-a-uivk"><h3><span class="section-heading">Deriving a Unified Address from a UIVK</span><span class="section-anchor"> <a rel="bookmark" href="#deriving-a-unified-address-from-a-uivk"><img width="24" height="24" class="section-anchor" src="assets/images/section-anchor.png" alt=""></a></span></h3>
<p>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,</p>
<ul>
<li>A Sapling diversifier index MUST generate a valid diversifier as defined in ZIP 32 section “Sapling diversifier derivation” <a id="id33" class="footnote_reference" href="#zip-0032-sapling-diversifier-derivation">16</a>.</li>
<li>A Transparent diversifier index MUST be in the range
<span class="math">\(0\)</span>
to
<span class="math">\(2^{31} - 1\)</span>
inclusive.</li>
<li>There are no additional constraints on an Orchard diversifier index.</li>
</ul>
<p>The following derivations are applied to each component IVK using the diversifier index:</p>
<ul>
<li>For a Sapling IVK, the corresponding Sapling Receiver is obtained as specified in <a id="id34" class="footnote_reference" href="#protocol-saplingkeycomponents">4</a>.</li>
<li>For an Orchard IVK, the corresponding Orchard Receiver is obtained as specified in <a id="id35" class="footnote_reference" href="#protocol-orchardkeycomponents">5</a>.</li>
<li>For a Transparent P2PKH IVK, the diversifier index is used as a BIP 44 child key index at the Index level <a id="id36" class="footnote_reference" href="#bip-0044-path-index">32</a> to derive the corresponding Transparent P2PKH Receiver. As is usual for derivations below the BIP 44 Account level, non-hardened (public) derivation <a id="id37" class="footnote_reference" href="#bip-0032-public-to-public">29</a> 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
<span class="math">\(m / 44' / \mathit{coin\_type\kern0.05em'} / \mathit{account\kern0.1em'} / 0 / \mathit{diversifier\_index}.\)</span>
</li>
</ul>
<p>In each case, the Typecode remains the same as in the IVK.</p>
<p>Items (including Metadata Items) that are unrecognized by a given Consumer, or that are specified in experiments that the user has not opted into (see <a href="#experimental-usage">Experimental Usage</a>), MUST be dropped when deriving a Receiver from a UIVK.</p>
</section>
<section id="usage-of-outgoing-viewing-keys"><h3><span class="section-heading">Usage of Outgoing Viewing Keys</span><span class="section-anchor"> <a rel="bookmark" href="#usage-of-outgoing-viewing-keys"><img width="24" height="24" class="section-anchor" src="assets/images/section-anchor.png" alt=""></a></span></h3>
<p>When a Sender constructs a transaction that creates Sapling or Orchard notes, it uses an outgoing viewing key, as described in <a id="id38" class="footnote_reference" href="#protocol-saplingsend">6</a> and <a id="id39" class="footnote_reference" href="#protocol-orchardsend">7</a>, 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.</p>
<p>However, the specification of which outgoing viewing key should be used is left somewhat open in <a id="id40" class="footnote_reference" href="#protocol-saplingsend">6</a> and <a id="id41" class="footnote_reference" href="#protocol-orchardsend">7</a>; in particular, it was unclear whether transfers should be considered as being sent from an address, or from a ZIP 32 account <a id="id42" class="footnote_reference" href="#zip-0032-key-path-levels">20</a>. 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="id43" class="footnote_reference" href="#zip-0315">25</a>.)</p>
<p>Here we refine the protocol specification in order to allow more precise determination of viewing authority for UFVKs.</p>
<p>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.</p>
<p>The Sender also determines a "preferred sending protocol" —one of "transparent", "Sapling", or "Orchard"— corresponding to the most preferred Receiver Type (as given in <a href="#encoding-of-unified-addresses">Encoding of Unified Addresses</a>) of any funds sent in the transaction.</p>
<p>If the sending Account has been determined, then the Sender SHOULD use the external or internal
<span class="math">\(\mathsf{ovk}\)</span>
(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).</p>
<p>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
<span class="math">\(\mathsf{ovk}\)</span>
(according to the type of transfer) of the full viewing key for that address.</p>
</section>
<section id="jumbling"><h3><span class="section-heading">Jumbling</span><span class="section-anchor"> <a rel="bookmark" href="#jumbling"><img width="24" height="24" class="section-anchor" src="assets/images/section-anchor.png" alt=""></a></span></h3>
<p>Security goal (<strong>near second preimage resistance</strong>):</p>
<ul>
<li>An adversary is given
<span class="math">\(q\)</span>
Unified Addresses/Viewing Keys, generated honestly.</li>
<li>The attack goal is to produce a “partially colliding” valid Unified Address/Viewing Key that:
<ol suffix=")" type="a">
<li>has a string encoding matching that of <em>one of</em> the input Addresses/Viewing Keys on some subset of characters (for concreteness, consider the first
<span class="math">\(n\)</span>
and last
<span class="math">\(m\)</span>
characters, up to some bound on
<span class="math">\(n+m\)</span>
);</li>
<li>is controlled by the adversary (for concreteness, the adversary knows <em>at least one</em> of the private keys of the constituent Addresses).</li>
</ol>
</li>
</ul>
<p>Security goal (<strong>nonmalleability</strong>):</p>
<ul>
<li>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.</li>
</ul>
<section id="discussion"><h4><span class="section-heading">Discussion</span><span class="section-anchor"> <a rel="bookmark" href="#discussion"><img width="24" height="24" class="section-anchor" src="assets/images/section-anchor.png" alt=""></a></span></h4>
<p>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
<span class="math">\(q\)</span>
targets. It may be possible to improve on this attack by making use of properties of checksums, etc.</p>
<p>The generic attack puts an upper bound on the achievable security: if it takes work
<span class="math">\(w\)</span>
to produce and verify a UA / UVK, and the size of the character set is
<span class="math">\(c,\)</span>
then the generic attack costs
<span class="math">\(\sim \frac{w \cdot
c^{n+m}}{q}.\)</span>
</p>
<p>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
<span class="math">\(w\)</span>
defined as above, the cost is
<span class="math">\(w/p\)</span>
where
<span class="math">\(p\)</span>
is the probability that a random decoding is of the required form.</p>
</section>
<section id="solution"><h4><span class="section-heading">Solution</span><span class="section-anchor"> <a rel="bookmark" href="#solution"><img width="24" height="24" class="section-anchor" src="assets/images/section-anchor.png" alt=""></a></span></h4>
<p>We use an unkeyed 4-round Feistel construction to approximate a random permutation. (As explained below, 3 rounds would not be sufficient.)</p>
<p>Let
<span class="math">\(H_i\)</span>
be a hash personalized by
<span class="math">\(i,\)</span>
with maximum output length
<span class="math">\(\ell_H\)</span>
bytes. Let
<span class="math">\(G_i\)</span>
be a XOF (a hash function with extendable output length) based on
<span class="math">\(H,\)</span>
personalized by
<span class="math">\(i.\)</span>
</p>
<p>Define
<span class="math">\(\ell^\mathsf{MAX}_M = (2^{16} + 1) \cdot \ell_H.\)</span>
For the instantiation using BLAKE2b defined below,
<span class="math">\(\ell^\mathsf{MAX}_M = 4194368.\)</span>
</p>
<p>Given input
<span class="math">\(M\)</span>
of length
<span class="math">\(\ell_M\)</span>
bytes such that
<span class="math">\(48 \leq \ell_M \leq \ell^\mathsf{MAX}_M,\)</span>
define
<span class="math">\(\mathsf{F4Jumble}(M)\)</span>
by:</p>
<ul>
<li>let
<span class="math">\(\ell_L = \mathsf{min}(\ell_H, \mathsf{floor}(\ell_M/2))\)</span>
</li>
<li>let
<span class="math">\(\ell_R = \ell_M - \ell_L\)</span>
</li>
<li>split
<span class="math">\(M\)</span>
into
<span class="math">\(a\)</span>
of length
<span class="math">\(\ell_L\)</span>
bytes and
<span class="math">\(b\)</span>
of length
<span class="math">\(\ell_R\)</span>
bytes</li>
<li>let
<span class="math">\(x = b \oplus G_0(a)\)</span>
</li>
<li>let
<span class="math">\(y = a \oplus H_0(x)\)</span>
</li>
<li>let
<span class="math">\(d = x \oplus G_1(y)\)</span>
</li>
<li>let
<span class="math">\(c = y \oplus H_1(d)\)</span>
</li>
<li>return
<span class="math">\(c \,||\, d.\)</span>
</li>
</ul>
<p>The inverse function
<span class="math">\(\mathsf{F4Jumble}^{-1}\)</span>
is obtained in the usual way for a Feistel construction, by observing that
<span class="math">\(r = p \oplus q\)</span>
implies
<span class="math">\(p = r \oplus q.\)</span>
</p>
<p>The first argument to BLAKE2b below is the personalization.</p>
<p>We instantiate
<span class="math">\(H_i(u)\)</span>
by
<span class="math">\(\mathsf{BLAKE2b}(8\ell_L)(\texttt{“UA_F4Jumble_H”} \,||\,\)</span>
<span class="math">\([i, 0, 0], u),\)</span>
with
<span class="math">\(\ell_H = 64.\)</span>
</p>
<p>We instantiate
<span class="math">\(G_i(u)\)</span>
as the first
<span class="math">\(\ell_R\)</span>
bytes of the concatenation of
<span class="math">\([\mathsf{BLAKE2b}512(\texttt{“UA_F4Jumble_G”} \,||\, [i] \,||\,\)</span>
<span class="math">\(\mathsf{I2LEOSP}_{16}(j), u) \text{ for } j \text{ from}\)</span>
<span class="math">\(0 \text{ up to } \mathsf{ceiling}(\ell_R/\ell_H)-1].\)</span>
</p>
<figure class="align-center" align="center">
<img width="372px" src="zip-0316-f4.png" />
<figcaption>Diagram of 4-round unkeyed Feistel construction</figcaption>
</figure>
<p>(In practice the lengths
<span class="math">\(\ell_L\)</span>
and
<span class="math">\(\ell_R\)</span>
will be roughly the same until
<span class="math">\(\ell_M\)</span>
is larger than
<span class="math">\(128\)</span>
bytes.)</p>
</section>
<section id="usage-for-unified-addresses-ufvks-and-uivks"><h4><span class="section-heading">Usage for Unified Addresses, UFVKs, and UIVKs</span><span class="section-anchor"> <a rel="bookmark" href="#usage-for-unified-addresses-ufvks-and-uivks"><img width="24" height="24" class="section-anchor" src="assets/images/section-anchor.png" alt=""></a></span></h4>
<p>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
<span class="math">\(\mathsf{F4Jumble}\)</span>
before encoding the result with Bech32m.</p>
<p>The Consumer rejects any Bech32m-decoded byte sequence that is less than 48 bytes or greater than
<span class="math">\(\ell^\mathsf{MAX}_M\)</span>
bytes; otherwise it applies
<span class="math">\(\mathsf{F4Jumble}^{-1}.\)</span>
It rejects any result that does not end in the expected 16-byte padding, before stripping these 16 bytes and parsing the result.</p>
<p>(48 bytes allows for the minimum size of a shielded UA, UFVK, or UIVK item encoding to be 32 bytes, taking into account 16 bytes of padding. Although there is currently no shielded item encoding that short, it is plausible that one might be added in future.
<span class="math">\(\ell^\mathsf{MAX}_M\)</span>
bytes is the largest input/output size supported by
<span class="math">\(\mathsf{F4Jumble}.\)</span>
)</p>
</section>
<section id="heuristic-analysis"><h4><span class="section-heading">Heuristic analysis</span><span class="section-anchor"> <a rel="bookmark" href="#heuristic-analysis"><img width="24" height="24" class="section-anchor" src="assets/images/section-anchor.png" alt=""></a></span></h4>
<p>A 3-round unkeyed Feistel, as shown, is not sufficient:</p>
<figure class="align-center" align="center">
<img width="372px" src="zip-0316-f3.png" />
<figcaption>Diagram of 3-round unkeyed Feistel construction</figcaption>
</figure>
<p>Suppose that an adversary has a target input/output pair
<span class="math">\((a \,||\, b, c \,||\, d),\)</span>
and that the input to
<span class="math">\(H_0\)</span>
is
<span class="math">\(x.\)</span>
By fixing
<span class="math">\(x,\)</span>
we can obtain another pair
<span class="math">\(((a \oplus t) \,||\, b', (c \oplus t) \,||\, d')\)</span>
such that
<span class="math">\(a \oplus t\)</span>
is close to
<span class="math">\(a\)</span>
and
<span class="math">\(c \oplus t\)</span>
is close to
<span class="math">\(c.\)</span>
(
<span class="math">\(b'\)</span>
and
<span class="math">\(d'\)</span>
will not be close to
<span class="math">\(b\)</span>
and
<span class="math">\(d,\)</span>
but that isn't necessarily required for a valid attack.)</p>
<p>A 4-round Feistel thwarts this and similar attacks. Defining
<span class="math">\(x\)</span>
and
<span class="math">\(y\)</span>
as the intermediate values in the first diagram above:</p>
<ul>
<li>if
<span class="math">\((x', y')\)</span>
are fixed to the same values as
<span class="math">\((x, y),\)</span>
then
<span class="math">\((a', b', c', d') = (a, b, c, d);\)</span>
</li>
<li>if
<span class="math">\(x' = x\)</span>
but
<span class="math">\(y' \neq y,\)</span>
then the adversary is able to introduce a controlled
<span class="math">\(\oplus\!\)</span>
-difference
<span class="math">\(a \oplus a' = y \oplus y',\)</span>
but the other three pieces
<span class="math">\((b, c, d)\)</span>
are all randomized, which is sufficient;</li>
<li>if
<span class="math">\(y' = y\)</span>
but
<span class="math">\(x' \neq x,\)</span>
then the adversary is able to introduce a controlled
<span class="math">\(\oplus\!\)</span>
-difference
<span class="math">\(d \oplus d' = x \oplus x',\)</span>
but the other three pieces
<span class="math">\((a, b, c)\)</span>
are all randomized, which is sufficient;</li>
<li>if
<span class="math">\(x' \neq x\)</span>
and
<span class="math">\(y' \neq y,\)</span>
all four pieces are randomized.</li>
</ul>
<p>Note that the size of each piece is at least 24 bytes.</p>
<p>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.</p>
<p>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.</p>
</section>
<section id="efficiency"><h4><span class="section-heading">Efficiency</span><span class="section-anchor"> <a rel="bookmark" href="#efficiency"><img width="24" height="24" class="section-anchor" src="assets/images/section-anchor.png" alt=""></a></span></h4>
<p>The cost is dominated by 4 BLAKE2b compressions for
<span class="math">\(\ell_M \leq 128\)</span>
bytes. A UA containing a Transparent Address, a Sapling Address, and an Orchard Address, would have
<span class="math">\(\ell_M = 128\)</span>
bytes. The restriction to a single Address with a given Typecode (and at most one Transparent Address) means that this is also the maximum length of a Unified Address containing only defined Receiver Types as of NU5 activation.</p>
<p>For longer UAs (when other Receiver Types are added) or UVKs, the cost increases to 6 BLAKE2b compressions for
<span class="math">\(128 &lt; \ell_M \leq 192,\)</span>
and 10 BLAKE2b compressions for
<span class="math">\(192 &lt; \ell_M \leq 256,\)</span>
for example. The maximum cost for which the algorithm is defined would be 196608 BLAKE2b compressions at
<span class="math">\(\ell_M = \ell^\mathsf{MAX}_M\)</span>
bytes.</p>
<p>A naïve implementation of the
<span class="math">\(\mathsf{F4Jumble}^{-1}\)</span>
function would require roughly
<span class="math">\(\ell_M\)</span>
bytes plus the size of a BLAKE2b hash state. However, it is possible to reduce this by streaming the
<span class="math">\(d\)</span>
part of the jumbled encoding three times from a less memory-constrained device. It is essential that the streamed value of
<span class="math">\(d\)</span>
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
<span class="math">\(d\)</span>
, the implementation is able to compute
<span class="math">\(y;\)</span>
after the second pass it is able to compute
<span class="math">\(a;\)</span>
and the third allows it to compute and incrementally parse
<span class="math">\(b.\)</span>
The maximum memory usage during this process would be 128 bytes plus two BLAKE2b hash states.</p>
<p>Since this streaming implementation of
<span class="math">\(\mathsf{F4Jumble}^{-1}\)</span>
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
<span class="math">\(\ell_M\)</span>
of at least
<span class="math">\(256\)</span>
bytes. Note that this effectively defines two conformance levels to this specification. A full implementation will support UAs / UVKs up to the maximum length.</p>
</section>
<section id="dependencies"><h4><span class="section-heading">Dependencies</span><span class="section-anchor"> <a rel="bookmark" href="#dependencies"><img width="24" height="24" class="section-anchor" src="assets/images/section-anchor.png" alt=""></a></span></h4>
<p>BLAKE2b, with personalization and variable output length, is the only external dependency.</p>
</section>
<section id="related-work"><h4><span class="section-heading">Related work</span><span class="section-anchor"> <a rel="bookmark" href="#related-work"><img width="24" height="24" class="section-anchor" src="assets/images/section-anchor.png" alt=""></a></span></h4>
<p><a href="https://www.iacr.org/cryptodb/data/paper.php?pubkey=218">Eliminating Random Permutation Oracles in the EvenMansour Cipher</a></p>
<ul>
<li>This paper argues that a 4-round unkeyed Feistel is sufficient to replace a random permutation in the EvenMansour cipher construction.</li>
</ul>
<p><a href="https://www.iacr.org/archive/crypto2000/18800377/18800377.pdf">On the Round Security of Symmetric-Key Cryptographic Primitives</a></p>
<p><a href="https://www.cl.cam.ac.uk/~rja14/Papers/bear-lion.pdf">LIONESS</a> is a similarly structured 4-round unbalanced Feistel cipher.</p>
</section>
</section>
</section>
<section id="reference-implementation"><h2><span class="section-heading">Reference implementation</span><span class="section-anchor"> <a rel="bookmark" href="#reference-implementation"><img width="24" height="24" class="section-anchor" src="assets/images/section-anchor.png" alt=""></a></span></h2>
<ul>
<li><a href="https://github.com/zcash/librustzcash/pull/352">https://github.com/zcash/librustzcash/pull/352</a></li>
<li><a href="https://github.com/zcash/librustzcash/pull/416">https://github.com/zcash/librustzcash/pull/416</a></li>
</ul>
</section>
<section id="acknowledgements"><h2><span class="section-heading">Acknowledgements</span><span class="section-anchor"> <a rel="bookmark" href="#acknowledgements"><img width="24" height="24" class="section-anchor" src="assets/images/section-anchor.png" alt=""></a></span></h2>
<p>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.</p>
</section>
<section id="references"><h2><span class="section-heading">References</span><span class="section-anchor"> <a rel="bookmark" href="#references"><img width="24" height="24" class="section-anchor" src="assets/images/section-anchor.png" alt=""></a></span></h2>
<table id="rfc2119" class="footnote">
<tbody>
<tr>
<th>1</th>
<td><a href="https://www.rfc-editor.org/rfc/rfc2119.html">RFC 2119: Key words for use in RFCs to Indicate Requirement Levels</a></td>
</tr>
</tbody>
</table>
<table id="protocol-nu5" class="footnote">
<tbody>
<tr>
<th>2</th>
<td><a href="protocol/protocol.pdf">Zcash Protocol Specification, Version 2022.2.19 or later [NU5 proposal]</a></td>
</tr>
</tbody>
</table>
<table id="protocol-notation" class="footnote">
<tbody>
<tr>
<th>3</th>
<td><a href="protocol/protocol.pdf#notation">Zcash Protocol Specification, Version 2022.2.19. Section 2: Notation</a></td>
</tr>
</tbody>
</table>
<table id="protocol-saplingkeycomponents" class="footnote">
<tbody>
<tr>
<th>4</th>
<td><a href="protocol/protocol.pdf#saplingkeycomponents">Zcash Protocol Specification, Version 2022.2.19. Section 4.2.2: Sapling Key Components</a></td>
</tr>
</tbody>
</table>
<table id="protocol-orchardkeycomponents" class="footnote">
<tbody>
<tr>
<th>5</th>
<td><a href="protocol/protocol.pdf#orchardkeycomponents">Zcash Protocol Specification, Version 2022.2.19. Section 4.2.3: Orchard Key Components</a></td>
</tr>
</tbody>
</table>
<table id="protocol-saplingsend" class="footnote">
<tbody>
<tr>
<th>6</th>
<td><a href="protocol/protocol.pdf#saplingsend">Zcash Protocol Specification, Version 2022.2.19. Section 4.7.2: Sending Notes (Sapling)</a></td>
</tr>
</tbody>
</table>
<table id="protocol-orchardsend" class="footnote">
<tbody>
<tr>
<th>7</th>
<td><a href="protocol/protocol.pdf#orchardsend">Zcash Protocol Specification, Version 2022.2.19. Section 4.7.3: Sending Notes (Orchard)</a></td>
</tr>
</tbody>
</table>
<table id="protocol-addressandkeyencoding" class="footnote">
<tbody>
<tr>
<th>8</th>
<td><a href="protocol/protocol.pdf#addressandkeyencoding">Zcash Protocol Specification, Version 2022.2.19. Section 5.6: Encodings of Addresses and Keys</a></td>
</tr>
</tbody>
</table>
<table id="protocol-saplingpaymentaddrencoding" class="footnote">
<tbody>
<tr>
<th>9</th>
<td><a href="protocol/protocol.pdf#saplingpaymentaddrencoding">Zcash Protocol Specification, Version 2022.2.19. Section 5.6.3.1: Sapling Payment Addresses</a></td>
</tr>
</tbody>
</table>
<table id="protocol-orchardpaymentaddrencoding" class="footnote">
<tbody>
<tr>
<th>10</th>
<td><a href="protocol/protocol.pdf#orchardpaymentaddrencoding">Zcash Protocol Specification, Version 2022.2.19. Section 5.6.4.2: Orchard Raw Payment Addresses</a></td>
</tr>
</tbody>
</table>
<table id="protocol-orchardinviewingkeyencoding" class="footnote">
<tbody>
<tr>
<th>11</th>
<td><a href="protocol/protocol.pdf#orchardinviewingkeyencoding">Zcash Protocol Specification, Version 2022.2.19. Section 5.6.4.3: Orchard Raw Incoming Viewing Keys</a></td>
</tr>
</tbody>
</table>
<table id="protocol-orchardfullviewingkeyencoding" class="footnote">
<tbody>
<tr>
<th>12</th>
<td><a href="protocol/protocol.pdf#orchardfullviewingkeyencoding">Zcash Protocol Specification, Version 2022.2.19. Section 5.6.4.4: Orchard Raw Full Viewing Keys</a></td>
</tr>
</tbody>
</table>
<table id="zip-0000" class="footnote">
<tbody>
<tr>
<th>13</th>
<td><a href="zip-0000">ZIP 0: ZIP Process</a></td>
</tr>
</tbody>
</table>
<table id="zip-0032-sapling-helper-functions" class="footnote">
<tbody>
<tr>
<th>14</th>
<td><a href="zip-0032#sapling-helper-functions">ZIP 32: Shielded Hierarchical Deterministic Wallets — Sapling helper functions</a></td>
</tr>
</tbody>
</table>
<table id="zip-0032-sapling-extfvk" class="footnote">
<tbody>
<tr>
<th>15</th>
<td><a href="zip-0032#sapling-extended-full-viewing-keys">ZIP 32: Shielded Hierarchical Deterministic Wallets — Sapling extended full viewing keys</a></td>
</tr>
</tbody>
</table>
<table id="zip-0032-sapling-diversifier-derivation" class="footnote">
<tbody>
<tr>
<th>16</th>
<td><a href="zip-0032#sapling-diversifier-derivation">ZIP 32: Shielded Hierarchical Deterministic Wallets — Sapling diversifier derivation</a></td>
</tr>
</tbody>
</table>
<table id="zip-0032-sapling-internal-key-derivation" class="footnote">
<tbody>
<tr>
<th>17</th>
<td><a href="zip-0032#sapling-internal-key-derivation">ZIP 32: Shielded Hierarchical Deterministic Wallets — Sapling internal key derivation</a></td>
</tr>
</tbody>
</table>
<table id="zip-0032-orchard-child-key-derivation" class="footnote">
<tbody>
<tr>
<th>18</th>
<td><a href="zip-0032#orchard-child-key-derivation">ZIP 32: Shielded Hierarchical Deterministic Wallets — Orchard child key derivation</a></td>
</tr>
</tbody>
</table>
<table id="zip-0032-orchard-internal-key-derivation" class="footnote">
<tbody>
<tr>
<th>19</th>
<td><a href="zip-0032#orchard-internal-key-derivation">ZIP 32: Shielded Hierarchical Deterministic Wallets — Orchard internal key derivation</a></td>
</tr>
</tbody>
</table>
<table id="zip-0032-key-path-levels" class="footnote">
<tbody>
<tr>
<th>20</th>
<td><a href="zip-0032#key-path-levels">ZIP 32: Shielded Hierarchical Deterministic Wallets — Key path levels</a></td>
</tr>
</tbody>
</table>
<table id="zip-0032-sapling-key-path" class="footnote">
<tbody>
<tr>
<th>21</th>
<td><a href="zip-0032#sapling-key-path">ZIP 32: Shielded Hierarchical Deterministic Wallets — Sapling key path</a></td>
</tr>
</tbody>
</table>
<table id="zip-0032-orchard-key-path" class="footnote">
<tbody>
<tr>
<th>22</th>
<td><a href="zip-0032#orchard-key-path">ZIP 32: Shielded Hierarchical Deterministic Wallets — Orchard key path</a></td>
</tr>
</tbody>
</table>
<table id="zip-0211" class="footnote">
<tbody>
<tr>
<th>23</th>
<td><a href="zip-0211">ZIP 211: Disabling Addition of New Value to the Sprout Chain Value Pool</a></td>
</tr>
</tbody>
</table>
<table id="zip-0224" class="footnote">
<tbody>
<tr>
<th>24</th>
<td><a href="zip-0224">ZIP 224: Orchard Shielded Protocol</a></td>
</tr>
</tbody>
</table>
<table id="zip-0315" class="footnote">
<tbody>
<tr>
<th>25</th>
<td><a href="zip-0315">ZIP 315: Best Practices for Wallet Handling of Multiple Pools</a></td>
</tr>
</tbody>
</table>
<table id="zip-0321" class="footnote">
<tbody>
<tr>
<th>26</th>
<td><a href="zip-0321">ZIP 321: Payment Request URIs</a></td>
</tr>
</tbody>
</table>
<table id="bip-0032" class="footnote">
<tbody>
<tr>
<th>27</th>
<td><a href="https://github.com/bitcoin/bips/blob/master/bip-0032.mediawiki">BIP 32: Hierarchical Deterministic Wallets</a></td>
</tr>
</tbody>
</table>
<table id="bip-0032-serialization-format" class="footnote">
<tbody>
<tr>
<th>28</th>
<td><a href="https://github.com/bitcoin/bips/blob/master/bip-0032.mediawiki#serialization-format">BIP 32: Hierarchical Deterministic Wallets — Serialization Format</a></td>
</tr>
</tbody>
</table>
<table id="bip-0032-public-to-public" class="footnote">
<tbody>
<tr>
<th>29</th>
<td><a href="https://github.com/bitcoin/bips/blob/master/bip-0032.mediawiki#public-parent-key--public-child-key">BIP 32: Hierarchical Deterministic Wallets — Child key derivation (CKD) functions: Public parent key → public child key</a></td>
</tr>
</tbody>
</table>
<table id="bip-0044" class="footnote">
<tbody>
<tr>
<th>30</th>
<td><a href="https://github.com/bitcoin/bips/blob/master/bip-0044.mediawiki">BIP 44: Multi-Account Hierarchy for Deterministic Wallets</a></td>
</tr>
</tbody>
</table>
<table id="bip-0044-path-change" class="footnote">
<tbody>
<tr>
<th>31</th>
<td><a href="https://github.com/bitcoin/bips/blob/master/bip-0044.mediawiki#change">BIP 44: Multi-Account Hierarchy for Deterministic Wallets — Path levels: Change</a></td>
</tr>
</tbody>
</table>
<table id="bip-0044-path-index" class="footnote">
<tbody>
<tr>
<th>32</th>
<td><a href="https://github.com/bitcoin/bips/blob/master/bip-0044.mediawiki#index">BIP 44: Multi-Account Hierarchy for Deterministic Wallets — Path levels: Index</a></td>
</tr>
</tbody>
</table>
<table id="bip-0350" class="footnote">
<tbody>
<tr>
<th>33</th>
<td><a href="https://github.com/bitcoin/bips/blob/master/bip-0350.mediawiki">BIP 350: Bech32m format for v1+ witness addresses</a></td>
</tr>
</tbody>
</table>
<table id="p2pkh" class="footnote">
<tbody>
<tr>
<th>34</th>
<td><a href="https://developer.bitcoin.org/devguide/transactions.html#p2pkh-script-validation">Transactions: P2PKH Script Validation — Bitcoin Developer Guide</a></td>
</tr>
</tbody>
</table>
<table id="p2sh" class="footnote">
<tbody>
<tr>
<th>35</th>
<td><a href="https://developer.bitcoin.org/devguide/transactions.html#pay-to-script-hash-p2sh">Transactions: P2SH Scripts — Bitcoin Developer Guide</a></td>
</tr>
</tbody>
</table>
<table id="bitcoin-compactsize" class="footnote">
<tbody>
<tr>
<th>36</th>
<td><a href="https://en.bitcoin.it/wiki/Protocol_documentation#Variable_length_integer">Variable length integer. Bitcoin Wiki</a></td>
</tr>
</tbody>
</table>
</section>
</section>
</body>
</html>