zips/zip-0143.html

428 lines
58 KiB
HTML
Raw Normal View History

<!DOCTYPE html>
<html xmlns="http://www.w3.org/1999/xhtml" lang="" xml:lang="">
<head>
<meta charset="utf-8" />
<meta name="generator" content="pandoc" />
<meta name="viewport" content="width=device-width, initial-scale=1.0, user-scalable=yes" />
<title>ZIP 143: Transaction Signature Verification for Overwinter</title>
<style type="text/css">
code{white-space: pre-wrap;}
span.smallcaps{font-variant: small-caps;}
span.underline{text-decoration: underline;}
div.column{display: inline-block; vertical-align: top; width: 50%;}
</style>
<style type="text/css">
a.sourceLine { display: inline-block; line-height: 1.25; }
a.sourceLine { pointer-events: none; color: inherit; text-decoration: inherit; }
a.sourceLine:empty { height: 1.2em; }
.sourceCode { overflow: visible; }
code.sourceCode { white-space: pre; position: relative; }
div.sourceCode { margin: 1em 0; }
pre.sourceCode { margin: 0; }
@media screen {
div.sourceCode { overflow: auto; }
}
@media print {
code.sourceCode { white-space: pre-wrap; }
a.sourceLine { text-indent: -1em; padding-left: 1em; }
}
pre.numberSource a.sourceLine
{ position: relative; left: -4em; }
pre.numberSource a.sourceLine::before
{ content: attr(title);
position: relative; left: -1em; text-align: right; vertical-align: baseline;
border: none; pointer-events: all; display: inline-block;
-webkit-touch-callout: none; -webkit-user-select: none;
-khtml-user-select: none; -moz-user-select: none;
-ms-user-select: none; user-select: none;
padding: 0 4px; width: 4em;
color: #aaaaaa;
}
pre.numberSource { margin-left: 3em; border-left: 1px solid #aaaaaa; padding-left: 4px; }
div.sourceCode
{ }
@media screen {
a.sourceLine::before { text-decoration: underline; }
}
code span.al { color: #ff0000; font-weight: bold; } /* Alert */
code span.an { color: #60a0b0; font-weight: bold; font-style: italic; } /* Annotation */
code span.at { color: #7d9029; } /* Attribute */
code span.bn { color: #40a070; } /* BaseN */
code span.bu { } /* BuiltIn */
code span.cf { color: #007020; font-weight: bold; } /* ControlFlow */
code span.ch { color: #4070a0; } /* Char */
code span.cn { color: #880000; } /* Constant */
code span.co { color: #60a0b0; font-style: italic; } /* Comment */
code span.cv { color: #60a0b0; font-weight: bold; font-style: italic; } /* CommentVar */
code span.do { color: #ba2121; font-style: italic; } /* Documentation */
code span.dt { color: #902000; } /* DataType */
code span.dv { color: #40a070; } /* DecVal */
code span.er { color: #ff0000; font-weight: bold; } /* Error */
code span.ex { } /* Extension */
code span.fl { color: #40a070; } /* Float */
code span.fu { color: #06287e; } /* Function */
code span.im { } /* Import */
code span.in { color: #60a0b0; font-weight: bold; font-style: italic; } /* Information */
code span.kw { color: #007020; font-weight: bold; } /* Keyword */
code span.op { color: #666666; } /* Operator */
code span.ot { color: #007020; } /* Other */
code span.pp { color: #bc7a00; } /* Preprocessor */
code span.sc { color: #4070a0; } /* SpecialChar */
code span.ss { color: #bb6688; } /* SpecialString */
code span.st { color: #4070a0; } /* String */
code span.va { color: #19177c; } /* Variable */
code span.vs { color: #4070a0; } /* VerbatimString */
code span.wa { color: #60a0b0; font-weight: bold; font-style: italic; } /* Warning */
</style>
<link rel="stylesheet" href="css/zip-style.css"><link rel="stylesheet" href="assets/css/style.css"></head>
<body>
<pre><code>ZIP: 143
Title: Transaction Signature Verification for Overwinter
Owners: Jack Grigg &lt;str4d@electriccoin.co&gt;
Daira Hopwood &lt;daira@electriccoin.co&gt;
Credits: Johnson Lau &lt;jl2012@xbt.hk&gt;
Pieter Wuille &lt;pieter.wuille@gmail.com&gt;
Bitcoin-ABC
Status: Final
Category: Consensus
Created: 2017-12-27
License: MIT</code></pre>
<h1 id="terminology">Terminology</h1>
<p>The key words &quot;MUST&quot; and &quot;MUST NOT&quot; in this document are to be interpreted as described in RFC 2119.<a href="#fn1" class="footnote-ref" id="fnref1"><sup>1</sup></a></p>
<p>The terms &quot;branch&quot; and &quot;network upgrade&quot; in this document are to be interpreted as described in ZIP 200.<a href="#fn2" class="footnote-ref" id="fnref2"><sup>2</sup></a></p>
<p>The term &quot;Overwinter&quot; in this document is to be interpreted as described in ZIP 201.<a href="#fn3" class="footnote-ref" id="fnref3"><sup>3</sup></a></p>
<h1 id="abstract">Abstract</h1>
<p>This proposal defines a new transaction digest algorithm for signature verification from the Overwinter network upgrade, in order to minimize redundant data hashing in verification, and to cover the input value by the signature.</p>
<h1 id="motivation">Motivation</h1>
<p>There are 4 ECDSA signature verification codes in the original Zcash script system: <code>CHECKSIG</code>, <code>CHECKSIGVERIFY</code>, <code>CHECKMULTISIG</code>, <code>CHECKMULTISIGVERIFY</code> (&quot;sigops&quot;). According to the sighash type (<code>ALL</code>, <code>NONE</code>, or <code>SINGLE</code>, possibly modified by <code>ANYONECANPAY</code>), a transaction digest is generated with a double SHA256 of a serialized subset of the transaction, and the signature is verified against this digest with a given public key. The detailed procedure is described in a Bitcoin Wiki article.<a href="#fn4" class="footnote-ref" id="fnref4"><sup>4</sup></a> The transaction digest is additionally used for the JoinSplit signature (solely with sighash type <code>ALL</code>). <a href="#fn5" class="footnote-ref" id="fnref5"><sup>5</sup></a></p>
<p>Unfortunately, there are at least 2 weaknesses in the original SignatureHash transaction digest algorithm:</p>
<ul>
<li>For the verification of each signature, the amount of data hashing is proportional to the size of the transaction. Therefore, data hashing grows in O(n<sup>2</sup>) as the number of sigops in a transaction increases. While a 1 MB block would normally take 2 seconds to verify with an average computer in 2015, a 1MB transaction with 5569 sigops may take 25 seconds to verify. This could be fixed by optimizing the digest algorithm by introducing some reusable &quot;midstate&quot;, so the time complexity becomes O(n).<a href="#fn6" class="footnote-ref" id="fnref6"><sup>6</sup></a></li>
<li>The algorithm does not involve the value being spent by the input. This is usually not a problem for online network nodes as they could request for the specified transaction to acquire the output value. For an offline transaction signing device (&quot;cold wallet&quot;), however, the lack of knowledge of input amount makes it impossible to calculate the exact amount being spent and the transaction fee. To cope with this problem a cold wallet must also acquire the full transaction being spent, which could be a big obstacle in the implementation of a lightweight, air-gapped wallet. By including the input value of part of the transaction digest, a cold wallet may safely sign a transaction by learning the value from an untrusted source. In the case that a wrong value is provided and signed, the signature would be invalid and no funds would be lost. <a href="#fn7" class="footnote-ref" id="fnref7"><sup>7</sup></a></li>
</ul>
<p>Deploying the aforementioned fixes in the original script system is not a simple task.</p>
<h1 id="specification">Specification</h1>
<p>A new transaction digest algorithm is defined:</p>
<pre><code>BLAKE2b-256 hash of the serialization of:
1. header of the transaction (4-byte little endian)
2. nVersionGroupId of the transaction (4-byte little endian)
3. hashPrevouts (32-byte hash)
4. hashSequence (32-byte hash)
5. hashOutputs (32-byte hash)
6. hashJoinSplits (32-byte hash)
7. nLockTime of the transaction (4-byte little endian)
8. nExpiryHeight of the transaction (4-byte little endian)
9. sighash type of the signature (4-byte little endian)
10. If we are serializing an input (i.e. this is not a JoinSplit signature hash):
a. outpoint (32-byte hash + 4-byte little endian)
b. scriptCode of the input (serialized as scripts inside CTxOuts)
c. value of the output spent by this input (8-byte little endian)
d. nSequence of the input (4-byte little endian)</code></pre>
<p>The new algorithm is based on the Bitcoin transaction digest algorithm defined in BIP 143,<a href="#fn8" class="footnote-ref" id="fnref8"><sup>8</sup></a> with replay protection inspired by BUIP-HF v1.2.<a href="#fn9" class="footnote-ref" id="fnref9"><sup>9</sup></a></p>
<p>The new algorithm MUST be used for signatures created over the Overwinter transaction format.<a href="#fn10" class="footnote-ref" id="fnref10"><sup>10</sup></a> Combined with the new consensus rule that v1 and v2 transaction formats will be invalid from the Overwinter upgrade,<a href="#fn11" class="footnote-ref" id="fnref11"><sup>11</sup></a> this effectively means that all transaction signatures from the Overwinter activation height will use the new algorithm.<a href="#fn12" class="footnote-ref" id="fnref12"><sup>12</sup></a></p>
<p>The BLAKE2b-256 personalization field<a href="#fn13" class="footnote-ref" id="fnref13"><sup>13</sup></a> is set to:</p>
<pre><code>&quot;ZcashSigHash&quot; || CONSENSUS_BRANCH_ID</code></pre>
<p><code>CONSENSUS_BRANCH_ID</code> is the little-endian encoding of <code>BRANCH_ID</code> for the epoch of the block containing the transaction.<a href="#fn14" class="footnote-ref" id="fnref14"><sup>14</sup></a> Domain separation of the signature hash across parallel branches provides replay protection: transactions targeted for one branch will have invalid signatures on other branches.</p>
<p>Transaction creators MUST specify the epoch they want their transaction to be mined in. Across a network upgrade, this means that if a transaction is not mined before the activation height, it will never be mined.</p>
<p>Semantics of the original sighash types remain unchanged, except the following:</p>
<ol>
<li>The serialization format is changed;</li>
<li>All sighash types commit to the amount being spent by the signed input;</li>
<li><code>SINGLE</code> does not commit to the input index. When <code>ANYONECANPAY</code> is not set, the semantics are unchanged since <code>hashPrevouts</code> and <code>outpoint</code> together implictly commit to the input index. When <code>SINGLE</code> is used with <code>ANYONECANPAY</code>, omission of the index commitment allows permutation of the input-output pairs, as long as each pair is located at an equivalent index.</li>
</ol>
<h2 id="field-definitions">Field definitions</h2>
<p>The items 7, 9, 10a, 10d have the same meaning as the original algorithm from Bitcoin.<a href="#fn15" class="footnote-ref" id="fnref15"><sup>15</sup></a></p>
<h3 id="header">1: <code>header</code></h3>
<p>Deserialized into two transaction properties: <code>fOverwintered</code> and <code>nVersion</code>. For transactions that use this transaction digest algorithm, <code>fOverwintered</code> is always set.<a href="#fn16" class="footnote-ref" id="fnref16"><sup>16</sup></a></p>
<h3 id="nversiongroupid">2: <code>nVersionGroupId</code></h3>
<p>Provides domain separation of <code>nVersion</code>. It is only defined if <code>fOverwintered</code> is set, which means that it is always defined for transactions that use this algorithm.<a href="#fn17" class="footnote-ref" id="fnref17"><sup>17</sup></a></p>
<h3 id="hashprevouts">3: <code>hashPrevouts</code></h3>
<ul>
<li>If the <code>ANYONECANPAY</code> flag is not set, <code>hashPrevouts</code> is the BLAKE2b-256 hash of the serialization of all input outpoints;
<ul>
<li>The BLAKE2b-256 personalization field is set to <code>ZcashPrevoutHash</code>.</li>
</ul></li>
<li>Otherwise, <code>hashPrevouts</code> is a <code>uint256</code> of <code>0x0000......0000</code>.</li>
</ul>
<h3 id="hashsequence">4: <code>hashSequence</code></h3>
<ul>
<li>If none of the <code>ANYONECANPAY</code>, <code>SINGLE</code>, <code>NONE</code> sighash type is set, <code>hashSequence</code> is the BLAKE2b-256 hash of the serialization of <code>nSequence</code> of all inputs;
<ul>
<li>The BLAKE2b-256 personalization field is set to <code>ZcashSequencHash</code>.</li>
</ul></li>
<li>Otherwise, <code>hashSequence</code> is a <code>uint256</code> of <code>0x0000......0000</code>.</li>
</ul>
<p>Note: the encoding of the sighash type is masked with <code>0x1F</code> when checking whether or not the <code>SINGLE</code> and <code>NONE</code> flags are set.</p>
<h3 id="hashoutputs">5: <code>hashOutputs</code></h3>
<ul>
<li>If the sighash type is neither <code>SINGLE</code> nor <code>NONE</code>, <code>hashOutputs</code> is the BLAKE2b-256 hash of the serialization of all output amount (8-byte little endian) with <code>scriptPubKey</code> (serialized as scripts inside CTxOuts);</li>
<li>If sighash type is <code>SINGLE</code> and the input index is smaller than the number of outputs, <code>hashOutputs</code> is the BLAKE2b-256 hash of the output (serialized as above) with the same index as the input;
<ul>
<li>The BLAKE2b-256 personalization field is set to <code>ZcashOutputsHash</code> in both cases above.</li>
</ul></li>
<li>Otherwise, <code>hashOutputs</code> is a <code>uint256</code> of <code>0x0000......0000</code>.<a href="#fn18" class="footnote-ref" id="fnref18"><sup>18</sup></a></li>
</ul>
<p>Note: the encoding of the sighash type is masked with <code>0x1F</code> when checking whether or not the SINGLE` and <code>NONE</code> flags are set.</p>
<h3 id="hashjoinsplits">6: <code>hashJoinSplits</code></h3>
<ul>
<li>If <code>vjoinsplits</code> is non-empty, <code>hashJoinSplits</code> is the BLAKE2b-256 hash of the serialization of all JoinSplits (in their canonical transaction serialization format) concatenated with the joinSplitPubKey;
<ul>
<li>The BLAKE2b-256 personalization field is set to <code>ZcashJSplitsHash</code>.</li>
<li>Note that while signatures are omitted, the JoinSplit proofs are included in the signature hash, as with v1 and v2 transactions.</li>
</ul></li>
<li>Otherwise, <code>hashJoinSplits</code> is a <code>uint256</code> of <code>0x0000......0000</code>.</li>
</ul>
<h3 id="nexpiryheight">8: <code>nExpiryHeight</code></h3>
<p>The block height after which the transaction becomes unilaterally invalid, and can never be mined.<a href="#fn19" class="footnote-ref" id="fnref19"><sup>19</sup></a></p>
<h3 id="b-scriptcode">10b: <code>scriptCode</code></h3>
<p>The script being currently executed: <code>redeemScript</code> for P2SH, or <code>scriptPubKey</code> in the general case. This is the same script as serialized in the Sprout transaction digest algorithm.</p>
<h3 id="c-value">10c: value</h3>
<p>An 8-byte little-endian value of the amount, in zatoshi, spent in this input.</p>
<h2 id="notes">Notes</h2>
<p>The <code>hashPrevouts</code>, <code>hashSequence</code>, <code>hashOutputs</code>, and <code>hashJoinSplits</code> calculated in an earlier verification can be reused in other inputs of the same transaction, so that the time complexity of the whole hashing process reduces from O(n<sup>2</sup>) to O(n).</p>
<p>Refer to the reference implementation, reproduced below, for the precise algorithm:</p>
<div class="sourceCode" id="cb4"><pre class="sourceCode cpp"><code class="sourceCode cpp"><a class="sourceLine" id="cb4-1" title="1"><span class="at">const</span> <span class="dt">unsigned</span> <span class="dt">char</span> ZCASH_PREVOUTS_HASH_PERSONALIZATION[<span class="dv">16</span>] =</a>
<a class="sourceLine" id="cb4-2" title="2"> {<span class="ch">&#39;Z&#39;</span>,<span class="ch">&#39;c&#39;</span>,<span class="ch">&#39;a&#39;</span>,<span class="ch">&#39;s&#39;</span>,<span class="ch">&#39;h&#39;</span>,<span class="ch">&#39;P&#39;</span>,<span class="ch">&#39;r&#39;</span>,<span class="ch">&#39;e&#39;</span>,<span class="ch">&#39;v&#39;</span>,<span class="ch">&#39;o&#39;</span>,<span class="ch">&#39;u&#39;</span>,<span class="ch">&#39;t&#39;</span>,<span class="ch">&#39;H&#39;</span>,<span class="ch">&#39;a&#39;</span>,<span class="ch">&#39;s&#39;</span>,<span class="ch">&#39;h&#39;</span>};</a>
<a class="sourceLine" id="cb4-3" title="3"><span class="at">const</span> <span class="dt">unsigned</span> <span class="dt">char</span> ZCASH_SEQUENCE_HASH_PERSONALIZATION[<span class="dv">16</span>] =</a>
<a class="sourceLine" id="cb4-4" title="4"> {<span class="ch">&#39;Z&#39;</span>,<span class="ch">&#39;c&#39;</span>,<span class="ch">&#39;a&#39;</span>,<span class="ch">&#39;s&#39;</span>,<span class="ch">&#39;h&#39;</span>,<span class="ch">&#39;S&#39;</span>,<span class="ch">&#39;e&#39;</span>,<span class="ch">&#39;q&#39;</span>,<span class="ch">&#39;u&#39;</span>,<span class="ch">&#39;e&#39;</span>,<span class="ch">&#39;n&#39;</span>,<span class="ch">&#39;c&#39;</span>,<span class="ch">&#39;H&#39;</span>,<span class="ch">&#39;a&#39;</span>,<span class="ch">&#39;s&#39;</span>,<span class="ch">&#39;h&#39;</span>};</a>
<a class="sourceLine" id="cb4-5" title="5"><span class="at">const</span> <span class="dt">unsigned</span> <span class="dt">char</span> ZCASH_OUTPUTS_HASH_PERSONALIZATION[<span class="dv">16</span>] =</a>
<a class="sourceLine" id="cb4-6" title="6"> {<span class="ch">&#39;Z&#39;</span>,<span class="ch">&#39;c&#39;</span>,<span class="ch">&#39;a&#39;</span>,<span class="ch">&#39;s&#39;</span>,<span class="ch">&#39;h&#39;</span>,<span class="ch">&#39;O&#39;</span>,<span class="ch">&#39;u&#39;</span>,<span class="ch">&#39;t&#39;</span>,<span class="ch">&#39;p&#39;</span>,<span class="ch">&#39;u&#39;</span>,<span class="ch">&#39;t&#39;</span>,<span class="ch">&#39;s&#39;</span>,<span class="ch">&#39;H&#39;</span>,<span class="ch">&#39;a&#39;</span>,<span class="ch">&#39;s&#39;</span>,<span class="ch">&#39;h&#39;</span>};</a>
<a class="sourceLine" id="cb4-7" title="7"><span class="at">const</span> <span class="dt">unsigned</span> <span class="dt">char</span> ZCASH_JOINSPLITS_HASH_PERSONALIZATION[<span class="dv">16</span>] =</a>
<a class="sourceLine" id="cb4-8" title="8"> {<span class="ch">&#39;Z&#39;</span>,<span class="ch">&#39;c&#39;</span>,<span class="ch">&#39;a&#39;</span>,<span class="ch">&#39;s&#39;</span>,<span class="ch">&#39;h&#39;</span>,<span class="ch">&#39;J&#39;</span>,<span class="ch">&#39;S&#39;</span>,<span class="ch">&#39;p&#39;</span>,<span class="ch">&#39;l&#39;</span>,<span class="ch">&#39;i&#39;</span>,<span class="ch">&#39;t&#39;</span>,<span class="ch">&#39;s&#39;</span>,<span class="ch">&#39;H&#39;</span>,<span class="ch">&#39;a&#39;</span>,<span class="ch">&#39;s&#39;</span>,<span class="ch">&#39;h&#39;</span>};</a>
<a class="sourceLine" id="cb4-9" title="9"></a>
<a class="sourceLine" id="cb4-10" title="10"><span class="co">// The default values are zeroes</span></a>
<a class="sourceLine" id="cb4-11" title="11">uint256 hashPrevouts;</a>
<a class="sourceLine" id="cb4-12" title="12">uint256 hashSequence;</a>
<a class="sourceLine" id="cb4-13" title="13">uint256 hashOutputs;</a>
<a class="sourceLine" id="cb4-14" title="14">uint256 hashJoinSplits;</a>
<a class="sourceLine" id="cb4-15" title="15"></a>
<a class="sourceLine" id="cb4-16" title="16"><span class="cf">if</span> (!(nHashType &amp; SIGHASH_ANYONECANPAY)) {</a>
<a class="sourceLine" id="cb4-17" title="17"> CBLAKE2bWriter ss(SER_GETHASH, <span class="dv">0</span>, ZCASH_PREVOUTS_HASH_PERSONALIZATION);</a>
<a class="sourceLine" id="cb4-18" title="18"> <span class="cf">for</span> (<span class="dt">unsigned</span> <span class="dt">int</span> n = <span class="dv">0</span>; n &lt; txTo.vin.size(); n++) {</a>
<a class="sourceLine" id="cb4-19" title="19"> ss &lt;&lt; txTo.vin[n].prevout;</a>
<a class="sourceLine" id="cb4-20" title="20"> }</a>
<a class="sourceLine" id="cb4-21" title="21"> hashPrevouts = ss.GetHash();</a>
<a class="sourceLine" id="cb4-22" title="22">}</a>
<a class="sourceLine" id="cb4-23" title="23"></a>
<a class="sourceLine" id="cb4-24" title="24"><span class="cf">if</span> (!(nHashType &amp; SIGHASH_ANYONECANPAY) &amp;&amp; (nHashType &amp; <span class="bn">0x1f</span>) != SIGHASH_SINGLE &amp;&amp; (nHashType &amp; <span class="bn">0x1f</span>) != SIGHASH_NONE) {</a>
<a class="sourceLine" id="cb4-25" title="25"> CBLAKE2bWriter ss(SER_GETHASH, <span class="dv">0</span>, ZCASH_SEQUENCE_HASH_PERSONALIZATION);</a>
<a class="sourceLine" id="cb4-26" title="26"> <span class="cf">for</span> (<span class="dt">unsigned</span> <span class="dt">int</span> n = <span class="dv">0</span>; n &lt; txTo.vin.size(); n++) {</a>
<a class="sourceLine" id="cb4-27" title="27"> ss &lt;&lt; txTo.vin[n].nSequence;</a>
<a class="sourceLine" id="cb4-28" title="28"> }</a>
<a class="sourceLine" id="cb4-29" title="29"> hashSequence = ss.GetHash();</a>
<a class="sourceLine" id="cb4-30" title="30">}</a>
<a class="sourceLine" id="cb4-31" title="31"></a>
<a class="sourceLine" id="cb4-32" title="32"><span class="cf">if</span> ((nHashType &amp; <span class="bn">0x1f</span>) != SIGHASH_SINGLE &amp;&amp; (nHashType &amp; <span class="bn">0x1f</span>) != SIGHASH_NONE) {</a>
<a class="sourceLine" id="cb4-33" title="33"> CBLAKE2bWriter ss(SER_GETHASH, <span class="dv">0</span>, ZCASH_OUTPUTS_HASH_PERSONALIZATION);</a>
<a class="sourceLine" id="cb4-34" title="34"> <span class="cf">for</span> (<span class="dt">unsigned</span> <span class="dt">int</span> n = <span class="dv">0</span>; n &lt; txTo.vout.size(); n++) {</a>
<a class="sourceLine" id="cb4-35" title="35"> ss &lt;&lt; txTo.vout[n];</a>
<a class="sourceLine" id="cb4-36" title="36"> }</a>
<a class="sourceLine" id="cb4-37" title="37"> hashOutputs = ss.GetHash();</a>
<a class="sourceLine" id="cb4-38" title="38">} <span class="cf">else</span> <span class="cf">if</span> ((nHashType &amp; <span class="bn">0x1f</span>) == SIGHASH_SINGLE &amp;&amp; nIn &lt; txTo.vout.size()) {</a>
<a class="sourceLine" id="cb4-39" title="39"> CBLAKE2bWriter ss(SER_GETHASH, <span class="dv">0</span>, ZCASH_OUTPUTS_HASH_PERSONALIZATION);</a>
<a class="sourceLine" id="cb4-40" title="40"> ss &lt;&lt; txTo.vout[nIn];</a>
<a class="sourceLine" id="cb4-41" title="41"> hashOutputs = ss.GetHash();</a>
<a class="sourceLine" id="cb4-42" title="42">}</a>
<a class="sourceLine" id="cb4-43" title="43"></a>
<a class="sourceLine" id="cb4-44" title="44"><span class="cf">if</span> (!txTo.vjoinsplit.empty()) {</a>
<a class="sourceLine" id="cb4-45" title="45"> CBLAKE2bWriter ss(SER_GETHASH, <span class="dv">0</span>, ZCASH_JOINSPLITS_HASH_PERSONALIZATION);</a>
<a class="sourceLine" id="cb4-46" title="46"> <span class="cf">for</span> (<span class="dt">unsigned</span> <span class="dt">int</span> n = <span class="dv">0</span>; n &lt; txTo.vjoinsplit.size(); n++) {</a>
<a class="sourceLine" id="cb4-47" title="47"> ss &lt;&lt; txTo.vjoinsplit[n];</a>
<a class="sourceLine" id="cb4-48" title="48"> }</a>
<a class="sourceLine" id="cb4-49" title="49"> ss &lt;&lt; txTo.joinSplitPubKey;</a>
<a class="sourceLine" id="cb4-50" title="50"> hashJoinSplits = ss.GetHash();</a>
<a class="sourceLine" id="cb4-51" title="51">}</a>
<a class="sourceLine" id="cb4-52" title="52"></a>
<a class="sourceLine" id="cb4-53" title="53"><span class="dt">uint32_t</span> leConsensusBranchId = htole32(consensusBranchId);</a>
<a class="sourceLine" id="cb4-54" title="54"><span class="dt">unsigned</span> <span class="dt">char</span> personalization[<span class="dv">16</span>] = {};</a>
<a class="sourceLine" id="cb4-55" title="55">memcpy(personalization, <span class="st">&quot;ZcashSigHash&quot;</span>, <span class="dv">12</span>);</a>
<a class="sourceLine" id="cb4-56" title="56">memcpy(personalization+<span class="dv">12</span>, &amp;leConsensusBranchId, <span class="dv">4</span>);</a>
<a class="sourceLine" id="cb4-57" title="57"></a>
<a class="sourceLine" id="cb4-58" title="58">CBLAKE2bWriter ss(SER_GETHASH, <span class="dv">0</span>, personalization);</a>
<a class="sourceLine" id="cb4-59" title="59"><span class="co">// fOverwintered and nVersion</span></a>
<a class="sourceLine" id="cb4-60" title="60">ss &lt;&lt; txTo.GetHeader();</a>
<a class="sourceLine" id="cb4-61" title="61"><span class="co">// Version group ID</span></a>
<a class="sourceLine" id="cb4-62" title="62">ss &lt;&lt; txTo.nVersionGroupId;</a>
<a class="sourceLine" id="cb4-63" title="63"><span class="co">// Input prevouts/nSequence (none/all, depending on flags)</span></a>
<a class="sourceLine" id="cb4-64" title="64">ss &lt;&lt; hashPrevouts;</a>
<a class="sourceLine" id="cb4-65" title="65">ss &lt;&lt; hashSequence;</a>
<a class="sourceLine" id="cb4-66" title="66"><span class="co">// Outputs (none/one/all, depending on flags)</span></a>
<a class="sourceLine" id="cb4-67" title="67">ss &lt;&lt; hashOutputs;</a>
<a class="sourceLine" id="cb4-68" title="68"><span class="co">// JoinSplits</span></a>
<a class="sourceLine" id="cb4-69" title="69">ss &lt;&lt; hashJoinSplits;</a>
<a class="sourceLine" id="cb4-70" title="70"><span class="co">// Locktime</span></a>
<a class="sourceLine" id="cb4-71" title="71">ss &lt;&lt; txTo.nLockTime;</a>
<a class="sourceLine" id="cb4-72" title="72"><span class="co">// Expiry height</span></a>
<a class="sourceLine" id="cb4-73" title="73">ss &lt;&lt; txTo.nExpiryHeight;</a>
<a class="sourceLine" id="cb4-74" title="74"><span class="co">// Sighash type</span></a>
<a class="sourceLine" id="cb4-75" title="75">ss &lt;&lt; nHashType;</a>
<a class="sourceLine" id="cb4-76" title="76"></a>
<a class="sourceLine" id="cb4-77" title="77"><span class="cf">if</span> (nIn != NOT_AN_INPUT) {</a>
<a class="sourceLine" id="cb4-78" title="78"> <span class="co">// The input being signed (replacing the scriptSig with scriptCode + amount)</span></a>
<a class="sourceLine" id="cb4-79" title="79"> <span class="co">// The prevout may already be contained in hashPrevout, and the nSequence</span></a>
<a class="sourceLine" id="cb4-80" title="80"> <span class="co">// may already be contained in hashSequence.</span></a>
<a class="sourceLine" id="cb4-81" title="81"> ss &lt;&lt; txTo.vin[nIn].prevout;</a>
<a class="sourceLine" id="cb4-82" title="82"> ss &lt;&lt; <span class="kw">static_cast</span>&lt;<span class="at">const</span> CScriptBase&amp;&gt;(scriptCode);</a>
<a class="sourceLine" id="cb4-83" title="83"> ss &lt;&lt; amount;</a>
<a class="sourceLine" id="cb4-84" title="84"> ss &lt;&lt; txTo.vin[nIn].nSequence;</a>
<a class="sourceLine" id="cb4-85" title="85">}</a>
<a class="sourceLine" id="cb4-86" title="86"></a>
<a class="sourceLine" id="cb4-87" title="87"><span class="cf">return</span> ss.GetHash();</a></code></pre></div>
<h1 id="example">Example</h1>
<p>To ensure consistency in consensus-critical behaviour, developers should test their implementations against the ZIP 143 test vectors<a href="#fn20" class="footnote-ref" id="fnref20"><sup>20</sup></a>. The first two test vectors are broken out below for clarity. Note that 32-byte values below are exactly as the hash function returns, and are not reversed. Further examples can be found in the SignatureHash test data<a href="#fn21" class="footnote-ref" id="fnref21"><sup>21</sup></a>.</p>
<h2 id="test-vector-1">Test vector 1</h2>
<p>Raw transaction:</p>
<pre><code>030000807082c4030002e7719811893e0000095200ac6551ac636565b2835a0805750200025151481cdd86b3cc431800
header: 03000080
nVersionGroupId: 7082c403
vin: 00
vout: 02 e7719811893e0000 095200ac6551ac636565
b2835a0805750200 025151
nLockTime: 481cdd86
nExpiryHeight: b3cc4318
vJoinSplits: 00</code></pre>
<p>Transaction digest with <code>nIn = NOT_AN_INPUT</code> and <code>nHashType = 1</code> (<code>SIGHASH_ALL</code>):</p>
<pre><code>hashPrevouts:
BLAKE2b-256(&#39;ZcashPrevoutHash&#39;, b&#39;&#39;)
= d53a633bbecf82fe9e9484d8a0e727c73bb9e68c96e72dec30144f6a84afa136
hashSequence:
BLAKE2b-256(&#39;ZcashSequencHash&#39;, b&#39;&#39;)
= a5f25f01959361ee6eb56a7401210ee268226f6ce764a4f10b7f29e54db37272
hashOutputs:
BLAKE2b-256(&#39;ZcashOutputsHash&#39;, e7719811893e0000095200ac6551ac636565b2835a0805750200025151)
= ab6f7f6c5ad6b56357b5f37e16981723db6c32411753e28c175e15589172194a
Preimage:
030000807082c403d53a633bbecf82fe9e9484d8a0e727c73bb9e68c96e72dec30144f6a84afa136a5f25f01959361ee6eb56a7401210ee268226f6ce764a4f10b7f29e54db37272ec55f4afc6cebfe1c35bdcded7519ff6efb381ab1d5a8dd0060c13b2a512932b0000000000000000000000000000000000000000000000000000000000000000481cdd86b3cc431801000000
header: 03000080
nVersionGroupId: 7082c403
hashPrevouts: d53a633bbecf82fe9e9484d8a0e727c73bb9e68c96e72dec30144f6a84afa136
hashSequence: a5f25f01959361ee6eb56a7401210ee268226f6ce764a4f10b7f29e54db37272
hashOutputs: ab6f7f6c5ad6b56357b5f37e16981723db6c32411753e28c175e15589172194a
hashJoinSplits: 0000000000000000000000000000000000000000000000000000000000000000
nLockTime: 481cdd86
nExpiryHeight: b3cc4318
nHashType: 01000000
sighash: a1f1a4e5cd9bd522322d661edd2af1bf2a7019cfab94ece18f4ba935b0a19073</code></pre>
<h2 id="test-vector-2">Test vector 2</h2>
<p>Raw transaction:</p>
<pre><code>030000807082c403024201cfb1cd8dbf69b8250c18ef41294ca97993db546c1fe01f7e9c8e36d6a5e29d4e30a703ac6a0098421c69378af1e40f64e125946f62c2fa7b2fecbcb64b6968912a6381ce3dc166d56a1d62f5a8d7056363635353e8c7203d02d2da86387ae60100080063656a63ac5200a7622997f4ff0400075151005353656597b0e4e4c705fc05020000000000000000000000000000000076495c222f7fba1e31defa3d5a57efc2e1e9b01a035587d5fb1a38e01d94903d3c3e0ad3360c1d3710acd20b183e31d49f25c9a138f49b1a537edcf04be34a9851a7af9db6990ed83dd64af3597c04323ea51b0052ad8084a8b9da948d320dadd64f5431e61ddf658d24ae67c22c8d1309131fc00fe7f235734276d38d47f1e191e00c7a1d48af046827591e9733a97fa6b679f3dc601d008285edcbdae69ce8fc1be4aac00ff2711ebd931de518856878f73476f21a482ec9378365c8f7393c94e2885315eb4671098b79535e790fe53e29fef2b3766697ac32b4f473f468a008e72389fc03880d780cb07fcfaabe3f1a84b27db59a4a153d882d2b2103596555ed9494c6ac893c49723833ec8926c1039586a7afcf4a0d9c731e985d99589c03b838e8aaf745533ed9e8ae3a1cd074a51a20da8aba18d1dbebbc862ded42435e02476930d069896cff30eb414f727b89e001afa2fb8dc3436d75a4a6f26572504b0b2232ecb9f0c02411e52596bc5e90457e745939ffedbd12863ce71a02af117d417adb3d15cc54dcb1fce467500c6b8fb86b12b56da9c382857deecc40a98d5f2903395ee4762dd21afdbb5d47fa9a6dd984d567db2857b927b7fae2db587105415d0242789d38f50b8dbcc129cab3d17d19f3355bcf73cecb8cb8a5da01307152f13902a270572670dc82d39026c6cb4cd4b0f7f5aa2a4f5a5341ec5dd715406f2fdd2a02733f5f641c8c21862a1bafce2609d9eecfa158cfb5cd79f88008e315dc7d8388036c1782fd2795d18a763624c25fa959cc97489ce75745824b77868c53239cfbdf73caec65604037314faaceb56218c6bd30f8374ac13386793f21a9fb80ad03bc0cda4a44946c00e1b1a1df0e5b87b5bece477a709649e950060591394812951e1fe3895b8cc3d14d2cf6556df6ed4b4ddd3d9a69f53357d7767f4f5ccbdbc596631277f8fecd08cb056b95e3025b9792fff7f244fc716269b926d62e9596fa825c6bf21aff9e68625a192440ea06828123d97884806f15fa08da52754a1095e3ff1abd5ce4fddfccfc3a6128aef784a64610a89d1a7099216d0814d3a2d452431c32d411ac1cce82ad0229407bbc48985675e3f874a4533f1d63a84dfa3e0f460fe2f57e34fbc75423c3737f5b2a0615f5722db041a3ef66fa483afd3c2e19e59444a64add6df1d963f5dd5b5010d3d025f0287c4cf19c75f33d51ddddba5d657b43ee8da645443814cc7329f3e9b4e54c236c29af3923101756d9fa4bd0f7d2ddaacb6b0f86a2658e0a07a05ac5b950051cd24c47a88d13d659ba2a46ca1830816d09cd7646f76f716abec5de07fe9b523410806ea6f288f8736c23357c85f45791e1708029d9824d90704607f387a03e49bf9836574431345a7877efaa8a08e73081ef8d62cb780ab6883a50a0d470190dfba10a857f82842d3825b3d6da0573d316eb160dc0b716c48fbd467f75b780149ae8808f4e68f50c0536acddf6f1aeab016b6bc1ec144b4e553acfd670f77e755fc88e0677e31ba459b44e307768958fe3789d41c2b1ff434cb30e15914f01bc6bc2307b488d2556d7b7380ea4ffd712f6b02fe806b94569cd4059f396bf29b99d0a40e5e1711ca944f72d436a102fca4b97693da0b086fe9d2e7162470d02e0f05d4bec9512bfb3f38327296efaa74328b118c27402c70c3a90b49ad4bbc68e37c0aa7d9b3fe17799d73b841e751713a02943905aae0803fd69442eb7681ec2a05600054e92eed555028f21b6a155268a2dd6640a69301a52a38d4d9f9f957ae35af7167118141ce4c9be0a6a492fe79f1581a155fa3a2b9dafd82e650b386ad3a08cb6b83131ac300b0846354a7eef9c410e4b62c47c5426907dfc6685c5c99b7141ac626ab4761fd3f41e728e1a28f89db89ffdeca364dd2f0f0739f0534556483199c71f189341ac9b78a269164206a0ea1ce73bfb2a942e7370b247c046f8e75ef8e3f8bd821cf577491864e20e6d08fd2e32b555c92c661f19588b72a89599710a88061253ca285b6304b37da2b5294f5cb354a894322848ccbdc7c2545b7da568afac87ffa005c312241c2d57f4b45d6419f0d2e2c5af33ae243785b325cdab95404fc7aed70525cddb41872cfcc214b13232edc78609753dbff930eb0dc156612b9cb434bc4b693392deb87c530435312edcedc6a961133338d786c4a3e103f60110a16b1337129704bf4754ff6ba9fbe65951e610620f71cda8fc877625f2c5bb04cbe1228b1e886f4050afd8fe94e97d2e9e85c6bb748c0042d3249abb1342bb0eebf62058bf3de080d94611a3750915b5dc6c0b3899d41222bace760ee9c8818ded599e34c56d7372af1eb86852f2a732104bdb750739de6c2c6e0f9eb7cb17f1942bfc9f4fd6ebb6b4cdd4da2bca26fac4578e9f543405acc7d86ff59158bd0cba3aef6f4a8472d144d99f8b8d1dedaa9077d4f01d4bb27bbe31d88fbefac3dcd4797563a26b1d61fcd9a464ab21ed550fe6fa09695ba0b2f10e00000000000000000000000000000000ea6468cc6e20a66f826e3d14c5006f0563887f5e1289be1b2004caca8d3f34d6e84bf59c1e04619a7c23a996941d889e4622a9b9b1d59d5e319094318cd405ba27b7e2c084762d31453ec4549a4d97729d03
header: 03000080
nVersionGroupId: 7082c403
vin: 02 4201cfb1cd8dbf69b8250c18ef41294ca97993db546c1fe01f7e9c8e36d6a5e2 9d4e30a7 03ac6a00 98421c69
378af1e40f64e125946f62c2fa7b2fecbcb64b6968912a6381ce3dc166d56a1d 62f5a8d7 056363635353 e8c7203d
vout: 02 d2da86387ae60100 080063656a63ac5200
a7622997f4ff0400 0751510053536565
nLockTime: 97b0e4e4
nExpiryHeight: c705fc05
vJoinSplit: 02
vpub_old: 0000000000000000
vpub_new: 0000000000000000
anchor: 76495c222f7fba1e31defa3d5a57efc2e1e9b01a035587d5fb1a38e01d94903d
nullifiers: 3c3e0ad3360c1d3710acd20b183e31d49f25c9a138f49b1a537edcf04be34a98 51a7af9db6990ed83dd64af3597c04323ea51b0052ad8084a8b9da948d320dad
commitments: d64f5431e61ddf658d24ae67c22c8d1309131fc00fe7f235734276d38d47f1e1 91e00c7a1d48af046827591e9733a97fa6b679f3dc601d008285edcbdae69ce8
ephemeralKey: fc1be4aac00ff2711ebd931de518856878f73476f21a482ec9378365c8f7393c
randomSeed: 94e2885315eb4671098b79535e790fe53e29fef2b3766697ac32b4f473f468a0
macs: 08e72389fc03880d780cb07fcfaabe3f1a84b27db59a4a153d882d2b21035965 55ed9494c6ac893c49723833ec8926c1039586a7afcf4a0d9c731e985d99589c
proof: 03b838e8aaf745533ed9e8ae3a1cd074a51a20da8aba18d1dbebbc862ded42435e02476930d069896cff30eb414f727b89e001afa2fb8dc3436d75a4a6f26572504b0b2232ecb9f0c02411e52596bc5e90457e745939ffedbd12863ce71a02af117d417adb3d15cc54dcb1fce467500c6b8fb86b12b56da9c382857deecc40a98d5f2903395ee4762dd21afdbb5d47fa9a6dd984d567db2857b927b7fae2db587105415d0242789d38f50b8dbcc129cab3d17d19f3355bcf73cecb8cb8a5da01307152f13902a270572670dc82d39026c6cb4cd4b0f7f5aa2a4f5a5341ec5dd715406f2fdd2a02733f5f641c8c21862a1bafce2609d9eecfa158cfb5cd79f88008e315dc7d8388036c1782fd2795d18a763624c25fa959cc97489ce75745824b77868c53239cfbdf
ciphertexts:
73caec65604037314faaceb56218c6bd30f8374ac13386793f21a9fb80ad03bc0cda4a44946c00e1b1a1df0e5b87b5bece477a709649e950060591394812951e1fe3895b8cc3d14d2cf6556df6ed4b4ddd3d9a69f53357d7767f4f5ccbdbc596631277f8fecd08cb056b95e3025b9792fff7f244fc716269b926d62e9596fa825c6bf21aff9e68625a192440ea06828123d97884806f15fa08da52754a1095e3ff1abd5ce4fddfccfc3a6128aef784a64610a89d1a7099216d0814d3a2d452431c32d411ac1cce82ad0229407bbc48985675e3f874a4533f1d63a84dfa3e0f460fe2f57e34fbc75423c3737f5b2a0615f5722db041a3ef66fa483afd3c2e19e59444a64add6df1d963f5dd5b5010d3d025f0287c4cf19c75f33d51ddddba5d657b43ee8da645443814cc7329f3e9b4e54c236c29af3923101756d9fa4bd0f7d2ddaacb6b0f86a2658e0a07a05ac5b950051cd24c47a88d13d659ba2a46ca1830816d09cd7646f76f716abec5de07fe9b523410806ea6f288f8736c23357c85f45791e1708029d9824d90704607f387a03e49bf9836574431345a7877efaa8a08e73081ef8d62cb780ab6883a50a0d470190dfba10a857f82842d3825b3d6da0573d316eb160dc0b716c48fbd467f75b780149ae8808f4e68f50c0536acddf6f1aeab016b6bc1ec144b4e553acfd670f77e755fc88e0677e31ba459b44e307768958fe3789d41c2b1ff434cb30e15914f01bc6bc2307b488d2556d7b7380ea4ffd712f6b02fe806b94569cd4059f396bf29b99d0a40e5e1711ca944f72d436a102fca4b97693da0b086fe9d2e7162470d02e0f05d4bec9512bf
b3f38327296efaa74328b118c27402c70c3a90b49ad4bbc68e37c0aa7d9b3fe17799d73b841e751713a02943905aae0803fd69442eb7681ec2a05600054e92eed555028f21b6a155268a2dd6640a69301a52a38d4d9f9f957ae35af7167118141ce4c9be0a6a492fe79f1581a155fa3a2b9dafd82e650b386ad3a08cb6b83131ac300b0846354a7eef9c410e4b62c47c5426907dfc6685c5c99b7141ac626ab4761fd3f41e728e1a28f89db89ffdeca364dd2f0f0739f0534556483199c71f189341ac9b78a269164206a0ea1ce73bfb2a942e7370b247c046f8e75ef8e3f8bd821cf577491864e20e6d08fd2e32b555c92c661f19588b72a89599710a88061253ca285b6304b37da2b5294f5cb354a894322848ccbdc7c2545b7da568afac87ffa005c312241c2d57f4b45d6419f0d2e2c5af33ae243785b325cdab95404fc7aed70525cddb41872cfcc214b13232edc78609753dbff930eb0dc156612b9cb434bc4b693392deb87c530435312edcedc6a961133338d786c4a3e103f60110a16b1337129704bf4754ff6ba9fbe65951e610620f71cda8fc877625f2c5bb04cbe1228b1e886f4050afd8fe94e97d2e9e85c6bb748c0042d3249abb1342bb0eebf62058bf3de080d94611a3750915b5dc6c0b3899d41222bace760ee9c8818ded599e34c56d7372af1eb86852f2a732104bdb750739de6c2c6e0f9eb7cb17f1942bfc9f4fd6ebb6b4cdd4da2bca26fac4578e9f543405acc7d86ff59158bd0cba3aef6f4a8472d144d99f8b8d1dedaa9077d4f01d4bb27bbe31d88fbefac3dcd4797563a26b1d61fcd9a464ab21ed550fe6fa09695ba0b2f10e
vpub_old: 0000000000000000
vpub_new: 0000000000000000
anchor: ea6468cc6e20a66f826e3d14c5006f0563887f5e1289be1b2004caca8d3f34d6
nullifiers: e84bf59c1e04619a7c23a996941d889e4622a9b9b1d59d5e319094318cd405ba 27b7e2c084762d31453ec4549a4d97729d033460fcf89d6494f2ffd789e98082
commitments: ea5ce9534b3acd60fe49e37e4f666931677319ed89f85588741b3128901a93bd 78e4be0225a9e2692c77c969ed0176bdf9555948cbd5a332d045de6ba6bf4490
ephemeralKey: adfe7444cd467a09075417fcc0062e49f008c51ad4227439c1b4476ccd8e9786
randomSeed: 2dab7be1e8d399c05ef27c6e22ee273e15786e394c8f1be31682a30147963ac8
macs: da8d41d804258426a3f70289b8ad19d8de13be4eebe3bd4c8a6f55d6e0c373d4 56851879f5fbc282db9e134806bff71e11bc33ab75dd6ca067fb73a043b646a7
proof: 0339cab4928386786d2f24141ee120fdc34d6764eafc66880ee0204f53cc1167ed02b43a52dea3ca7cff8ef35cd8e6d7c111a68ef44bcd0c1513ad47ca61c659cc5d0a5b440f6b9f59aff66879bb6688fd2859362b182f207b3175961f6411a493bffd048e7d0d87d82fe6f990a2b0a25f5aa0111a6e68f37bf6f3ac2d26b84686e569038d99c1383597fad81193c4c1b16e6a90e2d507cdfe6fbdaa86163e9cf5de310003ca7e8da047b090db9f37952fbfee76af61668190bd52ed490e677b515d0143840307219c7c0ee7fc7bfc79f325644e4df4c0d7db08e9f0bd024943c705abff899403a605cfbc7ed746a7d3f7c37d9e8bdc433b7d79e08a12f738a8f0dbddfef2f26502f3e47d1b0fd11e6a13311fb799c79c641d9da43b33e7ad012e28255398789262
ciphertexts:
275f1175be8462c01491c4d842406d0ec4282c9526174a09878fe8fdde33a29604e5e5e7b2a025d6650b97dbb52befb59b1d30a57433b0a351474444099daa371046613260cf3354cfcdada663ece824ffd7e44393886a86165ddddf2b4c41773554c86995269408b11e6737a4c447586f69173446d8e48bf84cbc000a807899973eb93c5e819aad669413f8387933ad1584aa35e43f4ecd1e2d0407c0b1b89920ffdfdb9bea51ac95b557af71b89f903f5d9848f14fcbeb1837570f544d6359eb23faf38a0822da36ce426c4a2fbeffeb0a8a2e297a9d19ba15024590e3329d9fa9261f9938a4032dd34606c9cf9f3dd33e576f05cd1dd6811c6298757d77d9e810abdb226afcaa4346a6560f8932b3181fd355d5d391976183f8d99388839632d6354f666d09d3e5629ea19737388613d38a34fd0f6e50ee5a0cc9677177f50028c141378187bd2819403fc534f80076e9380cb4964d3b6b45819d3b8e9caf54f051852d671bf8c1ffde2d1510756418cb4810936aa57e6965d6fb656a760b7f19adf96c173488552193b147ee58858033dac7cd0eb204c06490bbdedf5f7571acb2ebe76acef3f2a01ee987486dfe6c3f0a5e234c127258f97a28fb5d164a8176be946b8097d0e317287f33bf9c16f9a545409ce29b1f4273725fc0df02a04ebae178b3414fb0a82d50deb09fcf4e6ee9d180ff4f56ff3bc1d3601fc2dc90d814c3256f4967d3a8d64c83fea339c51f5a8e5801fbb97835581b602465dee04b5922c2761b54245bec0c9eef2db97d22b2b3556cc969fbb13d06509765a52b3fac54b93f421bf08e18d52ddd52cc1c8ca8adfaccab7e5cc2
f4573fbbf8239bb0b8aedbf8dad16282da5c9125dba1c059d0df8abf621078f02d6c4bc86d40845ac1d59710c45f07d585eb48b32fc0167ba256e73ca3b9311c62d109497957d8dbe10aa3e866b40c0baa2bc492c19ad1e6372d9622bf163fbffeaeee796a3cd9b6fbbfa4d792f34d7fd6e763cd5859dd26833d21d9bc5452bd19515dff9f4995b35bc0c1f876e6ad11f2452dc9ae85aec01fc56f8cbfda75a7727b75ebbd6bbffb43b63a3b1b671e40feb0db002974a3c3b1a788567231bf6399ff89236981149d423802d2341a3bedb9ddcbac1fe7b6435e1479c72e7089d029e7fbbaf3cf37e9b9a6b776791e4c5e6fda57e8d5f14c8c35a2d270846b9dbe005cda16af4408f3ab06a916eeeb9c9594b70424a4c1d171295b6763b22f47f80b53ccbb904bd68fd65fbd3fbdea1035e98c21a7dbc91a9b5bc7690f05ec317c97f8764eb48e911d428ec8d861b708e8298acb62155145155ae95f0a1d1501034753146e22d05f586d7f6b4fe12dad9a17f5db70b1db96b8d9a83edadc966c8a5466b61fc998c31f1070d9a5c9a6d268d304fe6b8fd3b4010348611abdcbd49fe4f85b623c7828c71382e1034ea67bc8ae97404b0c50b2a04f559e49950afcb0ef462a2ae024b0f0224dfd73684b88c7fbe92d02b68f759c4752663cd7b97a14943649305521326bde085630864629291bae25ff8822a14c4b666a9259ad0dc42a8290ac7bc7f53a16f379f758e5de750f04fd7cad47701c8597f97888bea6fa0bf2999956fbfd0ee68ec36e4688809ae231eb8bc4369f5fe1573f57e099d9c09901bf39caac48dc11956a8ae905ead86954547c448ae43d31
joinSplitPubKey: 5e669c4242da565938f417bf43ce7b2b30b1cd4018388e1a910f0fc41fb0877a
joinSplitSig: 5925e466819d375b0a912d4fe843b76ef6f223f0f7c894f38f7ab780dfd75f669c8c06cffa43eb47565a50e3b1fa45ad61ce9a1c4727b7aaa53562f523e73952
(joinSplitPubKey is a potentially-invalid public key; joinSplitSig is invalid random data)</code></pre>
<p>Transaction digest with <code>nIn = 1</code> and <code>nHashType = 3</code> (<code>SIGHASH_SINGLE</code>):</p>
<pre><code>hashPrevouts:
BLAKE2b-256(&#39;ZcashPrevoutHash&#39;, 4201cfb1cd8dbf69b8250c18ef41294ca97993db546c1fe01f7e9c8e36d6a5e29d4e30a7378af1e40f64e125946f62c2fa7b2fecbcb64b6968912a6381ce3dc166d56a1d62f5a8d7)
= 92b8af1f7e12cb8de105af154470a2ae0a11e64a24a514a562ff943ca0f35d7f
hashOutputs:
BLAKE2b-256(&#39;ZcashOutputsHash&#39;, 23752997f4ff04000751510053536565)
= e03b74bc5187184406285bb9f03b4be510f5700c5859738434cf7b8f5bdb6772
hashJoinSplits:
BLAKE2b-256(&#39;ZcashJSplitsHash&#39;, 0000000000000000000000000000000076495c222f7fba1e31defa3d5a57efc2e1e9b01a035587d5fb1a38e01d94903d3c3e0ad3360c1d3710acd20b183e31d49f25c9a138f49b1a537edcf04be34a9851a7af9db6990ed83dd64af3597c04323ea51b0052ad8084a8b9da948d320dadd64f5431e61ddf658d24ae67c22c8d1309131fc00fe7f235734276d38d47f1e191e00c7a1d48af046827591e9733a97fa6b679f3dc601d008285edcbdae69ce8fc1be4aac00ff2711ebd931de518856878f73476f21a482ec9378365c8f7393c94e2885315eb4671098b79535e790fe53e29fef2b3766697ac32b4f473f468a008e72389fc03880d780cb07fcfaabe3f1a84b27db59a4a153d882d2b2103596555ed9494c6ac893c49723833ec8926c1039586a7afcf4a0d9c731e985d99589c03b838e8aaf745533ed9e8ae3a1cd074a51a20da8aba18d1dbebbc862ded42435e02476930d069896cff30eb414f727b89e001afa2fb8dc3436d75a4a6f26572504b0b2232ecb9f0c02411e52596bc5e90457e745939ffedbd12863ce71a02af117d417adb3d15cc54dcb1fce467500c6b8fb86b12b56da9c382857deecc40a98d5f2903395ee4762dd21afdbb5d47fa9a6dd984d567db2857b927b7fae2db587105415d0242789d38f50b8dbcc129cab3d17d19f3355bcf73cecb8cb8a5da01307152f13902a270572670dc82d39026c6cb4cd4b0f7f5aa2a4f5a5341ec5dd715406f2fdd2a02733f5f641c8c21862a1bafce2609d9eecfa158cfb5cd79f88008e315dc7d8388036c1782fd2795d18a763624c25fa959cc97489ce75745824b77868c53239cfbdf73caec65604037314faaceb56218c6bd30f8374ac13386793f21a9fb80ad03bc0cda4a44946c00e1b1a1df0e5b87b5bece477a709649e950060591394812951e1fe3895b8cc3d14d2cf6556df6ed4b4ddd3d9a69f53357d7767f4f5ccbdbc596631277f8fecd08cb056b95e3025b9792fff7f244fc716269b926d62e9596fa825c6bf21aff9e68625a192440ea06828123d97884806f15fa08da52754a1095e3ff1abd5ce4fddfccfc3a6128aef784a64610a89d1a7099216d0814d3a2d452431c32d411ac1cce82ad0229407bbc48985675e3f874a4533f1d63a84dfa3e0f460fe2f57e34fbc75423c3737f5b2a0615f5722db041a3ef66fa483afd3c2e19e59444a64add6df1d963f5dd5b5010d3d025f0287c4cf19c75f33d51ddddba5d657b43ee8da645443814cc7329f3e9b4e54c236c29af3923101756d9fa4bd0f7d2ddaacb6b0f86a2658e0a07a05ac5b950051cd24c47a88d13d659ba2a46ca1830816d09cd7646f76f716abec5de07fe9b523410806ea6f288f8736c23357c85f45791e1708029d9824d90704607f387a03e49bf9836574431345a7877efaa8a08e73081ef8d62cb780ab6883a50a0d470190dfba10a857f82842d3825b3d6da0573d316eb160dc0b716c48fbd467f75b780149ae8808f4e68f50c0536acddf6f1aeab016b6bc1ec144b4e553acfd670f77e755fc88e0677e31ba459b44e307768958fe3789d41c2b1ff434cb30e15914f01bc6bc2307b488d2556d7b7380ea4ffd712f6b02fe806b94569cd4059f396bf29b99d0a40e5e1711ca944f72d436a102fca4b97693da0b086fe9d2e7162470d02e0f05d4bec9512bfb3f38327296efaa74328b118c27402c70c3a90b49ad4bbc68e37c0aa7d9b3fe17799d73b841e751713a02943905aae0803fd69442eb7681ec2a05600054e92eed555028f21b6a155268a2dd6640a69301a52a38d4d9f9f957ae35af7167118141ce4c9be0a6a492fe79f1581a155fa3a2b9dafd82e650b386ad3a08cb6b83131ac300b0846354a7eef9c410e4b62c47c5426907dfc6685c5c99b7141ac626ab4761fd3f41e728e1a28f89db89ffdeca364dd2f0f0739f0534556483199c71f189341ac9b78a269164206a0ea1ce73bfb2a942e7370b247c046f8e75ef8e3f8bd821cf577491864e20e6d08fd2e32b555c92c661f19588b72a89599710a88061253ca285b6304b37da2b5294f5cb354a894322848ccbdc7c2545b7da568afac87ffa005c312241c2d57f4b45d6419f0d2e2c5af33ae243785b325cdab95404fc7aed70525cddb41872cfcc214b13232edc78609753dbff930eb0dc156612b9cb434bc4b693392deb87c530435312edcedc6a961133338d786c4a3e103f60110a16b1337129704bf4754ff6ba9fbe65951e610620f71cda8fc877625f2c5bb04cbe1228b1e886f4050afd8fe94e97d2e9e85c6bb748c0042d3249abb1342bb0eebf62058bf3de080d94611a3750915b5dc6c0b3899d41222bace760ee9c8818ded599e34c56d7372af1eb86852f2a732104bdb750739de6c2c6e0f9eb7cb17f1942bfc9f4fd6ebb6b4cdd4da2bca26fac4578e9f543405acc7d86ff59158bd0cba3aef6f4a8472d144d99f8b8d1dedaa9077d4f01d4bb27bbe31d88fbefac3dcd4797563a26b1d61fcd9a464ab21ed550fe6fa09695ba0b2f10e00000000000000000000000000000000ea6468cc6e20a66f826e3d14c5006f0563887f5e1289be1b2004caca8d3f34d6e84bf59c1e04619a7c23a996941d889e4622a9b9b1d59d5e319094318cd405ba27b7e2c084762d31453ec4549a4d97729d033460fcf89d6494f2ffd789e98082ea5ce9534b3acd60fe49e37e4f666931677319ed89f85588741b3128901a93bd78e4be0225a9e2692c77c969ed0176bdf9555948cbd5a332d045de6ba6bf4490adfe7444cd467a09075417fcc0062e49f008c51ad4227439c1b4476ccd8e97862dab7be1e8d399c05ef27c6e22ee273e1
= f59e41b40f3a60be90bee2be11b0956dfff06a6d8e22668c4f215bd87b20d514
Preimage:
030000807082c40392b8af1f7e12cb8de105af154470a2ae0a11e64a24a514a562ff943ca0f35d7f0000000000000000000000000000000000000000000000000000000000000000e03b74bc5187184406285bb9f03b4be510f5700c5859738434cf7b8f5bdb6772f59e41b40f3a60be90bee2be11b0956dfff06a6d8e22668c4f215bd87b20d51497b0e4e4c705fc0503000000378af1e40f64e125946f62c2fa7b2fecbcb64b6968912a6381ce3dc166d56a1d62f5a8d70153418404963b4c0100e8c7203d
header: 03000080
nVersionGroupId: 7082c403
hashPrevouts: 92b8af1f7e12cb8de105af154470a2ae0a11e64a24a514a562ff943ca0f35d7f
hashSequence: 0000000000000000000000000000000000000000000000000000000000000000
hashOutputs: edc32cce530f836f7c31c53656f859f514c3ff8dcae642d3e17700fdc6e829a4
hashJoinSplits: f59e41b40f3a60be90bee2be11b0956dfff06a6d8e22668c4f215bd87b20d514
nLockTime: 97b0e4e4
nExpiryHeight: c705fc05
nHashType: 03000000
Input:
prevout: 378af1e40f64e125946f62c2fa7b2fecbcb64b6968912a6381ce3dc166d56a1d 62f5a8d7
scriptCode: 0153
amount: 2f6e04963b4c0100
nSequence: e8c7203d
sighash: 23652e76cb13b85a0e3363bb5fca061fa791c40c533eccee899364e6e60bb4f7</code></pre>
<h1 id="deployment">Deployment</h1>
<p>This proposal is deployed with the Overwinter network upgrade.<a href="#fn22" class="footnote-ref" id="fnref22"><sup>22</sup></a></p>
<h1 id="backward-compatibility">Backward compatibility</h1>
<p>This proposal is backwards-compatible with old UTXOs. It is <strong>not</strong> backwards-compatible with older software. All transactions will be required to use this transaction digest algorithm for signatures, and so transactions created by older software will be rejected by the network.</p>
<h1 id="reference-implementation">Reference Implementation</h1>
<p><a href="https://github.com/zcash/zcash/pull/2903" class="uri">https://github.com/zcash/zcash/pull/2903</a></p>
<h1 id="references">References</h1>
<section class="footnotes">
<hr />
<ol>
<li id="fn1"><p><a href="https://tools.ietf.org/html/rfc2119">Key words for use in RFCs to Indicate Requirement Levels</a><a href="#fnref1" class="footnote-back"></a></p></li>
<li id="fn2"><p><a href="https://github.com/zcash/zips/blob/master/zip-0200.rst">ZIP 200: Network Upgrade Mechanism</a><a href="#fnref2" class="footnote-back"></a></p></li>
<li id="fn3"><p><a href="https://github.com/zcash/zips/blob/master/zip-0201.rst">ZIP 201: Network Peer Management for Overwinter</a><a href="#fnref3" class="footnote-back"></a></p></li>
<li id="fn4"><p><a href="https://en.bitcoin.it/wiki/OP_CHECKSIG" class="uri">https://en.bitcoin.it/wiki/OP_CHECKSIG</a><a href="#fnref4" class="footnote-back"></a></p></li>
<li id="fn5"><p><a href="https://github.com/zcash/zips/blob/master/protocol/protocol.pdf">Zcash Protocol Specification, Section 4.6</a><a href="#fnref5" class="footnote-back"></a></p></li>
<li id="fn6"><ul>
<li><a href="https://web.nvd.nist.gov/view/vuln/detail?vulnId=CVE-2013-2292">CVE-2013-2292</a></li>
<li><a href="https://bitcointalk.org/?topic=140078">New Bitcoin vulnerability: A transaction that takes at least 3 minutes to verify</a></li>
<li><a href="http://rusty.ozlabs.org/?p=522">The Megatransaction: Why Does It Take 25 Seconds?</a></li>
</ul>
<a href="#fnref6" class="footnote-back"></a></li>
<li id="fn7"><p><a href="https://bitcointalk.org/index.php?topic=181734.0">SIGHASH_WITHINPUTVALUE: Super-lightweight HW wallets and offline data</a><a href="#fnref7" class="footnote-back"></a></p></li>
<li id="fn8"><p><a href="https://github.com/bitcoin/bips/blob/master/bip-0143.mediawiki">BIP 143: Transaction Signature Verification for Version 0 Witness Program</a><a href="#fnref8" class="footnote-back"></a></p></li>
<li id="fn9"><p><a href="https://github.com/Bitcoin-ABC/bitcoin-abc/blob/master/doc/abc/replay-protected-sighash.md">BUIP-HF Digest for replay protected signature verification across hard forks, version 1.2</a><a href="#fnref9" class="footnote-back"></a></p></li>
<li id="fn10"><p><a href="https://github.com/zcash/zips/blob/master/zip-0202.rst">ZIP 202: Version 3 Transaction Format for Overwinter</a><a href="#fnref10" class="footnote-back"></a></p></li>
<li id="fn11"><p><a href="https://github.com/zcash/zips/blob/master/zip-0202.rst">ZIP 202: Version 3 Transaction Format for Overwinter</a><a href="#fnref11" class="footnote-back"></a></p></li>
<li id="fn12"><p><a href="https://github.com/zcash/zips/blob/master/zip-0201.rst">ZIP 201: Network Peer Management for Overwinter</a><a href="#fnref12" class="footnote-back"></a></p></li>
<li id="fn13"><p><a href="https://blake2.net/blake2.pdf">&quot;BLAKE2: simpler, smaller, fast as MD5&quot;, Section 2.8</a><a href="#fnref13" class="footnote-back"></a></p></li>
<li id="fn14"><p><a href="https://github.com/zcash/zips/blob/master/zip-0200.rst">ZIP 200: Network Upgrade Mechanism</a><a href="#fnref14" class="footnote-back"></a></p></li>
<li id="fn15"><p><a href="https://en.bitcoin.it/wiki/OP_CHECKSIG" class="uri">https://en.bitcoin.it/wiki/OP_CHECKSIG</a><a href="#fnref15" class="footnote-back"></a></p></li>
<li id="fn16"><p><a href="https://github.com/zcash/zips/blob/master/zip-0202.rst">ZIP 202: Version 3 Transaction Format for Overwinter</a><a href="#fnref16" class="footnote-back"></a></p></li>
<li id="fn17"><p><a href="https://github.com/zcash/zips/blob/master/zip-0202.rst">ZIP 202: Version 3 Transaction Format for Overwinter</a><a href="#fnref17" class="footnote-back"></a></p></li>
<li id="fn18"><p>In the original algorithm, a <code>uint256</code> of <code>0x0000......0001</code> is committed if the input index for a <code>SINGLE</code> signature is greater than or equal to the number of outputs. In this ZIP a <code>0x0000......0000</code> is commited, without changing the semantics.<a href="#fnref18" class="footnote-back"></a></p></li>
<li id="fn19"><p><a href="https://github.com/zcash/zips/blob/master/zip-0203.rst">ZIP 203: Transaction Expiry</a><a href="#fnref19" class="footnote-back"></a></p></li>
<li id="fn20"><p><a href="https://github.com/zcash-hackworks/zcash-test-vectors/blob/master/zip_0143.py">ZIP 143 Test Vectors</a><a href="#fnref20" class="footnote-back"></a></p></li>
<li id="fn21"><p><a href="https://github.com/zcash/zcash/blob/master/src/test/data/sighash.json">SignatureHash Test Vectors</a><a href="#fnref21" class="footnote-back"></a></p></li>
<li id="fn22"><p><a href="https://github.com/zcash/zips/blob/master/zip-0201.rst">ZIP 201: Network Peer Management for Overwinter</a><a href="#fnref22" class="footnote-back"></a></p></li>
</ol>
</section>
</body>
</html>