ZIP 304: cosmetics (math fonts).

Signed-off-by: Daira Hopwood <daira@jacaranda.org>
This commit is contained in:
Daira Hopwood 2020-08-11 19:42:42 +01:00
parent 6e5278ed95
commit 9dee5a8700
2 changed files with 87 additions and 81 deletions

View File

@ -17,7 +17,7 @@ Category: Wallet
Created: 2020-06-01
License: MIT</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" src="assets/images/section-anchor.png" alt=""></a></span></h2>
<p>The key word "SHOULD" in this document is to be interpreted as described in RFC 2119. <a id="id1" class="footnote_reference" href="#rfc2119">1</a></p>
<p>The key words "MUST" and "SHOULD" in this document is to be interpreted as described in RFC 2119. <a id="id1" class="footnote_reference" href="#rfc2119">1</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" src="assets/images/section-anchor.png" alt=""></a></span></h2>
<p>This proposal describes a mechanism for creating signatures with Sapling addresses, suitable for use by the <code>signmessage</code> and <code>verifymessage</code> RPC methods in <code>zcashd</code>.</p>
@ -41,28 +41,28 @@ License: MIT</pre>
<span class="math">\(\mathsf{MerkleCRH}^\mathsf{Sapling}\)</span>
<a id="id4" class="footnote_reference" href="#merkle-crh">5</a></li>
<li>
<span class="math">\(\mathsf{DiversifyHash}(d)\)</span>
<span class="math">\(\mathsf{DiversifyHash}(\mathsf{d})\)</span>
<a id="id5" class="footnote_reference" href="#diversify-hash">6</a></li>
<li>
<span class="math">\(\mathsf{MixingPedersenHash}(cm, position)\)</span>
<span class="math">\(\mathsf{MixingPedersenHash}(\mathsf{cm}, position)\)</span>
<a id="id6" class="footnote_reference" href="#mixing-pedersen-hash">7</a></li>
<li>
<span class="math">\(\mathsf{PRF}^\mathsf{nfSapling}_nk(ρ)\)</span>
<span class="math">\(\mathsf{PRF}^\mathsf{nfSapling}_\mathsf{nk}(ρ)\)</span>
<a id="id7" class="footnote_reference" href="#prfs">8</a></li>
<li>
<span class="math">\(\mathsf{SpendAuthSig.RandomizePrivate}(α, sk)\)</span>
<span class="math">\(\mathsf{SpendAuthSig.RandomizePrivate}(α, \mathsf{sk})\)</span>
,
<span class="math">\(\mathsf{SpendAuthSig.RandomizePublic}(α, vk)\)</span>
<span class="math">\(\mathsf{SpendAuthSig.RandomizePublic}(α, \mathsf{vk})\)</span>
,
<span class="math">\(\mathsf{SpendAuthSig.Sign}(sk, m)\)</span>
<span class="math">\(\mathsf{SpendAuthSig.Sign}(\mathsf{sk}, m)\)</span>
, and
<span class="math">\(\mathsf{SpendAuthSig.Verify}(vk, m, σ)\)</span>
<span class="math">\(\mathsf{SpendAuthSig.Verify}(\mathsf{vk}, m, σ)\)</span>
<a id="id8" class="footnote_reference" href="#spend-auth-sig">9</a></li>
<li>
<span class="math">\(\mathsf{NoteCommit}^\mathsf{Sapling}_rcm(g_d, pk_d, value)\)</span>
<span class="math">\(\mathsf{NoteCommit}^\mathsf{Sapling}_\mathsf{rcm}(\mathsf{g_d}, \mathsf{pk_d}, value)\)</span>
<a id="id9" class="footnote_reference" href="#note-commit">10</a></li>
<li>
<span class="math">\(\mathsf{ValueCommit}_rcv(value)\)</span>
<span class="math">\(\mathsf{ValueCommit}_\mathsf{rcv}(value)\)</span>
<a id="id10" class="footnote_reference" href="#value-commit">11</a></li>
</ul>
<p>We also reproduce some notation and functions here for convenience:</p>
@ -102,17 +102,21 @@ License: MIT</pre>
<section id="specification"><h2><span class="section-heading">Specification</span><span class="section-anchor"> <a rel="bookmark" href="#specification"><img width="24" height="24" src="assets/images/section-anchor.png" alt=""></a></span></h2>
<p>A Sapling address signature is created by taking the process for creating a Sapling Spend description, and running it with fixed inputs:</p>
<ul>
<li>A fake Sapling note with a value of 1 zatoshi and rcm = 0.</li>
<li>A fake Sapling note with a value of
<span class="math">\(1\)</span>
zatoshi and
<span class="math">\(\mathsf{rcm} = 0\)</span>
.</li>
<li>A Sapling commitment tree that is empty except for the commitment for the fake note.</li>
</ul>
<section id="signature-algorithm"><h3><span class="section-heading">Signature algorithm</span><span class="section-anchor"> <a rel="bookmark" href="#signature-algorithm"><img width="24" height="24" src="assets/images/section-anchor.png" alt=""></a></span></h3>
<p>The inputs to the signature algorithm are:</p>
<ul>
<li>The payment address
<span class="math">\((d, pk_d)\)</span>
<span class="math">\((\mathsf{d}, \mathsf{pk_d})\)</span>
,</li>
<li>Its corresponding expanded spending key
<span class="math">\((ask, nsk, ovk)\)</span>
<span class="math">\((\mathsf{ask}, \mathsf{nsk}, \mathsf{ovk})\)</span>
,</li>
<li>The SLIP-44 <a id="id12" class="footnote_reference" href="#slip-0044">13</a> coin type, and</li>
<li>The message
@ -122,13 +126,13 @@ License: MIT</pre>
<p>The signature is created as follows:</p>
<ul>
<li>Derive the full viewing key
<span class="math">\((ak, nk, ovk)\)</span>
<span class="math">\((\mathsf{ak}, \mathsf{nk}, \mathsf{ovk})\)</span>
from the expanded spending key.</li>
<li>Let
<span class="math">\(g_d = \mathsf{DiversifyHash}(d)\)</span>
.</li>
<li>Let
<span class="math">\(cm = \mathsf{NoteCommit}^\mathsf{Sapling}_0(\mathsf{repr}_\mathbb{J}(g_d), \mathsf{repr}_\mathbb{J}(pk_d), 1)\)</span>
<span class="math">\(cm = \mathsf{NoteCommit}^\mathsf{Sapling}_0(\mathsf{repr}_\mathbb{J}(\mathsf{g_d}), \mathsf{repr}_\mathbb{J}(\mathsf{pk_d}), 1)\)</span>
.</li>
<li>Let
<span class="math">\(rt\)</span>
@ -147,30 +151,30 @@ License: MIT</pre>
<span class="math">\(rt\)</span>
. <a id="id13" class="footnote_reference" href="#merkle-path">14</a></li>
<li>Let
<span class="math">\(cv = \mathsf{ValueCommit}_0(1)\)</span>
<span class="math">\(\mathsf{cv} = \mathsf{ValueCommit}_0(1)\)</span>
.
<ul>
<li>This is a constant and may be pre-computed.</li>
</ul>
</li>
<li>Let
<span class="math">\(nf = \mathsf{PRF}^\mathsf{nfSapling}_{\mathsf{repr}_\mathbb{J}(nk)}(\mathsf{repr}_\mathbb{J}(\mathsf{MixingPedersenHash}(cm, 0)))\)</span>
<span class="math">\(nf = \mathsf{PRF}^\mathsf{nfSapling}_{\mathsf{repr}_\mathbb{J}(\mathsf{nk})}(\mathsf{repr}_\mathbb{J}(\mathsf{MixingPedersenHash}(\mathsf{cm}, 0)))\)</span>
.</li>
<li>Select a random
<span class="math">\(α\)</span>
.</li>
<li>Let
<span class="math">\(rk = \mathsf{SpendAuthSig.RandomizePublic}(α, ak)\)</span>
<span class="math">\(\mathsf{rk} = \mathsf{SpendAuthSig.RandomizePublic}(α, \mathsf{ak})\)</span>
.</li>
<li>Let
<span class="math">\(zkproof\)</span>
be a Sapling spend proof with primary input
<span class="math">\((rt, cv, nf, rk)\)</span>
<span class="math">\((\mathsf{rt}, \mathsf{cv}, \mathsf{nf}, \mathsf{rk})\)</span>
and auxiliary input
<span class="math">\((path, 0, g_d, pk_d, 1, 0, cm, 0, α, ak, nsk)\)</span>
<span class="math">\((path, 0, \mathsf{g_d}, \mathsf{pk_d}, 1, 0, \mathsf{cm}, 0, α, \mathsf{ak}, \mathsf{nsk})\)</span>
. <a id="id14" class="footnote_reference" href="#spend-statement">15</a></li>
<li>Let
<span class="math">\(rsk = \mathsf{SpendAuthSig.RandomizePrivate}(α, ask)\)</span>
<span class="math">\(\mathsf{rsk} = \mathsf{SpendAuthSig.RandomizePrivate}(α, \mathsf{ask})\)</span>
.</li>
<li>Let
<span class="math">\(coinType\)</span>
@ -179,10 +183,10 @@ License: MIT</pre>
<span class="math">\(digest = \mathsf{BLAKE2b}\text{-}\mathsf{256}(\texttt{"ZIP304Signed"}\,||\,coinType, zkproof\,||\,msg)\)</span>
.</li>
<li>Let
<span class="math">\(spendAuthSig = \mathsf{SpendAuthSig.Sign}(rsk, digest)\)</span>
<span class="math">\(spendAuthSig = \mathsf{SpendAuthSig.Sign}(\mathsf{rsk}, digest)\)</span>
.</li>
<li>Return
<span class="math">\((nf, rk, zkproof, spendAuthSig)\)</span>
<span class="math">\((\mathsf{nf}, \mathsf{rk}, zkproof, spendAuthSig)\)</span>
.</li>
</ul>
</section>
@ -190,17 +194,17 @@ License: MIT</pre>
<p>The inputs to the verification algorithm are:</p>
<ul>
<li>The payment address
<span class="math">\((d, pk_d)\)</span>
<span class="math">\((\mathsf{d}, \mathsf{pk_d})\)</span>
,</li>
<li>The SLIP-44 <a id="id15" class="footnote_reference" href="#slip-0044">13</a> coin type,</li>
<li>The message
<span class="math">\(msg\)</span>
that is claimed to be signed, and</li>
<li>The ZIP 304 signature
<span class="math">\((nf, rk, zkproof, spendAuthSig)\)</span>
<span class="math">\((\mathsf{nf}, \mathsf{rk}, zkproof, spendAuthSig)\)</span>
.</li>
</ul>
<p>The signature is verified as follows:</p>
<p>The signature MUST be verified as follows:</p>
<ul>
<li>Let
<span class="math">\(coinType\)</span>
@ -209,29 +213,29 @@ License: MIT</pre>
<span class="math">\(digest = \mathsf{BLAKE2b}\text{-}\mathsf{256}(\texttt{"ZIP304Signed"}\,||\,coinType, zkproof\,||\,msg)\)</span>
.</li>
<li>If
<span class="math">\(\mathsf{SpendAuthSig.Verify}(rk, digest, spendAuthSig) = 0\)</span>
<span class="math">\(\mathsf{SpendAuthSig.Verify}(\mathsf{rk}, digest, spendAuthSig) = 0\)</span>
, return false.</li>
<li>Let
<span class="math">\(cm = \mathsf{NoteCommit}^\mathsf{Sapling}_0(\mathsf{repr}_\mathbb{J}(\mathsf{DiversifyHash}(d)), \mathsf{repr}_\mathbb{J}(pk_d), 1)\)</span>
<span class="math">\(\mathsf{cm} = \mathsf{NoteCommit}^\mathsf{Sapling}_0(\mathsf{repr}_\mathbb{J}(\mathsf{DiversifyHash}(\mathsf{d})), \mathsf{repr}_\mathbb{J}(\mathsf{pk_d}), 1)\)</span>
.</li>
<li>Let
<span class="math">\(rt\)</span>
<span class="math">\(\mathsf{rt}\)</span>
be the root of a Merkle tree with depth
<span class="math">\(\mathsf{MerkleDepth}^\mathsf{Sapling}\)</span>
and hashing function
<span class="math">\(\mathsf{MerkleCRH}^\mathsf{Sapling}\)</span>
, containing
<span class="math">\(cm\)</span>
<span class="math">\(\mathsf{cm}\)</span>
at position 0, and
<span class="math">\(\mathsf{Uncommitted}^\mathsf{Sapling}\)</span>
at all other positions.</li>
<li>Let
<span class="math">\(path\)</span>
be the Merkle path from position 0 to
<span class="math">\(rt\)</span>
<span class="math">\(\mathsf{rt}\)</span>
. <a id="id16" class="footnote_reference" href="#merkle-path">14</a></li>
<li>Let
<span class="math">\(cv = \mathsf{ValueCommit}_0(1)\)</span>
<span class="math">\(\mathsf{cv} = \mathsf{ValueCommit}_0(1)\)</span>
.
<ul>
<li>This is a constant and may be pre-computed.</li>
@ -240,31 +244,33 @@ License: MIT</pre>
<li>Verify
<span class="math">\(zkproof\)</span>
as a Sapling spend proof with primary input
<span class="math">\((rt, cv, nf, rk)\)</span>
<span class="math">\((\mathsf{rt}, \mathsf{cv}, \mathsf{nf}, \mathsf{rk})\)</span>
. <a id="id17" class="footnote_reference" href="#spend-statement">15</a> If verification fails, return false.</li>
<li>Return true.</li>
</ul>
</section>
<section id="signature-encoding"><h3><span class="section-heading">Signature encoding</span><span class="section-anchor"> <a rel="bookmark" href="#signature-encoding"><img width="24" height="24" src="assets/images/section-anchor.png" alt=""></a></span></h3>
<p>The raw form of a ZIP 304 signature is
<span class="math">\(nf\,||\,rk\,||\,zkproof\,||\,spendAuthSig\)</span>
<span class="math">\(\mathsf{nf}\,||\,\mathsf{rk}\,||\,zkproof\,||\,spendAuthSig\)</span>
, for a total size of 320 bytes.</p>
<p>When encoding a ZIP 304 signature in a human-readable format, implementations <strong>SHOULD</strong> use standard Base64 for compatibility with the <code>signmessage</code> and <code>verifymessage</code> RPC methods in <code>zcashd</code>. ZIP 304 signatures in this form are 428 bytes. The encoded form is the string 'zip304:' followed by the result of Base64-encoding <a id="id18" class="footnote_reference" href="#rfc4648">2</a> the raw form of the signature.</p>
</section>
</section>
<section id="rationale"><h2><span class="section-heading">Rationale</span><span class="section-anchor"> <a rel="bookmark" href="#rationale"><img width="24" height="24" src="assets/images/section-anchor.png" alt=""></a></span></h2>
<p>We use a fake note within the signature scheme in order to reuse the Sapling Spend circuit and its parameters. It is possible to construct a signature scheme with a smaller encoded signature, but this would require a new circuit and another parameter-generation ceremony (if Groth16 were used).</p>
<p>We use a note value of 1 zatoshi instead of zero to ensure that the payment address is fully bound to
<p>We use a note value of
<span class="math">\(1\)</span>
zatoshi instead of zero to ensure that the payment address is fully bound to
<span class="math">\(zkproof\)</span>
. Notes with zero value have certain constraints disabled inside the circuit.</p>
<p>We set
<span class="math">\(rcm\)</span>
<span class="math">\(\mathsf{rcm}\)</span>
and
<span class="math">\(rcv\)</span>
<span class="math">\(\mathsf{rcv}\)</span>
to zero because we do not need the hiding properties of the note commitment or value commitment schemes (as we are using a fixed-value fake note), and can thus omit both
<span class="math">\(rcm\)</span>
<span class="math">\(\mathsf{rcm}\)</span>
and
<span class="math">\(rcv\)</span>
<span class="math">\(\mathsf{rcv}\)</span>
from the signature.</p>
</section>
<section id="security-and-privacy-considerations"><h2><span class="section-heading">Security and Privacy Considerations</span><span class="section-anchor"> <a rel="bookmark" href="#security-and-privacy-considerations"><img width="24" height="24" src="assets/images/section-anchor.png" alt=""></a></span></h2>
@ -275,12 +281,12 @@ License: MIT</pre>
<p>Most of the data within a ZIP 304 signature is inherently non-malleable:</p>
<ul>
<li>
<span class="math">\(nullifier\)</span>
<span class="math">\(\mathsf{nf}\)</span>
is a binary public input to
<span class="math">\(zkproof\)</span>
.</li>
<li>
<span class="math">\(rk\)</span>
<span class="math">\(\mathsf{rk}\)</span>
is internally bound to
<span class="math">\(spendAuthSig\)</span>
by the design of RedJubjub.</li>

View File

@ -14,8 +14,8 @@
Terminology
===========
The key word "SHOULD" in this document is to be interpreted as described in RFC 2119.
[#RFC2119]_
The key words "MUST" and "SHOULD" in this document is to be interpreted as described in
RFC 2119. [#RFC2119]_
Abstract
@ -68,15 +68,15 @@ specification: [#protocol-spec]_
- :math:`\mathsf{MerkleDepth}^\mathsf{Sapling}` and
:math:`\mathsf{Uncommitted}^\mathsf{Sapling}` [#constants]_
- :math:`\mathsf{MerkleCRH}^\mathsf{Sapling}` [#merkle-crh]_
- :math:`\mathsf{DiversifyHash}(d)` [#diversify-hash]_
- :math:`\mathsf{MixingPedersenHash}(cm, position)` [#mixing-pedersen-hash]_
- :math:`\mathsf{PRF}^\mathsf{nfSapling}_nk(ρ)` [#prfs]_
- :math:`\mathsf{SpendAuthSig.RandomizePrivate}(α, sk)`,
:math:`\mathsf{SpendAuthSig.RandomizePublic}(α, vk)`,
:math:`\mathsf{SpendAuthSig.Sign}(sk, m)`, and
:math:`\mathsf{SpendAuthSig.Verify}(vk, m, σ)` [#spend-auth-sig]_
- :math:`\mathsf{NoteCommit}^\mathsf{Sapling}_rcm(g_d, pk_d, value)` [#note-commit]_
- :math:`\mathsf{ValueCommit}_rcv(value)` [#value-commit]_
- :math:`\mathsf{DiversifyHash}(\mathsf{d})` [#diversify-hash]_
- :math:`\mathsf{MixingPedersenHash}(\mathsf{cm}, position)` [#mixing-pedersen-hash]_
- :math:`\mathsf{PRF}^\mathsf{nfSapling}_\mathsf{nk}(ρ)` [#prfs]_
- :math:`\mathsf{SpendAuthSig.RandomizePrivate}(α, \mathsf{sk})`,
:math:`\mathsf{SpendAuthSig.RandomizePublic}(α, \mathsf{vk})`,
:math:`\mathsf{SpendAuthSig.Sign}(\mathsf{sk}, m)`, and
:math:`\mathsf{SpendAuthSig.Verify}(\mathsf{vk}, m, σ)` [#spend-auth-sig]_
- :math:`\mathsf{NoteCommit}^\mathsf{Sapling}_\mathsf{rcm}(\mathsf{g_d}, \mathsf{pk_d}, value)` [#note-commit]_
- :math:`\mathsf{ValueCommit}_\mathsf{rcv}(value)` [#value-commit]_
We also reproduce some notation and functions here for convenience:
@ -118,7 +118,7 @@ Specification
A Sapling address signature is created by taking the process for creating a Sapling Spend
description, and running it with fixed inputs:
- A fake Sapling note with a value of 1 zatoshi and rcm = 0.
- A fake Sapling note with a value of :math:`1` zatoshi and :math:`\mathsf{rcm} = 0`.
- A Sapling commitment tree that is empty except for the commitment for the fake note.
Signature algorithm
@ -126,18 +126,18 @@ Signature algorithm
The inputs to the signature algorithm are:
- The payment address :math:`(d, pk_d)`,
- Its corresponding expanded spending key :math:`(ask, nsk, ovk)`,
- The payment address :math:`(\mathsf{d}, \mathsf{pk_d})`,
- Its corresponding expanded spending key :math:`(\mathsf{ask}, \mathsf{nsk}, \mathsf{ovk})`,
- The SLIP-44 [#slip-0044]_ coin type, and
- The message :math:`msg` to be signed.
The signature is created as follows:
- Derive the full viewing key :math:`(ak, nk, ovk)` from the expanded spending key.
- Derive the full viewing key :math:`(\mathsf{ak}, \mathsf{nk}, \mathsf{ovk})` from the expanded spending key.
- Let :math:`g_d = \mathsf{DiversifyHash}(d)`.
- Let :math:`cm = \mathsf{NoteCommit}^\mathsf{Sapling}_0(\mathsf{repr}_\mathbb{J}(g_d), \mathsf{repr}_\mathbb{J}(pk_d), 1)`.
- Let :math:`cm = \mathsf{NoteCommit}^\mathsf{Sapling}_0(\mathsf{repr}_\mathbb{J}(\mathsf{g_d}), \mathsf{repr}_\mathbb{J}(\mathsf{pk_d}), 1)`.
- Let :math:`rt` be the root of a Merkle tree with depth
:math:`\mathsf{MerkleDepth}^\mathsf{Sapling}` and hashing function
@ -146,72 +146,72 @@ The signature is created as follows:
- Let :math:`path` be the Merkle path from position 0 to :math:`rt`. [#merkle-path]_
- Let :math:`cv = \mathsf{ValueCommit}_0(1)`.
- Let :math:`\mathsf{cv} = \mathsf{ValueCommit}_0(1)`.
- This is a constant and may be pre-computed.
- Let :math:`nf = \mathsf{PRF}^\mathsf{nfSapling}_{\mathsf{repr}_\mathbb{J}(nk)}(\mathsf{repr}_\mathbb{J}(\mathsf{MixingPedersenHash}(cm, 0)))`.
- Let :math:`nf = \mathsf{PRF}^\mathsf{nfSapling}_{\mathsf{repr}_\mathbb{J}(\mathsf{nk})}(\mathsf{repr}_\mathbb{J}(\mathsf{MixingPedersenHash}(\mathsf{cm}, 0)))`.
- Select a random :math:`α`.
- Let :math:`rk = \mathsf{SpendAuthSig.RandomizePublic}(α, ak)`.
- Let :math:`\mathsf{rk} = \mathsf{SpendAuthSig.RandomizePublic}(α, \mathsf{ak})`.
- Let :math:`zkproof` be a Sapling spend proof with primary input :math:`(rt, cv, nf, rk)`
and auxiliary input :math:`(path, 0, g_d, pk_d, 1, 0, cm, 0, α, ak, nsk)`.
- Let :math:`zkproof` be a Sapling spend proof with primary input :math:`(\mathsf{rt}, \mathsf{cv}, \mathsf{nf}, \mathsf{rk})`
and auxiliary input :math:`(path, 0, \mathsf{g_d}, \mathsf{pk_d}, 1, 0, \mathsf{cm}, 0, α, \mathsf{ak}, \mathsf{nsk})`.
[#spend-statement]_
- Let :math:`rsk = \mathsf{SpendAuthSig.RandomizePrivate}(α, ask)`.
- Let :math:`\mathsf{rsk} = \mathsf{SpendAuthSig.RandomizePrivate}(α, \mathsf{ask})`.
- Let :math:`coinType` be the 4-byte little-endian encoding of the coin type in its index
form, not its hardened form (i.e. 133 for mainnet Zcash).
- Let :math:`digest = \mathsf{BLAKE2b}\text{-}\mathsf{256}(\texttt{"ZIP304Signed"}\,||\,coinType, zkproof\,||\,msg)`.
- Let :math:`spendAuthSig = \mathsf{SpendAuthSig.Sign}(rsk, digest)`.
- Let :math:`spendAuthSig = \mathsf{SpendAuthSig.Sign}(\mathsf{rsk}, digest)`.
- Return :math:`(nf, rk, zkproof, spendAuthSig)`.
- Return :math:`(\mathsf{nf}, \mathsf{rk}, zkproof, spendAuthSig)`.
Verification algorithm
----------------------
The inputs to the verification algorithm are:
- The payment address :math:`(d, pk_d)`,
- The payment address :math:`(\mathsf{d}, \mathsf{pk_d})`,
- The SLIP-44 [#slip-0044]_ coin type,
- The message :math:`msg` that is claimed to be signed, and
- The ZIP 304 signature :math:`(nf, rk, zkproof, spendAuthSig)`.
- The ZIP 304 signature :math:`(\mathsf{nf}, \mathsf{rk}, zkproof, spendAuthSig)`.
The signature is verified as follows:
The signature MUST be verified as follows:
- Let :math:`coinType` be the 4-byte little-endian encoding of the coin type in its index
form, not its hardened form (i.e. 133 for mainnet Zcash).
- Let :math:`digest = \mathsf{BLAKE2b}\text{-}\mathsf{256}(\texttt{"ZIP304Signed"}\,||\,coinType, zkproof\,||\,msg)`.
- If :math:`\mathsf{SpendAuthSig.Verify}(rk, digest, spendAuthSig) = 0`, return false.
- If :math:`\mathsf{SpendAuthSig.Verify}(\mathsf{rk}, digest, spendAuthSig) = 0`, return false.
- Let :math:`cm = \mathsf{NoteCommit}^\mathsf{Sapling}_0(\mathsf{repr}_\mathbb{J}(\mathsf{DiversifyHash}(d)), \mathsf{repr}_\mathbb{J}(pk_d), 1)`.
- Let :math:`\mathsf{cm} = \mathsf{NoteCommit}^\mathsf{Sapling}_0(\mathsf{repr}_\mathbb{J}(\mathsf{DiversifyHash}(\mathsf{d})), \mathsf{repr}_\mathbb{J}(\mathsf{pk_d}), 1)`.
- Let :math:`rt` be the root of a Merkle tree with depth
- Let :math:`\mathsf{rt}` be the root of a Merkle tree with depth
:math:`\mathsf{MerkleDepth}^\mathsf{Sapling}` and hashing function
:math:`\mathsf{MerkleCRH}^\mathsf{Sapling}`, containing :math:`cm` at position 0, and
:math:`\mathsf{MerkleCRH}^\mathsf{Sapling}`, containing :math:`\mathsf{cm}` at position 0, and
:math:`\mathsf{Uncommitted}^\mathsf{Sapling}` at all other positions.
- Let :math:`path` be the Merkle path from position 0 to :math:`rt`. [#merkle-path]_
- Let :math:`path` be the Merkle path from position 0 to :math:`\mathsf{rt}`. [#merkle-path]_
- Let :math:`cv = \mathsf{ValueCommit}_0(1)`.
- Let :math:`\mathsf{cv} = \mathsf{ValueCommit}_0(1)`.
- This is a constant and may be pre-computed.
- Verify :math:`zkproof` as a Sapling spend proof with primary input
:math:`(rt, cv, nf, rk)`. [#spend-statement]_ If verification fails, return false.
:math:`(\mathsf{rt}, \mathsf{cv}, \mathsf{nf}, \mathsf{rk})`. [#spend-statement]_ If verification fails, return false.
- Return true.
Signature encoding
------------------
The raw form of a ZIP 304 signature is :math:`nf\,||\,rk\,||\,zkproof\,||\,spendAuthSig`, for a
The raw form of a ZIP 304 signature is :math:`\mathsf{nf}\,||\,\mathsf{rk}\,||\,zkproof\,||\,spendAuthSig`, for a
total size of 320 bytes.
When encoding a ZIP 304 signature in a human-readable format, implementations **SHOULD**
@ -228,13 +228,13 @@ and its parameters. It is possible to construct a signature scheme with a smalle
signature, but this would require a new circuit and another parameter-generation ceremony
(if Groth16 were used).
We use a note value of 1 zatoshi instead of zero to ensure that the payment address is
We use a note value of :math:`1` zatoshi instead of zero to ensure that the payment address is
fully bound to :math:`zkproof`. Notes with zero value have certain constraints disabled
inside the circuit.
We set :math:`rcm` and :math:`rcv` to zero because we do not need the hiding properties of
We set :math:`\mathsf{rcm}` and :math:`\mathsf{rcv}` to zero because we do not need the hiding properties of
the note commitment or value commitment schemes (as we are using a fixed-value fake note),
and can thus omit both :math:`rcm` and :math:`rcv` from the signature.
and can thus omit both :math:`\mathsf{rcm}` and :math:`\mathsf{rcv}` from the signature.
Security and Privacy Considerations
@ -251,8 +251,8 @@ different diversified addresses of the same spending key are unlinkable, as long
Most of the data within a ZIP 304 signature is inherently non-malleable:
- :math:`nullifier` is a binary public input to :math:`zkproof`.
- :math:`rk` is internally bound to :math:`spendAuthSig` by the design of RedJubjub.
- :math:`\mathsf{nf}` is a binary public input to :math:`zkproof`.
- :math:`\mathsf{rk}` is internally bound to :math:`spendAuthSig` by the design of RedJubjub.
- RedJubjub signatures are themselves non-malleable.
The one component that is inherently malleable is :math:`zkproof`. The zero-knowledge