diff --git a/.gitignore b/.gitignore index 58c8a585c..57bbccb2c 100644 --- a/.gitignore +++ b/.gitignore @@ -20,10 +20,13 @@ *.save *.save.* *~ +*.html.temp .Makefile.uptodate .zipfilelist.* .draftfilelist.* +MultiMarkdown-6 + protocol/aux/ protocol/protocol.ver diff --git a/Dockerfile b/Dockerfile index 48fd6085e..af77cee29 100644 --- a/Dockerfile +++ b/Dockerfile @@ -2,10 +2,10 @@ FROM debian:latest RUN apt-get update RUN apt-get install -y \ - gawk \ perl \ sed \ git \ + cmake \ python3 \ python3-pip \ pandoc \ @@ -18,7 +18,12 @@ RUN apt-get install -y \ texlive-bibtex-extra RUN rm /usr/lib/python3.11/EXTERNALLY-MANAGED -RUN pip install rst2html5 +RUN pip install 'docutils==0.21.2' 'rst2html5==2.0.1' + +RUN git config --global --add safe.directory /zips + +# Use a fork so that we're running pinned code. +RUN git clone -b develop https://github.com/Electric-Coin-Company/MultiMarkdown-6 && cd MultiMarkdown-6 && make release && cd build && make && make install ENV PATH=${PATH}:/root/.local/bin diff --git a/Makefile b/Makefile index 91414311a..a887b8087 100644 --- a/Makefile +++ b/Makefile @@ -1,4 +1,6 @@ -# Dependencies: see zip-guide.rst and protocol/README.rst +# Dependencies: see zips/zip-guide.rst and protocol/README.rst + +MARKDOWN_OPTION?=--mmd .PHONY: all-zips all tag-release protocol all-protocol discard all-zips: .Makefile.uptodate @@ -31,30 +33,18 @@ all-specs: all-zips discard: git checkout -- 'rendered/*.html' 'README.rst' 'rendered/protocol/*.pdf' -.Makefile.uptodate: Makefile edithtml.sh +.Makefile.uptodate: Makefile render.sh $(MAKE) clean touch .Makefile.uptodate -define PROCESSRST -$(eval TITLE := $(shell echo '$(patsubst zips/%,%,$(basename $<))' | sed -E 's|zip-0{0,3}|ZIP |;s|draft-|Draft |')$(shell grep -E '^(\.\.)?\s*Title: ' $< |sed -E 's|.*Title||')) -rst2html5 -v --title="$(TITLE)" $< >$@ -./edithtml.sh --rst $@ -endef - -define PROCESSMD -$(eval TITLE := $(shell echo '$(patsubst zips/%,%,$(basename $<))' | sed -E 's|zip-0{0,3}|ZIP |;s|draft-|Draft |')$(shell grep -E '^(\.\.)?\s*Title: ' $< |sed -E 's|.*Title||')) -pandoc --from=markdown --to=html $< --output=$@ -./edithtml.sh --md $@ "${TITLE}" -endef - -rendered/index.html: README.rst edithtml.sh - $(PROCESSRST) +rendered/index.html: README.rst render.sh + ./render.sh --rst $< $@ -rendered/%.html: zips/%.rst edithtml.sh - $(PROCESSRST) +rendered/%.html: zips/%.rst render.sh + ./render.sh --rst $< $@ -rendered/%.html: zips/%.md edithtml.sh - $(PROCESSMD) +rendered/%.html: zips/%.md render.sh + ./render.sh $(MARKDOWN_OPTION) $< $@ README.rst: .zipfilelist.current .draftfilelist.current makeindex.sh README.template $(wildcard zips/zip-*.rst) $(wildcard zips/zip-*.md) $(wildcard zips/draft-*.rst) $(wildcard zips/draft-*.md) ./makeindex.sh | cat README.template - >README.rst diff --git a/README.rst b/README.rst index ea74f770f..e9376841c 100644 --- a/README.rst +++ b/README.rst @@ -123,7 +123,7 @@ Released ZIPs 321 Payment Request URIs Proposed 401 Addressing Mempool Denial-of-Service Active 1014 Establishing a Dev Fund for ECC, ZF, and Major Grants Active - 1015 Block Reward Allocation for Non-Direct Development Funding Proposed + 1015 Block Subsidy Allocation for Non-Direct Development Funding Proposed 2001 Lockbox Funding Streams Implemented (zcashd and zebrad) @@ -342,7 +342,7 @@ Index of ZIPs 1012 Dev Fund to ECC + ZF + Major Grants Obsolete 1013 Keep It Simple, Zcashers: 10% to ECC, 10% to ZF Obsolete 1014 Establishing a Dev Fund for ECC, ZF, and Major Grants Active - 1015 Block Reward Allocation for Non-Direct Development Funding Proposed + 1015 Block Subsidy Allocation for Non-Direct Development Funding Proposed 2001 Lockbox Funding Streams Implemented (zcashd and zebrad) 2002 Explicit Fees Draft 2003 Disallow version 4 transactions Draft diff --git a/edithtml.sh b/edithtml.sh deleted file mode 100755 index 0cdead977..000000000 --- a/edithtml.sh +++ /dev/null @@ -1,49 +0,0 @@ -#!/bin/sh - -if ! ( ( [ "x$1" = "x--rst" ] && [ $# -eq 2 ] ) || ( [ "x$1" = "x--md" ] && [ $# -eq 3 ] ) ); then - echo "Usage: edithtml.sh --rst " - echo " or: edithtml.sh --md " - exit -fi - -if ! [ -f "$2" ]; then - echo File not found: "$2" - exit -fi - -if [ "x$1" = "x--rst" ]; then - sed -i.sedbak 's|</head>|<meta name="viewport" content="width=device-width, initial-scale=1"><link rel="stylesheet" href="css/style.css"></head>|' $2 - sed -i.sedbak 's|http://cdn.mathjax.org/mathjax/latest/MathJax.js|https://cdn.jsdelivr.net/npm/mathjax@3/es5/tex-mml-chtml.js|' $2 -else - cat - "$2" >"$2".prefix <<EOF -<!DOCTYPE html> -<html> -<head> - <title>$3 - - - - - -EOF - cat "$2.prefix" - >"$2" < - -EOF - rm -f "$2".prefix -fi - -sed -i.sedbak 's|Protocol Specification|Protocol Specification|g' "$2" -sed -i.sedbak 's|\s*(dark mode version)||g' "$2" - -sed -i.sedbak 's|||g' "$2" -sed -i.sedbak 's|||g' "$2" -sed -i.sedbak 's|<\(https:[^&]*\)>|\<\1\>|g' "$2" - -sed -i.sedbak 's|src="../rendered/|src="|g' "$2" -sed -i.sedbak 's|\s*.?\s*([^<]*(?:[^<]*[^<]*)?)|
\3 |g' "$2" - -rm -f rendered/*.sedbak diff --git a/protocol/README.rst b/protocol/README.rst index 96535392b..ae2f3c101 100644 --- a/protocol/README.rst +++ b/protocol/README.rst @@ -6,7 +6,7 @@ Build dependencies on Debian-based systems include, at least: .. code:: - apt install python3-pip pandoc perl sed perl \ + apt install python3-pip perl sed cmake \ texlive texlive-science texlive-fonts-extra texlive-bibtex-extra biber latexmk Prior to Bullseye you may also need the ``awk`` and ``texlive-generic-recommended`` @@ -16,7 +16,7 @@ For link checking, you will also need the following Python packages: .. code:: - pip3 install docutils==0.19 rst2html5 certifi PyPDF2 + pip3 install 'docutils==0.21.2' 'rst2html5==2.0.1' certifi PyPDF2 Building diff --git a/protocol/protocol.tex b/protocol/protocol.tex index 5f76e4b77..e719ee1ae 100644 --- a/protocol/protocol.tex +++ b/protocol/protocol.tex @@ -650,7 +650,11 @@ \newcommand{\labelcolor}{cream} \iftoggle{isnusix}{ - \providecommand{\baseurl}{https://zips.z.cash/protocol/protocol.pdf} + \iftoggle{darkmode}{ + \providecommand{\baseurl}{https://zips.z.cash/protocol/protocol-dark.pdf} + }{ + \providecommand{\baseurl}{https://zips.z.cash/protocol/protocol.pdf} + } \toggletrue{isnufive} \newcommand{\setnusix}{\color{\nusixcolor}} \newcommand{\nusix}[1]{\texorpdfstring{{\setnusix{#1}}}{#1}} diff --git a/protocol/zcash.bib b/protocol/zcash.bib index ec823e03d..da172b9ff 100644 --- a/protocol/zcash.bib +++ b/protocol/zcash.bib @@ -1519,7 +1519,7 @@ @misc{ZIP-1014 @misc{ZIP-1015, presort={ZIP-1015}, author={Jason McGee and @Peacemonger and Kris Nuttycombe}, - title={Block Reward Allocation for Non-Direct Development Funding}, + title={Block Subsidy Allocation for Non-Direct Development Funding}, howpublished={Zcash Improvement Proposal 1015. Created August~26, 2024.}, url={https://zips.z.cash/zip-1015}, urldate={2024-09-24} diff --git a/render.sh b/render.sh new file mode 100755 index 000000000..4fdbf2cbc --- /dev/null +++ b/render.sh @@ -0,0 +1,91 @@ +#!/bin/bash + +set -euo pipefail + +if ! ( ( [ "x$1" = "x--rst" ] || [ "x$1" = "x--pandoc" ] || [ "x$1" = "x--mmd" ] ) && [ $# -eq 3 ] ); then + cat - < + +--rst render reStructuredText using rst2html5 +--pandoc render Markdown using pandoc +--mmd render Markdown using multimarkdown +EndOfUsage + exit +fi + +inputfile="$2" +outputfile="$3" + +if ! [ -f "${inputfile}" ]; then + echo "File not found: ${inputfile}" + exit +fi + +if [ "x$1" = "x--rst" ]; then + filetype='.rst' +else + filetype='.md' +fi +title="$(basename -s ${filetype} ${inputfile} | sed -E 's|zip-0{0,3}|ZIP |; s|draft-|Draft |')$(grep -E '^(\.\.)?\s*Title: ' ${inputfile} |sed -E 's|.*Title||')" +echo " ${title}" + +Math1='<link rel="stylesheet" href="https://cdn.jsdelivr.net/npm/katex@0.16.11/dist/katex.min.css" integrity="sha384-nB0miv6/jRmo5UMMR1wu3Gz6NLsoTkbqJghGIsx//Rlm+ZU03BU6SQNC66uf4l5+" crossorigin="anonymous">' +Math2='<script defer src="https://cdn.jsdelivr.net/npm/katex@0.16.11/dist/katex.min.js" integrity="sha384-7zkQWkzuo3B5mTepMUcHkMB5jZaolc2xDwL6VFqjFALcbeS9Ggm/Yr2r3Dy4lfFg" crossorigin="anonymous"></script>' +Math3='<script defer src="https://cdn.jsdelivr.net/npm/katex@0.16.11/dist/contrib/auto-render.min.js" integrity="sha384-43gviWU0YVjaDtb/GhzOouOXtZMP/7XUzwPTstBeZFe/+rCMvRwr4yROQP43s0Xk" crossorigin="anonymous" onload="renderMathInElement(document.body);"></script>' +ViewAndStyle='<meta name="viewport" content="width=device-width, initial-scale=1"><link rel="stylesheet" href="css/style.css">' + +cat <( + if [ "x$1" = "x--rst" ]; then + # These are basic regexps so \+ is needed, not +. + # We use the Unicode 💲 character to move an escaped $ out of the way, + # which is much easier than trying to handle escapes within a capture. + + cat "${inputfile}" \ + | sed 's|[\][$]|💲|g; + s|[$]\([^$]\+\)[$]\([.,:;!?)-]\)|:math:`\1\\!`\2|g; + s|[$]\([^$]\+\)[$]|:math:`\1`|g; + s|💲|$|g' \ + | rst2html5 -v --title="${title}" - \ + | sed "s|<script src=\"http://cdn.mathjax.org/mathjax/latest/MathJax.js?config=TeX-AMS-MML_HTMLorMML\"></script>|${Math1}\n ${Math2}\n ${Math3}|; + s|</head>|${ViewAndStyle}</head>|" + else + if [ "x$1" = "x--pandoc" ]; then + # Not actually MathJax. KaTeX is compatible if we use the right headers. + pandoc --mathjax --from=markdown --to=html "${inputfile}" --output="${outputfile}.temp" + else + multimarkdown ${inputfile} -o "${outputfile}.temp" + fi + + # Both pandoc and multimarkdown just output the HTML body. + echo "<!DOCTYPE html>" + echo "<html>" + echo "<head>" + echo " <title>${title}" + echo " " + if grep -q -E 'class="math( inline)?"' "${outputfile}.temp"; then + echo " ${Math1}" + echo " ${Math2}" + echo " ${Math3}" + fi + echo " ${ViewAndStyle}" + echo "" + echo "" + cat "${outputfile}.temp" + rm -f "${outputfile}.temp" + echo "" + echo "" + fi +) \ +| sed \ +'s|Protocol Specification|Protocol Specification|g; + s|\s*(dark mode version)||g; + s|||g; + s|||g; + s|<\(https:[^&]*\)>|\<\1\>|g; + s|src="../rendered/|src="|g; + s|\s*.?\s*([^<]*(?:[^<]*[^<]*)?)|
\3 |g; + s|([^<]*(?:[^<]*[^<]*)?)|\3 |g;' \ +> "${outputfile}" diff --git a/rendered/css/style.css b/rendered/css/style.css index 9cf20f050..f1cd9577d 100644 --- a/rendered/css/style.css +++ b/rendered/css/style.css @@ -296,28 +296,18 @@ pre { font-size: 0.9375rem; } -span.math { - transform: scale(1, 1.03); - -moz-transform: scale(1, 1.03); - -ms-transform: scale(1, 1.03); - -webkit-transform: scale(1, 1.03); - -o-transform: scale(1, 1.03); - font-size: 0.97rem; +.katex { + font-size: 1.21em; } div.math { - transform: scale(1.3, 1.339); - -moz-transform: scale(1.3, 1.339); - -ms-transform: scale(1.3, 1.339); - -webkit-transform: scale(1.3, 1.339); - -o-transform: scale(1.3, 1.339); + transform: scale(1.42, 1.42); display: block; overflow-x: auto; overflow-y: hidden; margin: 2.6rem 1rem 2.6rem 1rem; text-align: center; padding: 0; - font-size: 0.97rem; } a, a:visited { @@ -344,12 +334,76 @@ span.section-heading:hover + span { opacity: 1; } -a.footnote_reference::before { +a.footnote_reference::before, a.footnote-ref::before, a.footnote::before { content: "["; } -a.footnote_reference::after { + +a.footnote_reference::after, a.footnote-ref::after, a.footnote::after { + content: "]"; +} + +/* {{{ rst-specific */ +#references table, #references th, #references td { + border: 0 none transparent; + font-size: 1.125rem; +} + +#references table { + margin-left: 0; + margin-bottom: 0; +} + +#references th { + padding-left: 0; + width: 1.9em; + text-align: right; +} + +#references th::before { + content: "["; +} + +#references th::after { content: "]"; } +/* }}} rst-specific */ + +/* {{{ md-specific */ +a.footnote-ref sup, a.footnote sup { + vertical-align: baseline; + font-size: 100%; +} + +/* pandoc only, not multimarkdown */ +#footnotes ol { + margin-top: -3ex; +} + +.footnotes li { + margin-top: -0.8ex; + margin-left: 1em; + list-style-type: md-references; +} + +.footnotes ::marker { + font-weight: 600; + font-size: 1.125rem; +} + +.footnotes hr { + display: none; +} + +.footnote-back::before { + content: " "; +} + +@counter-style md-references { + system: extends decimal; + prefix: "["; + suffix: "]     "; +} +/* }}} md-specific */ strong, b { font-family: 'robotomedium',Arial,Helvetica Neue,Helvetica,sans-serif; @@ -361,7 +415,6 @@ hr { margin: 1.875rem 0; } - table { border-collapse: collapse; border: 0 none transparent; @@ -399,22 +452,6 @@ td:first-child { padding-bottom: 0.4rem; } -#references table, #references th, #references td { - border: 0 none transparent; - font-size: 1.125rem; -} - -#references table { - margin-bottom: 0; -} - -#references th::before { - content: "["; -} -#references th::after { - content: "]"; -} - @media (max-width: 576px) { table:not(.footnote) { display: block; diff --git a/rendered/index.html b/rendered/index.html index 3c6e50835..f06b03aa4 100644 --- a/rendered/index.html +++ b/rendered/index.html @@ -88,7 +88,7 @@ 321 Payment Request URIs Proposed 401 Addressing Mempool Denial-of-Service Active 1014 Establishing a Dev Fund for ECC, ZF, and Major Grants Active - 1015 Block Reward Allocation for Non-Direct Development Funding Proposed + 1015 Block Subsidy Allocation for Non-Direct Development Funding Proposed 2001 Lockbox Funding Streams Implemented (zcashd and zebrad)

Draft ZIPs

@@ -278,7 +278,7 @@ 1012 Dev Fund to ECC + ZF + Major Grants Obsolete 1013 Keep It Simple, Zcashers: 10% to ECC, 10% to ZF Obsolete 1014 Establishing a Dev Fund for ECC, ZF, and Major Grants Active - 1015 Block Reward Allocation for Non-Direct Development Funding Proposed + 1015 Block Subsidy Allocation for Non-Direct Development Funding Proposed 2001 Lockbox Funding Streams Implemented (zcashd and zebrad) 2002 Explicit Fees Draft 2003 Disallow version 4 transactions Draft diff --git a/rendered/protocol/protocol-dark.pdf b/rendered/protocol/protocol-dark.pdf index fa1e45a63..980574e9b 100644 Binary files a/rendered/protocol/protocol-dark.pdf and b/rendered/protocol/protocol-dark.pdf differ diff --git a/rendered/protocol/protocol.pdf b/rendered/protocol/protocol.pdf index d9be9d18c..f2e608236 100644 Binary files a/rendered/protocol/protocol.pdf and b/rendered/protocol/protocol.pdf differ diff --git a/rendered/zip-0032.html b/rendered/zip-0032.html index 432702ad2..d4dd53635 100644 --- a/rendered/zip-0032.html +++ b/rendered/zip-0032.html @@ -3,7 +3,9 @@ ZIP 32: Shielded Hierarchical Deterministic Wallets - + + +
@@ -59,30 +61,30 @@ means the sequence formed from the first \(k\) elements of - \(S\) + \(S\!\) .
  • \(a\,||\,b\) means the concatenation of sequences \(a\) then - \(b\) + \(b\!\) .
  • \([k] P\) means scalar multiplication of the elliptic curve point \(P\) by the scalar - \(k\) + \(k\!\) .
  • \(\mathsf{LEOS2IP}_\ell(S)\) is the integer in range - \(\{ 0\,.\!. 2^\ell - 1 \}\) + \(\{ 0\,..\, 2^\ell - 1 \}\) represented in little-endian order by the byte sequence \(S\) of length - \(\ell/8\) + \(\ell/8\!\) .
  • \(\mathsf{I2LEBSP}_\ell(k)\) @@ -96,7 +98,7 @@ is defined as follows when \(\ell\) is a multiple of - \(8\) + \(8\!\) : convert each group of 8 bits in \(B\) to a byte value with the least significant bit first, and concatenate the resulting bytes in the same order as the groups.
  • @@ -108,22 +110,22 @@
  • \(\mathsf{BLAKE2b}\text{-}\mathsf{256}(p, x)\) refers to unkeyed BLAKE2b-256 in sequential mode, with an output digest length of 32 bytes, 16-byte personalization string - \(p\) + \(p\!\) , and input - \(x\) + \(x\!\) .
  • \(\mathsf{BLAKE2b}\text{-}\mathsf{512}(p, x)\) refers to unkeyed BLAKE2b-512 in sequential mode, with an output digest length of 64 bytes, 16-byte personalization string - \(p\) + \(p\!\) , and input - \(x\) + \(x\!\) .
  • \(\mathsf{PRF^{expand}}(\mathsf{sk}, t) :=\) - \(\mathsf{BLAKE2b}\text{-}\mathsf{512}(\texttt{“Zcash_ExpandSeed”},\) - \(\mathsf{sk}\,||\,t)\) -
  • + \(\mathsf{BLAKE2b}\text{-}\mathsf{512}(\texttt{“Zcash\_ExpandSeed”},\) + \(\mathsf{sk}\,||\,t)\!\) + .
  • \(r_\mathbb{J}\) is the order of the Jubjub large prime subgroup.
  • @@ -132,11 +134,11 @@ is the order of the Pallas curve.
  • \(\mathsf{ToScalar^{Sapling}}(x) :=\) - \(\mathsf{LEOS2IP}_{512}(x) \pmod{r_\mathbb{J}}\) + \(\mathsf{LEOS2IP}_{512}(x) \pmod{r_\mathbb{J}}\!\) .
  • \(\mathsf{ToScalar^{Orchard}}(x) :=\) - \(\mathsf{LEOS2IP}_{512}(x) \pmod{r_\mathbb{P}}\) + \(\mathsf{LEOS2IP}_{512}(x) \pmod{r_\mathbb{P}}\!\) .
  • \(\mathsf{DiversifyHash^{Sapling}}(d)\) @@ -151,15 +153,15 @@
  • \(\mathsf{FF1}\text{-}\mathsf{AES256.Encrypt}(key, tweak, x)\) refers to the FF1 encryption algorithm using AES with a 256-bit - \(key\) + \(key\!\) , and parameters \(radix = 2,\) \(minlen = 88,\) - \(maxlen = 88\) + \(maxlen = 88\!\) . It will be used only with the empty string \(\texttt{“”}\) as the - \(tweak\) + \(tweak\!\) . \(x\) is a sequence of 88 bits, as is the output.
  • @@ -175,22 +177,22 @@ representing in little-endian order the integer \(k\) in range - \(\{ 0\,.\!. 2^\ell - 1 \}\) + \(\{ 0\,..\, 2^\ell - 1 \}\!\) . It is the reverse operation of - \(\mathsf{LEOS2IP}_\ell(S)\) + \(\mathsf{LEOS2IP}_\ell(S)\!\) .

    Implementors should note that this ZIP is consistently little-endian (in keeping with the Sapling and Orchard specifications), which is the opposite of BIP 32.

    We adapt the path notation of BIP 32 2 to describe shielded HD paths, using prime marks ( - \('\) + \(\kern-0.1em{}'\!\) ) to indicate hardened derivation ( - \(i' = i + 2^{31}\) + \(\!i' = i + 2^{31}\!\) ) as in BIP 44 5:

    • \(\mathsf{CKDfvk}(\mathsf{CKDfvk}(\mathsf{CKDfvk}(m_\mathsf{Sapling}, a), b), c)\) is written as - \(m_\mathsf{Sapling} / a / b / c\) + \(m_\mathsf{Sapling} / a / b / c\!\) .
    @@ -202,7 +204,7 @@
  • We do not derive Sapling public keys directly, as this would prevent the use of diversified addresses. Instead, we derive Sapling full viewing keys, from which payment addresses can be generated. This maintains the trust semantics of BIP 32: someone with access to a BIP 32 extended public key is able to view all transactions involving that address, which a Sapling full viewing key also enables.
  • We represent a Sapling extended spending key as - \((\mathsf{ask, nsk, ovk, dk, c})\) + \((\mathsf{ask, nsk, ovk, dk, c})\!\) , where \((\mathsf{ask, nsk, ovk})\) is the normal Sapling expanded spending key, @@ -211,7 +213,7 @@ \(\mathsf{c}\) is the chain code.

    We represent a Sapling extended full viewing key as - \((\mathsf{ak, nk, ovk, dk, c})\) + \((\mathsf{ak, nk, ovk, dk, c})\!\) , where \((\mathsf{ak, nk, ovk})\) is the normal Sapling full viewing key, @@ -245,40 +247,40 @@ be a seed byte sequence of a chosen length, which MUST be at least 32 and at most 252 bytes.

    • Calculate - \(I = \mathsf{BLAKE2b}\text{-}\mathsf{512}(\texttt{“ZcashIP32Sapling”}, S)\) + \(I = \mathsf{BLAKE2b}\text{-}\mathsf{512}(\texttt{“ZcashIP32Sapling”}, S)\!\) .
    • Split \(I\) into two 32-byte sequences, \(I_L\) and - \(I_R\) + \(I_R\!\) .
    • Use \(I_L\) as the master spending key - \(\mathsf{sk}_m\) + \(\mathsf{sk}_m\!\) , and \(I_R\) as the master chain code - \(\mathsf{c}_m\) + \(\mathsf{c}_m\!\) .
    • Calculate - \(\mathsf{ask}_m\) + \(\mathsf{ask}_m\!\) , - \(\mathsf{nsk}_m\) + \(\mathsf{nsk}_m\!\) , and \(\mathsf{ovk}_m\) via the standard Sapling derivation 11:
      • - \(\mathsf{ask}_m = \mathsf{ToScalar^{Sapling}}(\mathsf{PRF^{expand}}(\mathsf{sk}_m, [\texttt{0x00}]))\) + \(\mathsf{ask}_m = \mathsf{ToScalar^{Sapling}}(\mathsf{PRF^{expand}}(\mathsf{sk}_m, [\mathtt{0x00}]))\)
      • - \(\mathsf{nsk}_m = \mathsf{ToScalar^{Sapling}}(\mathsf{PRF^{expand}}(\mathsf{sk}_m, [\texttt{0x01}]))\) + \(\mathsf{nsk}_m = \mathsf{ToScalar^{Sapling}}(\mathsf{PRF^{expand}}(\mathsf{sk}_m, [\mathtt{0x01}]))\)
      • - \(\mathsf{ovk}_m = \mathsf{truncate}_{32}(\mathsf{PRF^{expand}}(\mathsf{sk}_m, [\texttt{0x02}]))\) + \(\mathsf{ovk}_m = \mathsf{truncate}_{32}(\mathsf{PRF^{expand}}(\mathsf{sk}_m, [\mathtt{0x02}]))\!\) .
    • @@ -287,47 +289,47 @@ similarly:
      • - \(\mathsf{dk}_m = \mathsf{truncate}_{32}(\mathsf{PRF^{expand}}(\mathsf{sk}_m, [\texttt{0x10}]))\) + \(\mathsf{dk}_m = \mathsf{truncate}_{32}(\mathsf{PRF^{expand}}(\mathsf{sk}_m, [\mathtt{0x10}]))\!\) .
    • Return \((\mathsf{ask}_m, \mathsf{nsk}_m, \mathsf{ovk}_m, \mathsf{dk}_m, \mathsf{c}_m)\) as the master extended spending key - \(m_\mathsf{Sapling}\) + \(m_\mathsf{Sapling}\!\) .

    Note that the master extended key is invalid if \(\mathsf{ask}_m\) is - \(0\) + \(0\!\) , or if the corresponding \(\mathsf{ivk}\) derived as specified in 11 is - \(0\) + \(0\!\) .

    Sapling child key derivation

    As in BIP 32, the method for deriving a child extended key, given a parent extended key and an index - \(i\) + \(i\!\) , depends on the type of key being derived, and whether this is a hardened or non-hardened derivation.

    Deriving a child extended spending key

    \(\mathsf{CKDsk}((\mathsf{ask}_{par}, \mathsf{nsk}_{par}, \mathsf{ovk}_{par}, \mathsf{dk}_{par}, \mathsf{c}_{par}), i)\) \(\rightarrow (\mathsf{ask}_i, \mathsf{nsk}_i, \mathsf{ovk}_i, \mathsf{dk}_i, \mathsf{c}_i)\) -

    + :

    • Check whether \(i \geq 2^{31}\) (whether the child is a hardened key).
      • If so (hardened child): let - \(I = \mathsf{PRF^{expand}}(\mathsf{c}_{par}, [\texttt{0x11}]\) + \(I = \mathsf{PRF^{expand}}(\mathsf{c}_{par}, [\mathtt{0x11}]\) \(||\,\mathsf{EncodeExtSKParts}(\mathsf{ask}_{par}, \mathsf{nsk}_{par}, \mathsf{ovk}_{par}, \mathsf{dk}_{par})\) - \(||\,\mathsf{I2LEOSP}_{32}(i))\) + \(||\,\mathsf{I2LEOSP}_{32}(i))\!\) .
      • If not (normal child): let - \(I = \mathsf{PRF^{expand}}(\mathsf{c}_{par}, [\texttt{0x12}]\) + \(I = \mathsf{PRF^{expand}}(\mathsf{c}_{par}, [\mathtt{0x12}]\) \(||\,\mathsf{EncodeExtFVKParts}(\mathsf{ak}_{par}, \mathsf{nk}_{par}, \mathsf{ovk}_{par}, \mathsf{dk}_{par})\) \(||\,\mathsf{I2LEOSP}_{32}(i))\) where @@ -342,13 +344,13 @@ into two 32-byte sequences, \(I_L\) and - \(I_R\) + \(I_R\!\) .
      • Let - \(I_\mathsf{ask} = \mathsf{ToScalar^{Sapling}}(\mathsf{PRF^{expand}}(I_L, [\texttt{0x13}]))\) + \(I_\mathsf{ask} = \mathsf{ToScalar^{Sapling}}(\mathsf{PRF^{expand}}(I_L, [\mathtt{0x13}]))\!\) .
      • Let - \(I_\mathsf{nsk} = \mathsf{ToScalar^{Sapling}}(\mathsf{PRF^{expand}}(I_L, [\texttt{0x14}]))\) + \(I_\mathsf{nsk} = \mathsf{ToScalar^{Sapling}}(\mathsf{PRF^{expand}}(I_L, [\mathtt{0x14}]))\!\) .
      • Return:
          @@ -359,15 +361,15 @@ \(\mathsf{nsk}_i = (I_\mathsf{nsk} + \mathsf{nsk}_{par}) \pmod{r_\mathbb{J}}\)
        • - \(\mathsf{ovk}_i = \mathsf{truncate}_{32}(\mathsf{PRF^{expand}}(I_L, [\texttt{0x15}]\) + \(\mathsf{ovk}_i = \mathsf{truncate}_{32}(\mathsf{PRF^{expand}}(I_L, [\mathtt{0x15}]\) \(||\,\mathsf{ovk}_{par}))\)
        • - \(\mathsf{dk}_i = \mathsf{truncate}_{32}(\mathsf{PRF^{expand}}(I_L, [\texttt{0x16}]\) + \(\mathsf{dk}_i = \mathsf{truncate}_{32}(\mathsf{PRF^{expand}}(I_L, [\mathtt{0x16}]\) \(||\,\mathsf{dk}_{par}))\)
        • - \(\mathsf{c}_i = I_R\) + \(\mathsf{c}_i = I_R\!\) .
      • @@ -375,11 +377,11 @@

        Note that the child extended key is invalid if \(\mathsf{ask}_i\) is - \(0\) + \(0\!\) , or if the corresponding \(\mathsf{ivk}\) derived as specified in 11 is - \(0\) + \(0\!\) .

    Deriving a child extended full viewing key

    @@ -391,7 +393,7 @@

    \(\mathsf{CKDfvk}((\mathsf{ak}_{par}, \mathsf{nk}_{par}, \mathsf{ovk}_{par}, \mathsf{dk}_{par}, \mathsf{c}_{par}), i)\) \(\rightarrow (\mathsf{ak}_{i}, \mathsf{nk}_{i}, \mathsf{ovk}_{i}, \mathsf{dk}_{i}, \mathsf{c}_{i})\) -

    + :

    • Check whether \(i \geq 2^{31}\) @@ -399,9 +401,9 @@
      • If so (hardened child): return failure.
      • If not (normal child): let - \(I = \mathsf{PRF^{expand}}(\mathsf{c}_{par}, [\texttt{0x12}]\) + \(I = \mathsf{PRF^{expand}}(\mathsf{c}_{par}, [\mathtt{0x12}]\) \(||\,\mathsf{EncodeExtFVKParts}(\mathsf{ak}_{par}, \mathsf{nk}_{par}, \mathsf{ovk}_{par}, \mathsf{dk}_{par})\) - \(||\,\mathsf{I2LEOSP}_{32}(i))\) + \(||\,\mathsf{I2LEOSP}_{32}(i))\!\) .
    • @@ -410,13 +412,13 @@ into two 32-byte sequences, \(I_L\) and - \(I_R\) + \(I_R\!\) .
    • Let - \(I_\mathsf{ask} = \mathsf{ToScalar^{Sapling}}(\mathsf{PRF^{expand}}(I_L, [\texttt{0x13}]))\) + \(I_\mathsf{ask} = \mathsf{ToScalar^{Sapling}}(\mathsf{PRF^{expand}}(I_L, [\mathtt{0x13}]))\!\) .
    • Let - \(I_\mathsf{nsk} = \mathsf{ToScalar^{Sapling}}(\mathsf{PRF^{expand}}(I_L, [\texttt{0x14}]))\) + \(I_\mathsf{nsk} = \mathsf{ToScalar^{Sapling}}(\mathsf{PRF^{expand}}(I_L, [\mathtt{0x14}]))\!\) .
    • Return:
        @@ -427,15 +429,15 @@ \(\mathsf{nk}_i = [I_\mathsf{nsk}]\,\mathcal{H}^\mathsf{Sapling} + \mathsf{nk}_{par}\)
      • - \(\mathsf{ovk}_i = \mathsf{truncate}_{32}(\mathsf{PRF^{expand}}(I_L, [\texttt{0x15}]\) + \(\mathsf{ovk}_i = \mathsf{truncate}_{32}(\mathsf{PRF^{expand}}(I_L, [\mathtt{0x15}]\) \(||\,\mathsf{ovk}_{par}))\)
      • - \(\mathsf{dk}_i = \mathsf{truncate}_{32}(\mathsf{PRF^{expand}}(I_L, [\texttt{0x16}]\) + \(\mathsf{dk}_i = \mathsf{truncate}_{32}(\mathsf{PRF^{expand}}(I_L, [\mathtt{0x16}]\) \(||\,\mathsf{dk}_{par}))\)
      • - \(\mathsf{c}_i = I_R\) + \(\mathsf{c}_i = I_R\!\) .
    • @@ -445,7 +447,7 @@ is the zero point of Jubjub, or if the corresponding \(\mathsf{ivk}\) derived as specified in 11 is - \(0\) + \(0\!\) .

    @@ -462,26 +464,26 @@ \(\mathsf{nk}\) as specified in 11.
  • Let - \(I = \textsf{BLAKE2b-256}(\texttt{"Zcash_SaplingInt"}, \mathsf{EncodeExtFVKParts}(\mathsf{ak}, \mathsf{nk}, \mathsf{ovk}, \mathsf{dk}))\) + \(I = \textsf{BLAKE2b-256}(\texttt{“Zcash\_SaplingInt”}, \mathsf{EncodeExtFVKParts}(\mathsf{ak}, \mathsf{nk}, \mathsf{ovk}, \mathsf{dk}))\!\) .
  • Let - \(I_\mathsf{nsk} = \mathsf{ToScalar^{Sapling}}(\mathsf{PRF^{expand}}(I, [\mathtt{0x17}]))\) + \(I_\mathsf{nsk} = \mathsf{ToScalar^{Sapling}}(\mathsf{PRF^{expand}}(I, [\mathtt{0x17}]))\!\) .
  • Let - \(R = \mathsf{PRF^{expand}}(I, [\mathtt{0x18}])\) + \(R = \mathsf{PRF^{expand}}(I, [\mathtt{0x18}])\!\) .
  • Let - \(\mathsf{nsk_{internal}} = (I_\mathsf{nsk} + \mathsf{nsk}) \pmod{r_\mathbb{J}}\) + \(\mathsf{nsk_{internal}} = (I_\mathsf{nsk} + \mathsf{nsk}) \pmod{r_\mathbb{J}}\!\) .
  • Split \(R\) into two 32-byte sequences, \(\mathsf{dk_{internal}}\) and - \(\mathsf{ovk_{internal}}\) + \(\mathsf{ovk_{internal}}\!\) .
  • Return the internal spending key as - \((\mathsf{ask}, \mathsf{nsk_{internal}}, \mathsf{ovk_{internal}}, \mathsf{dk_{internal}})\) + \((\mathsf{ask}, \mathsf{nsk_{internal}}, \mathsf{ovk_{internal}}, \mathsf{dk_{internal}})\!\) .
  • Note that the child extended key is invalid if @@ -489,7 +491,7 @@ is the zero point of Jubjub, or if the corresponding \(\mathsf{ivk}\) derived as specified in 11 is - \(0\) + \(0\!\) .

    Deriving a Sapling internal full viewing key

    @@ -501,35 +503,35 @@ be the external full viewing key.

    • Let - \(I = \textsf{BLAKE2b-256}(\texttt{"Zcash_SaplingInt"}, \mathsf{EncodeExtFVKParts}(\mathsf{ak}, \mathsf{nk}, \mathsf{ovk}, \mathsf{dk}))\) + \(I = \textsf{BLAKE2b-256}(\texttt{“Zcash\_SaplingInt”}, \mathsf{EncodeExtFVKParts}(\mathsf{ak}, \mathsf{nk}, \mathsf{ovk}, \mathsf{dk}))\!\) .
    • Let - \(I_\mathsf{nsk} = \mathsf{ToScalar^{Sapling}}(\mathsf{PRF^{expand}}(I, [\mathtt{0x17}]))\) + \(I_\mathsf{nsk} = \mathsf{ToScalar^{Sapling}}(\mathsf{PRF^{expand}}(I, [\mathtt{0x17}]))\!\) .
    • Let - \(R = \mathsf{PRF^{expand}}(I, [\mathtt{0x18}])\) + \(R = \mathsf{PRF^{expand}}(I, [\mathtt{0x18}])\!\) .
    • Let - \(\mathsf{nk_{internal}} = [I_\mathsf{nsk}] \mathcal{H}^\mathsf{Sapling} + \mathsf{nk}\) + \(\mathsf{nk_{internal}} = [I_\mathsf{nsk}] \mathcal{H}^\mathsf{Sapling} + \mathsf{nk}\!\) .
    • Split \(R\) into two 32-byte sequences, \(\mathsf{dk_{internal}}\) and - \(\mathsf{ovk_{internal}}\) + \(\mathsf{ovk_{internal}}\!\) .
    • Return the internal full viewing key as - \((\mathsf{ak}, \mathsf{nk_{internal}}, \mathsf{ovk_{internal}}, \mathsf{dk_{internal}})\) + \((\mathsf{ak}, \mathsf{nk_{internal}}, \mathsf{ovk_{internal}}, \mathsf{dk_{internal}})\!\) .

    This design uses the same technique as non-hardened derivation to obtain a full viewing key with the same spend authority (the private key corresponding to - \(\mathsf{ak}\) + \(\mathsf{ak}\!\) ) as the original, but viewing authority only for internal transfers.

    The values of - \(I\) + \(I\!\) , - \(I_\mathsf{nsk}\) + \(I_\mathsf{nsk}\!\) , and \(R\) are the same between deriving a full viewing key, and deriving the corresponding spending key. Both of these derivations are shown in the following diagram:

    @@ -544,35 +546,35 @@ is the zero point of Jubjub, or if the corresponding \(\mathsf{ivk_{internal}}\) derived from the internal full viewing key as specified in 11 is - \(0\) + \(0\!\) .

    Sapling diversifier derivation

    The 88-bit diversifiers for a Sapling extended key are derived from its diversifier key - \(\mathsf{dk}\) + \(\mathsf{dk}\!\) . To prevent the diversifier leaking how many diversified addresses have already been generated for an account, we make the sequence of diversifiers pseudorandom and uncorrelated to that of any other account. In order to reach the maximum possible diversifier range without running into repetitions due to the birthday bound, we use FF1-AES256 as a Pseudo-Random Permutation as follows:

    • Let \(j\) be the index of the desired diversifier, in the range - \(0\,.\!. 2^{88} - 1\) + \(0\,..\, 2^{88} - 1\!\) .
    • - \(d_j = \mathsf{FF1}\text{-}\mathsf{AES256.Encrypt}(\mathsf{dk}, \texttt{“”}, \mathsf{I2LEBSP}_{88}(j))\) + \(d_j = \mathsf{FF1}\text{-}\mathsf{AES256.Encrypt}(\mathsf{dk}, \texttt{“”}, \mathsf{I2LEBSP}_{88}(j))\!\) .

    A valid diversifier \(d_j\) is one for which - \(\mathsf{DiversifyHash^{Sapling}}(d_j) \neq \bot\) + \(\mathsf{DiversifyHash^{Sapling}}(d_j) \neq \bot\!\) . For a given - \(\mathsf{dk}\) + \(\mathsf{dk}\!\) , approximately half of the possible values of \(j\) yield valid diversifiers.

    The default diversifier for a Sapling extended key is defined to be - \(d_j\) + \(d_j\!\) , where \(j\) is the least nonnegative integer yielding a valid diversifier.

    @@ -591,7 +593,7 @@
  • \(\mathsf{Context.CKDDomain}\) is a byte value, used as a domain separator during child key derivation. This should be tracked as part of the global set of domains defined for - \(\mathsf{PRF^{expand}}\) + \(\mathsf{PRF^{expand}}\!\) .
  • @@ -601,30 +603,30 @@ be an input key material byte sequence, which MUST use an unambiguous encoding within the given context, and SHOULD contain at least 256 bits of entropy. It is RECOMMENDED to use a prefix-free encoding, which may require the use of length fields if multiple fields need to be encoded.

    \(\mathsf{MKGh}^\mathsf{Context}(\mathsf{IKM}) \rightarrow (\mathsf{sk}_m, \mathsf{c}_m)\) -

    + :

    • Calculate - \(I = \mathsf{BLAKE2b}\text{-}\mathsf{512}(\mathsf{Context.MKGDomain}, \mathsf{IKM})\) + \(I = \mathsf{BLAKE2b}\text{-}\mathsf{512}(\mathsf{Context.MKGDomain}, \mathsf{IKM})\!\) .
    • Split \(I\) into two 32-byte sequences, \(I_L\) and - \(I_R\) + \(I_R\!\) .
    • Use \(I_L\) as the master secret key - \(\mathsf{sk}_m\) + \(\mathsf{sk}_m\!\) .
    • Use \(I_R\) as the master chain code - \(\mathsf{c}_m\) + \(\mathsf{c}_m\!\) .
    • Return - \((\mathsf{sk}_m, \mathsf{c}_m)\) + \((\mathsf{sk}_m, \mathsf{c}_m)\!\) .
    @@ -632,14 +634,14 @@

    \(\mathsf{CKDh}^\mathsf{Context}((\mathsf{sk}_{par}, \mathsf{c}_{par}), i)\) \(\rightarrow (\mathsf{sk}_i, \mathsf{c}_i)\) -

    + :

    • Check whether \(i \geq 2^{31}\) (whether the child is a hardened key).
      • If so (hardened child): let - \(I = \mathsf{PRF^{expand}}(\mathsf{c}_{par}, [\mathsf{Context.CKDDomain}]\,||\,\mathsf{sk}_{par}\,||\,\mathsf{I2LEOSP}_{32}(i))\) + \(I = \mathsf{PRF^{expand}}(\mathsf{c}_{par}, [\mathsf{Context.CKDDomain}]\,||\,\mathsf{sk}_{par}\,||\,\mathsf{I2LEOSP}_{32}(i))\!\) .
      • If not (normal child): return failure.
      @@ -649,20 +651,20 @@ into two 32-byte sequences, \(I_L\) and - \(I_R\) + \(I_R\!\) .
    • Use \(I_L\) as the child secret key - \(\mathsf{sk}_i\) + \(\mathsf{sk}_i\!\) .
    • Use \(I_R\) as the child chain code - \(\mathsf{c}_i\) + \(\mathsf{c}_i\!\) .
    • Return - \((\mathsf{sk}_i, \mathsf{c}_i)\) + \((\mathsf{sk}_i, \mathsf{c}_i)\!\) .
    @@ -674,7 +676,7 @@ \(\mathsf{Orchard.MKGDomain} = \texttt{“ZcashIP32Orchard”}\)
  • - \(\mathsf{Orchard.CKDDomain} = \texttt{0x81}\) + \(\mathsf{Orchard.CKDDomain} = \mathtt{0x81}\)
  • Orchard extended keys

    @@ -694,7 +696,7 @@
  • Return \(\mathsf{MKGh}^\mathsf{Orchard}(S)\) as the master extended spending key - \(m_\mathsf{Orchard}\) + \(m_\mathsf{Orchard}\!\) .
  • @@ -702,7 +704,7 @@

    \(\mathsf{CKDsk}((\mathsf{sk}_{par}, \mathsf{c}_{par}), i)\) \(\rightarrow (\mathsf{sk}_{i}, \mathsf{c}_i)\) -

    + :

    • Return \(\mathsf{CKDh}^\mathsf{Orchard}((\mathsf{sk}_{par}, \mathsf{c}_{par}), i)\) @@ -722,24 +724,24 @@ as follows:

      • Let - \(K = \mathsf{I2LEBSP}_{256}(\mathsf{rivk})\) + \(K = \mathsf{I2LEBSP}_{256}(\mathsf{rivk})\!\) .
      • Let - \(\mathsf{rivk_{internal}} = \mathsf{ToScalar^{Orchard}}(\mathsf{PRF^{expand}}(K, [\mathtt{0x83}] \,||\, \mathsf{I2LEOSP_{256}}(\mathsf{ak}) \,||\, \mathsf{I2LEOSP_{256}}(\mathsf{nk}))\) + \(\mathsf{rivk_{internal}} = \mathsf{ToScalar^{Orchard}}(\mathsf{PRF^{expand}}(K, [\mathtt{0x83}] \,||\, \mathsf{I2LEOSP_{256}}(\mathsf{ak}) \,||\, \mathsf{I2LEOSP_{256}}(\mathsf{nk}))\!\) .
      • Return - \((\mathsf{ak}, \mathsf{nk}, \mathsf{rivk_{internal}})\) + \((\mathsf{ak}, \mathsf{nk}, \mathsf{rivk_{internal}})\!\) .

      The result of applying \(\mathsf{DeriveInternalFVK^{Orchard}}\) to the external full viewing key is the internal full viewing key. The corresponding expanded internal spending key is - \((\mathsf{ask}, \mathsf{nk}, \mathsf{rivk_{internal}})\) - ,

      + \((\mathsf{ask}, \mathsf{nk}, \mathsf{rivk_{internal}})\!\) + .

      Unlike Sapling internal key derivation, we do not base this internal key derivation procedure on non-hardened derivation, which is not defined for Orchard. We can obtain the desired separation of viewing authority by modifying only the \(\mathsf{rivk_{internal}}\) field relative to the external full viewing key, which results in different - \(\mathsf{dk_{internal}}\) + \(\mathsf{dk_{internal}}\!\) , \(\mathsf{ivk_{internal}}\) and @@ -755,27 +757,27 @@

      Orchard diversifier derivation

      As with Sapling, we define a mechanism for deterministically deriving a sequence of diversifiers, without leaking how many diversified addresses have already been generated for an account. Unlike Sapling, we do so by deriving a diversifier key directly from the full viewing key, instead of as part of the extended spending key. This means that the full viewing key provides the capability to determine the position of a diversifier within the sequence, which matches the capabilities of a Sapling extended full viewing key but simplifies the key structure.

      Given an Orchard extended spending key - \((\mathsf{sk}_i, \mathsf{c}_i)\) + \((\mathsf{sk}_i, \mathsf{c}_i)\!\) :

      • Let \((\mathsf{ak}, \mathsf{nk}, \mathsf{rivk})\) be the Orchard full viewing key for - \(\mathsf{sk}_i\) + \(\mathsf{sk}_i\!\) .
      • Let - \(K = \mathsf{I2LEBSP}_{256}(\mathsf{rivk})\) + \(K = \mathsf{I2LEBSP}_{256}(\mathsf{rivk})\!\) .
      • - \(\mathsf{dk}_i = \mathsf{truncate}_{32}(\mathsf{PRF^{expand}}(K, [\texttt{0x82}] \,||\, \mathsf{I2LEOSP}_{256}(\mathsf{ak}) \,||\, \mathsf{I2LEOSP}_{256}(\mathsf{nk})))\) + \(\mathsf{dk}_i = \mathsf{truncate}_{32}(\mathsf{PRF^{expand}}(K, [\mathtt{0x82}] \,||\, \mathsf{I2LEOSP}_{256}(\mathsf{ak}) \,||\, \mathsf{I2LEOSP}_{256}(\mathsf{nk})))\!\) .
      • Let \(j\) be the index of the desired diversifier, in the range - \(0\,.\!. 2^{88} - 1\) + \(0\,..\, 2^{88} - 1\!\) .
      • - \(d_{i,j} = \mathsf{FF1}\text{-}\mathsf{AES256.Encrypt}(\mathsf{dk}_i, \texttt{“”}, \mathsf{I2LEBSP}_{88}(j))\) + \(d_{i,j} = \mathsf{FF1}\text{-}\mathsf{AES256.Encrypt}(\mathsf{dk}_i, \texttt{“”}, \mathsf{I2LEBSP}_{88}(j))\!\) .

      Note that unlike Sapling, all Orchard diversifiers are valid, and thus all possible values of @@ -799,7 +801,7 @@ \(\mathsf{Arbitrary.MKGDomain} = \texttt{“ZcashArbitraryKD”}\)

    • - \(\mathsf{Arbitrary.CKDDomain} = \texttt{0xAB}\) + \(\mathsf{Arbitrary.CKDDomain} = \mathtt{0xAB}\)

    Arbitrary master key generation

    @@ -815,7 +817,7 @@

    \(\mathsf{CKDarb}((\mathsf{sk}_{par}, \mathsf{c}_{par}), i)\) \(\rightarrow (\mathsf{sk}_i, \mathsf{c}_i)\) -

    + :

    • Return \(\mathsf{CKDh}^\mathsf{Arbitrary}((\mathsf{sk}_{par}, \mathsf{c}_{par}), i)\!\) @@ -840,21 +842,21 @@

      Sapling and Orchard key paths have the following three path levels at the top, all of which use hardened derivation:

      • - \(purpose\) + \(purpose\!\) : a constant set to \(32'\) (or - \(\texttt{0x80000020}\) + \(\mathtt{0x80000020}\!\) ) following the BIP 43 recommendation. It indicates that the subtree of this node is used according to this specification.
      • - \(coin\_type\) + \(coin\_type\!\) : a constant identifying the cryptocurrency that this subtree's keys are used with. For compatibility with existing BIP 44 implementations, we use the same constants as defined in SLIP 44 6. Note that in keeping with that document, all cryptocurrency testnets share \(coin\_type\) index - \(1\) + \(1\!\) .
      • - \(account\) + \(account\!\) : numbered from index \(0\) in sequentially increasing manner. Defined as in BIP 44 5.
      • @@ -866,11 +868,11 @@

        Sapling key path

        Sapling provides a mechanism to allow the efficient creation of diversified payment addresses with the same spending authority. A group of such addresses shares the same full viewing key and incoming viewing key, and so creating as many unlinkable addresses as needed does not increase the cost of scanning the block chain for relevant transactions.

        The above key path levels include an account identifier, which in all user interfaces is represented as a "bucket of funds" under the control of a single spending authority. Therefore, wallets implementing Sapling ZIP 32 derivation MUST support the following path for any account in range - \(\{ 0\,.\!. 2^{31} - 1 \}\) + \(\{ 0\,..\, 2^{31} - 1 \}\!\) :

        • - \(m_\mathsf{Sapling} / purpose' / coin\_type' / account'\) + \(m_\mathsf{Sapling} / purpose' / coin\_type' / account'\!\) .

        Furthermore, wallets MUST support generating the default payment address (corresponding to the default diversifier as defined above) for any account they support. They MAY also support generating a stream of payment addresses for a given account, if they wish to maintain the user experience of giving a unique address to each recipient.

        @@ -882,23 +884,23 @@ path level as in 5:

        • - \(m_\mathsf{Sapling} / purpose' / coin\_type' / account' / address\_index\) + \(m_\mathsf{Sapling} / purpose' / coin\_type' / account' / address\_index\!\) .

        zcashd version 4.6.0 and later uses this to derive "legacy" Sapling addresses from a mnemonic seed phrase under account - \(\mathtt{0x7FFFFFFF}\) + \(\mathtt{0x7FFFFFFF}\!\) , using hardened derivation for - \(address\_index\) + \(address\_index\!\) .

        Orchard key path

        Orchard supports diversified addresses with the same spending authority (like Sapling). A group of such addresses shares the same full viewing key and incoming viewing key, and so creating as many unlinkable addresses as needed does not increase the cost of scanning the block chain for relevant transactions.

        The above key path levels include an account identifier, which in all user interfaces is represented as a "bucket of funds" under the control of a single spending authority. Therefore, wallets implementing Orchard ZIP 32 derivation MUST support the following path for any account in range - \(\{ 0\,.\!. 2^{31} - 1 \}\) + \(\{ 0\,..\, 2^{31} - 1 \}\!\) :

        • - \(m_\mathsf{Orchard} / purpose' / coin\_type' / account'\) + \(m_\mathsf{Orchard} / purpose' / coin\_type' / account'\!\) .

        Furthermore, wallets MUST support generating the default payment address (corresponding to the default diversifier for Orchard) for any account they support. They MAY also support generating a stream of diversified payment addresses for a given account, if they wish to enable users to give a unique address to each recipient.

        @@ -914,7 +916,7 @@ (as specified in 18) is given by:

        • - \(\mathsf{BLAKE2b}\text{-}\mathsf{256}(\texttt{“ZcashSaplingFVFP”}, \mathit{FVK})\) + \(\mathsf{BLAKE2b}\text{-}\mathsf{256}(\texttt{“ZcashSaplingFVFP”}, \mathit{FVK})\!\) .

        It MAY be used to uniquely identify a particular Sapling full viewing key.

        @@ -926,7 +928,7 @@ (as specified in 20) is given by:

        • - \(\mathsf{BLAKE2b}\text{-}\mathsf{256}(\texttt{“ZcashOrchardFVFP”}, \mathit{FVK})\) + \(\mathsf{BLAKE2b}\text{-}\mathsf{256}(\texttt{“ZcashOrchardFVFP”}, \mathit{FVK})\!\) .

        It MAY be used to uniquely identify a particular Orchard full viewing key.

        @@ -938,8 +940,8 @@ of a hierarchical deterministic wallet is given by:

        • - \(\mathsf{BLAKE2b}\text{-}\mathsf{256}(\texttt{“Zcash_HD_Seed_FP”},\) - \([\mathsf{length}(S)]\,||\,S)\) + \(\mathsf{BLAKE2b}\text{-}\mathsf{256}(\texttt{“Zcash\_HD\_Seed\_FP”},\) + \([\mathsf{length}(S)]\,||\,S)\!\) .

        It MAY be used to uniquely identify a particular hierarchical deterministic wallet.

        @@ -951,13 +953,13 @@

        The following encodings are analogous to the xprv and xpub encodings defined in BIP 32 for transparent keys and addresses. Each key type has a raw representation and a Bech32 7 encoding.

        Sapling extended spending keys

        A Sapling extended spending key - \((\mathsf{ask, nsk, ovk, dk, c})\) + \((\mathsf{ask, nsk, ovk, dk, c})\!\) , at depth - \(depth\) + \(depth\!\) , with parent full viewing key tag \(parent\_fvk\_tag\) and child number - \(i\) + \(i\!\) , is represented as a byte sequence:

        • @@ -965,31 +967,31 @@ \(||\,parent\_fvk\_tag\) \(||\,\mathsf{I2LEOSP}_{32}(i)\) \(||\,\mathsf{c}\) - \(||\,\mathsf{EncodeExtSKParts}(\mathsf{ask, nsk, ovk, dk})\) + \(||\,\mathsf{EncodeExtSKParts}(\mathsf{ask, nsk, ovk, dk})\!\) .

        For the master extended spending key, \(depth\) is - \(0\) + \(0\!\) , \(parent\_fvk\_tag\) is 4 zero bytes, and \(i\) is - \(0\) + \(0\!\) .

        When encoded as Bech32, the Human-Readable Part is secret-extended-key-main for the production network, or secret-extended-key-test for the test network.

        Sapling extended full viewing keys

        A Sapling extended full viewing key - \((\mathsf{ak, nk, ovk, dk, c})\) + \((\mathsf{ak, nk, ovk, dk, c})\!\) , at depth - \(depth\) + \(depth\!\) , with parent full viewing key tag \(parent\_fvk\_tag\) and child number - \(i\) + \(i\!\) , is represented as a byte sequence:

        • @@ -997,47 +999,47 @@ \(||\,parent\_fvk\_tag\) \(||\,\mathsf{I2LEOSP}_{32}(i)\) \(||\,\mathsf{c}\) - \(||\,\mathsf{EncodeExtFVKParts}(\mathsf{ak, nk, ovk, dk})\) + \(||\,\mathsf{EncodeExtFVKParts}(\mathsf{ak, nk, ovk, dk})\!\) .

        For the master extended full viewing key, \(depth\) is - \(0\) + \(0\!\) , \(parent\_fvk\_tag\) is 4 zero bytes, and \(i\) is - \(0\) + \(0\!\) .

        When encoded as Bech32, the Human-Readable Part is zxviews for the production network, or zxviewtestsapling for the test network.

        Orchard extended spending keys

        An Orchard extended spending key - \((\mathsf{sk, c})\) + \((\mathsf{sk, c})\!\) , at depth - \(depth\) + \(depth\!\) , with parent full viewing key tag \(parent\_fvk\_tag\) and child number - \(i\) + \(i\!\) , is represented as a byte sequence:

        • - \(\mathsf{I2LEOSP}_{8}(depth)\,||\,parent\_fvk\_tag\,||\,\mathsf{I2LEOSP}_{32}(i)\,||\,\mathsf{c}\,||\,\mathsf{sk}\) + \(\mathsf{I2LEOSP}_{8}(depth)\,||\,parent\_fvk\_tag\,||\,\mathsf{I2LEOSP}_{32}(i)\,||\,\mathsf{c}\,||\,\mathsf{sk}\!\) .

        For the master extended spending key, \(depth\) is - \(0\) + \(0\!\) , \(parent\_fvk\_tag\) is 4 zero bytes, and \(i\) is - \(0\) + \(0\!\) .

        When encoded as Bech32, the Human-Readable Part is secret-orchard-extsk-main for Mainnet, or secret-orchard-extsk-test for Testnet.

        We define this encoding for completeness, however given that it includes the capability to derive child spending keys, we expect that most wallets will only expose the regular Orchard spending key encoding to users 21.

        @@ -1049,17 +1051,17 @@
      • the \(\mathsf{BLAKE2b}\text{-}\mathsf{512}\) personalization - \(\texttt{“ZcashIP32_Sprout”}\) + \(\texttt{“ZcashIP32\_Sprout”}\!\) , formerly specified for derivation of the master key of the Sprout tree;
      • the \(\mathsf{BLAKE2b}\text{-}\mathsf{256}\) personalization - \(\texttt{“Zcash_Sprout_AFP”}\) + \(\texttt{“Zcash\_Sprout\_AFP”}\!\) , formerly specified for generation of Sprout address fingerprints;
      • the \(\mathsf{PRF^{expand}}\) prefix - \(\texttt{0x80}\) + \(\mathtt{0x80}\!\) , formerly specified for Sprout child key derivation;
      • the Bech32 Human-Readable Parts zxsprout and zxtestsprout, formerly specified for Sprout extended spending keys on Mainnet and Testnet respectively.
      diff --git a/rendered/zip-0203.html b/rendered/zip-0203.html index 074d62c7d..26ef4083e 100644 --- a/rendered/zip-0203.html +++ b/rendered/zip-0203.html @@ -3,7 +3,9 @@ ZIP 203: Transaction Expiry - + + +
      @@ -22,14 +24,14 @@

      Transactions that have insufficient fees are often not mined. This indeterminism is a source of confusion for users and wallets. Allowing a transaction to set a block height after which it cannot be mined would provide certainty around how long a transaction has to confirm before it is rejected by the network and must be re-sent.

      Advantages include optimizing mempool performance by removing transactions that will not be mined, and potentially simplifying bidirectional payment channels by reducing the need to store and compress revocations for past states, since transactions not committed to the chain could expire and become invalid after a period of time.

      If the expiry is at block height - \(N\) + \(N\!\!\) , then the transaction must be included in block \(N\) or earlier. Block \(N+1\) will be too late, and the transaction will be removed from the mempool.

      The new consensus rule will enforce that the transaction will not be considered valid if included in block of height greater than - \(N\) + \(N\!\!\) , and blocks that include expired transactions will not be considered valid.

      Specification

      diff --git a/rendered/zip-0207.html b/rendered/zip-0207.html index cebc673ba..88ced65b0 100644 --- a/rendered/zip-0207.html +++ b/rendered/zip-0207.html @@ -3,7 +3,9 @@ ZIP 207: Funding Streams - + + +
      @@ -36,7 +38,7 @@

      Motivation

      Motivation for the Zcash Development Fund is considered in ZIP 1014 20.

      This ZIP 207 was originally proposed for the Blossom network upgrade, as a means of splitting the original Founders' Reward into several streams. It was then withdrawn when such splitting was judged to be unnecessary at the consensus level. Since the capabilities of the funding stream mechanism match the requirements for the Zcash Development Fund, the ZIP was reintroduced for that purpose in the Canopy upgrade in order to reuse specification, analysis, and implementation effort.

      -

      As of NU6, ZIP 1015 21 directs part of the block reward to a reserve, the distribution of which is to be determined via a future ZIP. ZIP 2001 22 modified this ZIP to augment the funding stream mechanism with a common mechanism to implement this proposal.

      +

      As of NU6, ZIP 1015 21 directs part of the block subsidy to a reserve, the distribution of which is to be determined via a future ZIP. ZIP 2001 22 modified this ZIP to augment the funding stream mechanism with a common mechanism to implement this proposal.

      Requirements

      The primary requirement of this ZIP is to provide a mechanism for specifying the funding streams that are used in ZIP 214 17 to implement the Zcash Development Fund. It should be sufficiently expressive to handle both the main three "slices" (BP, ZF, and MG) defined in ZIP 1014 20, and also (with additional funding stream definitions) the "direct grant option" described in that ZIP.

      @@ -59,13 +61,13 @@ \(\mathsf{BlockSubsidy}(\mathsf{height})\)
    • - \(\mathsf{RedeemScriptHash}(\mathsf{height})\) + \(\mathsf{RedeemScriptHash}(\mathsf{height})\!\) .

    We also define the following function:

    • - \(\mathsf{HeightForHalving}(\mathsf{halving})\) + \(\mathsf{HeightForHalving}(\mathsf{halving})\!\) : Smallest \(\mathsf{height}\) such that @@ -82,11 +84,11 @@ \frac{\mathsf{BlockSubsidy}(\mathsf{height}) \,\cdot\, \mathsf{FundingStream[FUND].ValueNumerator}}{\mathsf{FundingStream[FUND].ValueDenominator}} \right)\)

      An active funding stream at a given block height is defined as a funding stream for which the block height is less than its end height, but not less than its start height.

      -

      The funding streams are paid to one of a pre-defined set of recipients, depending on the block height. Each recipient identifier MUST be either the string encoding of a transparent P2SH address or Sapling address (as specified in 6 or [#protocol-saplingpaymentaddrencoding]) to be paid by an output in the coinbase transaction, or the identifier - \(\mathsf{DEFERRED}\_\mathsf{POOL}\) - . The latter, added in the NU6 network upgrade 19, indicates that the value is to be paid to a reserve to be used for development funding, the distribution of which is to be determined via a future ZIP.

      +

      The funding streams are paid to one of a pre-defined set of recipients, depending on the block height. Each recipient identifier MUST be either the string encoding of a transparent P2SH address or Sapling address (as specified in 6 or 7) to be paid by an output in the coinbase transaction, or the identifier + \(\mathsf{DEFERRED\_POOL}\!\) + . The latter, added in the NU6 network upgrade 19, indicates that the value is to be paid to a reserve to be used for development funding, the distribution of which is to be determined via a future ZIP.

      Each address is used for at most 1/48th of a halving interval, creating a roughly-monthly sequence of funding periods. The address to be used for a given block height is defined as follows:

      -
      \(\begin{eqnarray*} +
      \(\begin{array}{rcl} \mathsf{AddressChangeInterval} &=& \mathsf{PostBlossomHalvingInterval} / 48 \\ \mathsf{AddressPeriod}(\mathsf{height}) &=& \mathsf{floor}\left( @@ -95,7 +97,7 @@ \mathsf{FundingStream[FUND].AddressIndex}(\mathsf{height}) &=& \mathsf{AddressPeriod}(\mathsf{height}) - \\&&\hspace{2em} \mathsf{AddressPeriod}(\mathsf{FundingStream[FUND].StartHeight}) \\ \mathsf{FundingStream[FUND].Address}(\mathsf{height}) &=& \mathsf{FundingStream[FUND].Addresses[} \\&&\hspace{2em} \mathsf{FundingStream[FUND].AddressIndex}(\mathsf{height})\mathsf{]} -\end{eqnarray*}\)
      +\end{array}\)

      This has the property that all active funding streams change the address they are using on the same block height schedule, aligned to the height of the first halving so that 48 funding periods fit cleanly within a halving interval. This can be leveraged to simplify implementations, by batching the necessary outputs for each funding period.

      Below is a visual representation of how stream addresses align with funding periods:

      @@ -207,21 +209,21 @@ where \(\mathsf{DeferredFundingStreams}(\mathsf{height})\) is the set of funding streams with recipient identifier - \(\mathsf{DEFERRED}\_\mathsf{POOL}\) + \(\mathsf{DEFERRED\_POOL}\) in the block at height - \(\mathsf{height}\) + \(\mathsf{height}\!\) .

      The \(\mathsf{ChainValuePoolBalance^{Deferred}}\) chain value pool balance for a given block chain is the sum of the values of payments to - \(\mathsf{DEFERRED}\_\mathsf{POOL}\) + \(\mathsf{DEFERRED\_POOL}\) for transactions in the block chain.

      Equivalently, \(\mathsf{ChainValuePoolBalance^{Deferred}}\) for a block chain up to and including height \(\mathsf{height}\) is given by - \(\sum_{\mathsf{h} = 0}^{\mathsf{height}} \mathsf{totalDeferredOutput}(\mathsf{h})\) + \(\sum_{\mathsf{h} = 0}^{\mathsf{height}} \mathsf{totalDeferredOutput}(\mathsf{h})\!\) .

      Note: \(\mathsf{totalDeferredOutput}(\mathsf{h})\) @@ -230,18 +232,18 @@ prior to NU6 activation.

    Consensus rules

    -

    Prior to activation of the Canopy network upgrade, the existing consensus rule for payment of the original Founders' Reward is enforced. 10

    +

    Prior to activation of the Canopy network upgrade, the existing consensus rule for payment of the original Founders' Reward is enforced. 10

    Once the Canopy network upgrade activates:

      -
    • The existing consensus rule for payment of the Founders' Reward 10 is no longer active. (This would be the case under the preexisting consensus rules for Mainnet, but not for Testnet.)
    • +
    • The existing consensus rule for payment of the Founders' Reward 10 is no longer active. (This would be the case under the preexisting consensus rules for Mainnet, but not for Testnet.)
    • In each block with coinbase transaction \(\mathsf{cb}\) at block height - \(\mathsf{height}\) + \(\mathsf{height}\!\) , for each funding stream \(\mathsf{fs}\) active at that block height with a recipient identifier other than - \(\mathsf{DEFERRED}\_\mathsf{POOL}\) + \(\mathsf{DEFERRED\_POOL}\) given by \(\mathsf{fs.Recipient}(\mathsf{height})\!\) , @@ -252,29 +254,29 @@
    • \(\mathsf{fs.Recipient}(\mathsf{height})\) is defined as - \(\mathsf{fs.Recipients_{\,\fs.RecipientIndex}}(\mathsf{height})\!\) + \(\mathsf{fs.Recipients_{\,fs.RecipientIndex}}(\mathsf{height})\!\) .
    • The "prescribed way" to pay a transparent P2SH address is to use a standard P2SH script of the form OP_HASH160 RedeemScriptHash(height) OP_EQUAL as the scriptPubKey.
    • -
    • The "prescribed way" to pay a Sapling address is as defined in 16. That is, all Sapling outputs in coinbase transactions (including, but not limited to, outputs for funding streams) MUST have valid note commitments when recovered using a 32-byte array of zeroes as the outgoing viewing key. In this case the note plaintext lead byte MUST be +
    • The "prescribed way" to pay a Sapling address is as defined in 16. That is, all Sapling outputs in coinbase transactions (including, but not limited to, outputs for funding streams) MUST have valid note commitments when recovered using a 32-byte array of zeroes as the outgoing viewing key. In this case the note plaintext lead byte MUST be \(\mathbf{0x02}\!\) - , as specified in 15.
    • + , as specified in 15.
    -

    These rules are reproduced in [#protocol-fundingstreams].

    +

    These rules are reproduced in 11.

    The effect of the definition of \(\mathsf{ChainValuePoolBalance^{Deferred}}\) above is that payments to the - \(\mathsf{DEFERRED}\_\mathsf{POOL}\) + \(\mathsf{DEFERRED\_POOL}\) cause \(\mathsf{FundingStream[FUND].Value}(\mathsf{height})\) to be added to \(\mathsf{ChainValuePoolBalance^{Deferred}}\) for the block chain including that block.

    -

    For the funding stream definitions to be activated at Canopy and at NU6, see ZIP 214. 17 Funding stream definitions can be added, changed, or deleted in ZIPs associated with subsequent network upgrades, subject to the ZIP process. 12

    +

    For the funding stream definitions to be activated at Canopy and at NU6, see ZIP 214. 17 Funding stream definitions can be added, changed, or deleted in ZIPs associated with subsequent network upgrades, subject to the ZIP process. 12

    Deployment

    -

    This proposal was initially deployed with Canopy. 18

    -

    Changes to support deferred funding streams are to be deployed with NU6. 19

    +

    This proposal was initially deployed with Canopy. 18

    +

    Changes to support deferred funding streams are to be deployed with NU6. 19

    Backward compatibility

    This proposal intentionally creates what is known as a "bilateral consensus rule change". Use of this mechanism requires that all network participants upgrade their software to a compatible version within the upgrade window. Older software will treat post-upgrade blocks as invalid, and will follow any pre-upgrade consensus branch that persists.

    @@ -291,7 +293,7 @@ 1 - Information on BCP 14 — "RFC 2119: Key words for use in RFCs to Indicate Requirement Levels" and "RFC 8174: Ambiguity of Uppercase vs Lowercase in RFC 2119 Key Words" <https://www.rfc-editor.org/info/bcp14> + Information on BCP 14 — "RFC 2119: Key words for use in RFCs to Indicate Requirement Levels" and "RFC 8174: Ambiguity of Uppercase vs Lowercase in RFC 2119 Key Words" @@ -299,7 +301,7 @@ 2 - Zcash Protocol Specification, Version 2024.5.1 or later <protocol/protocol.pdf> + Zcash Protocol Specification, Version 2024.5.1 or later @@ -307,7 +309,7 @@ 3 - Zcash Protocol Specification, Version 2024.5.1 [NU6]. Section 3.10: Block Subsidy and Founders' Reward <protocol/protocol.pdf#subsidyconcepts> + Zcash Protocol Specification, Version 2024.5.1 [NU6]. Section 3.10: Block Subsidy and Founders' Reward @@ -315,7 +317,7 @@ 4 - Zcash Protocol Specification, Version 2024.5.1 [NU6]. Section 3.12: Mainnet and Testnet <protocol/protocol.pdf#networks> + Zcash Protocol Specification, Version 2024.5.1 [NU6]. Section 3.12: Mainnet and Testnet @@ -323,7 +325,7 @@ 5 - Zcash Protocol Specification, Version 2024.5.1 [NU6]. Section 5.3: Constants <protocol/protocol.pdf#constants> + Zcash Protocol Specification, Version 2024.5.1 [NU6]. Section 5.3: Constants @@ -331,7 +333,7 @@ 6 - Zcash Protocol Specification, Version 2024.5.1 [NU6]. Section 5.6.1.1: Transparent Addresses <protocol/protocol.pdf#transparentaddrencoding> + Zcash Protocol Specification, Version 2024.5.1 [NU6]. Section 5.6.1.1: Transparent Addresses @@ -339,7 +341,7 @@ 7 - Zcash Protocol Specification, Version 2024.5.1 [NU6]. Section 5.6.3.1: Sapling Payment Addresses <protocol/protocol.pdf#saplingpaymentaddrencoding> + Zcash Protocol Specification, Version 2024.5.1 [NU6]. Section 5.6.3.1: Sapling Payment Addresses @@ -347,7 +349,7 @@ 8 - Zcash Protocol Specification, Version 2024.5.1 [NU6]. Section 7.7.3: Difficulty adjustment <protocol/protocol.pdf#diffadjustment> + Zcash Protocol Specification, Version 2024.5.1 [NU6]. Section 7.7.3: Difficulty adjustment @@ -355,7 +357,7 @@ 9 - Zcash Protocol Specification, Version 2024.5.1 [NU6]. Section 7.8: Calculation of Block Subsidy, Funding Streams, and Founders' Reward <protocol/protocol.pdf#subsidies> + Zcash Protocol Specification, Version 2024.5.1 [NU6]. Section 7.8: Calculation of Block Subsidy, Funding Streams, and Founders' Reward @@ -363,7 +365,7 @@ 10 - Zcash Protocol Specification, Version 2024.5.1 [NU6]. Section 7.9: Payment of Founders' Reward <protocol/protocol.pdf#foundersreward> + Zcash Protocol Specification, Version 2024.5.1 [NU6]. Section 7.9: Payment of Founders' Reward @@ -371,7 +373,7 @@ 11 - Zcash Protocol Specification, Version 2024.5.1 [NU6]. Section 7.10: Payment of Funding Streams <protocol/protocol.pdf#fundingstreams> + Zcash Protocol Specification, Version 2024.5.1 [NU6]. Section 7.10: Payment of Funding Streams @@ -379,7 +381,7 @@ 12 - ZIP 0: ZIP Process <zip-0000.rst> + ZIP 0: ZIP Process @@ -387,7 +389,7 @@ 13 - ZIP 200: Network Upgrade Mechanism <zip-0200.rst> + ZIP 200: Network Upgrade Mechanism @@ -395,7 +397,7 @@ 14 - ZIP 208: Shorter Block Target Spacing <zip-0208.rst> + ZIP 208: Shorter Block Target Spacing @@ -403,7 +405,7 @@ 15 - ZIP 212: Allow Recipient to Derive Sapling Ephemeral Secret from Note Plaintext <zip-0212.rst> + ZIP 212: Allow Recipient to Derive Sapling Ephemeral Secret from Note Plaintext @@ -411,7 +413,7 @@ 16 - ZIP 213: Shielded Coinbase <zip-0213.rst> + ZIP 213: Shielded Coinbase @@ -419,7 +421,7 @@ 17 - ZIP 214: Consensus rules for a Zcash Development Fund <zip-0214.rst> + ZIP 214: Consensus rules for a Zcash Development Fund @@ -427,7 +429,7 @@ 18 - ZIP 251: Deployment of the Canopy Network Upgrade <zip-0251.rst> + ZIP 251: Deployment of the Canopy Network Upgrade @@ -435,7 +437,7 @@ 19 - ZIP 253: Deployment of the NU6 Network Upgrade <zip-0253.rst> + ZIP 253: Deployment of the NU6 Network Upgrade @@ -443,7 +445,7 @@ 20 - ZIP 1014: Establishing a Dev Fund for ECC, ZF, and Major Grants <zip-1014.rst> + ZIP 1014: Establishing a Dev Fund for ECC, ZF, and Major Grants @@ -451,7 +453,7 @@ 21 - ZIP 1015: Block Reward Allocation for Non-Direct Development Funding <zip-1015.rst> + ZIP 1015: Block Subsidy Allocation for Non-Direct Development Funding @@ -459,7 +461,7 @@ 22 - ZIP 2001: Lockbox Funding Streams <zip-2001.rst> + ZIP 2001: Lockbox Funding Streams diff --git a/rendered/zip-0208.html b/rendered/zip-0208.html index 4d4a014bc..b3734d244 100644 --- a/rendered/zip-0208.html +++ b/rendered/zip-0208.html @@ -3,6 +3,9 @@ ZIP 208: Shorter Block Target Spacing + + +
    @@ -38,81 +41,181 @@

    Specification

    The changes described in this section are to be made in the Zcash Protocol Specification 3, relative to the pre-Blossom specification in [#preblossom-protocol].

    Consensus changes

    -

    Throughout the specification, rename HalvingInterval to PreBlossomHalvingInterval, and rename PoWTargetSpacing to PreBlossomTargetSpacing. These constants retain their values from 2 of 840000 (blocks) and 150 (seconds) respectively.

    -

    In section 2 (Notation), add BlossomActivationHeight and PostBlossomPoWTargetSpacing to the list of integer constants.

    -

    In section 5.3 (Constants), define PostBlossomPoWTargetSpacing := 75 seconds.

    -

    For a given network (production or test), define BlossomActivationHeight as the height at which Blossom activates on that network, as specified in 11.

    +

    Throughout the specification, rename + \(\mathsf{HalvingInterval}\) + to + \(\mathsf{PreBlossomHalvingInterval}\!\) + , and rename + \(\mathsf{PoWTargetSpacing}\) + to + \(\mathsf{PreBlossomTargetSpacing}\!\) + . These constants retain their values from 2 of + \(840000\) + (blocks) and + \(150\) + (seconds) respectively.

    +

    In section 2 (Notation), add + \(\mathsf{BlossomActivationHeight}\) + and + \(\mathsf{PostBlossomPoWTargetSpacing}\) + to the list of integer constants.

    +

    In section 5.3 (Constants), define + \(\mathsf{PostBlossomPoWTargetSpacing} := 75\) + seconds.

    +

    For a given network (production or test), define + \(\mathsf{BlossomActivationHeight}\) + as the height at which Blossom activates on that network, as specified in 11.

    In section 7.6.3 (Difficulty adjustment) [later moved to section 7.7.3], make the following changes:

    -

    Define IsBlossomActivated(height) to return true if height ≥ BlossomActivationHeight, otherwise false.

    -

    This specification assumes that BlossomActivationHeight ≥ SlowStartInterval.

    +

    Define + \(\mathsf{IsBlossomActivated}(\mathsf{height})\) + to return true if + \(\mathsf{height} \geq \mathsf{BlossomActivationHeight}\!\) + , otherwise false.

    +

    This specification assumes that + \(\mathsf{BlossomActivationHeight} \geq \mathsf{SlowStartInterval}\!\) + .

    Define:

      -
    • BlossomPoWTargetSpacingRatio := PreBlossomPoWTargetSpacing / PostBlossomPoWTargetSpacing
    • -
    • PostBlossomHalvingInterval := floor(PreBlossomHalvingInterval ¡ BlossomPoWTargetSpacingRatio).
    • -
    -

    In the same section, redefine PoWTargetSpacing as a function taking a height parameter, as follows:

    -
      -
    • PoWTargetSpacing(height) := -
        -
      • PreBlossomPoWTargetSpacing, if not IsBlossomActivated(height)
      • -
      • PostBlossomPoWTargetSpacing, otherwise.
      • -
      +
    • + \(\mathsf{BlossomPoWTargetSpacingRatio} := \mathsf{PreBlossomPoWTargetSpacing} / \mathsf{PostBlossomPoWTargetSpacing}\)
    • +
    • + \(\mathsf{PostBlossomHalvingInterval} := \mathsf{floor}(\mathsf{PreBlossomHalvingInterval} \cdot \mathsf{BlossomPoWTargetSpacingRatio})\!\) + .
    -

    Also redefine AveragingWindowTimespan, MinActualTimespan, MaxActualTimespan, ActualTimespanDamped, ActualTimespanBounded, and Threshold as follows:

    -
      -
    • add a height parameter to each of these functions that does not already have one;
    • -
    • ensure that each reference to any of these values, or to PoWTargetSpacing, are replaced with a function call passing the height parameter.
    • -
    -

    In section 7.7 (Calculation of Block Subsidy and Founders’ Reward) [later moved to section 7.8], redefine the Halving and BlockSubsidy functions as follows:

    +

    In the same section, redefine $mathsf{PoWTargetSpacing} as a function taking a + \(\mathsf{height}\) + parameter, as follows:

    +
    \(\mathsf{PoWTargetSpacing}(\mathsf{height}) := + \begin{cases} + \mathsf{PreBlossomPoWTargetSpacing}, &\!\!\text{if not } \mathsf{IsBlossomActivated}(\mathsf{height}) \\ + \mathsf{PostBlossomPoWTargetSpacing} &\!\!\text{otherwise} + \end{cases}\)
    +

    Also redefine + \(\mathsf{AveragingWindowTimespan}\!\) + , + \(\mathsf{MinActualTimespan}\!\) + , + \(\mathsf{MaxActualTimespan}\!\) + , + \(\mathsf{ActualTimespanDamped}\!\) + , + \(\mathsf{ActualTimespanBounded}\!\) + , and + \(\mathsf{Threshold}\) + as follows:

      -
    • Halving(height) := -
        -
      • floor((height - SlowStartShift) / PreBlossomHalvingInterval), if not IsBlossomActivated(height)
      • -
      • floor((BlossomActivationHeight - SlowStartShift) / PreBlossomHalvingInterval + (height - BlossomActivationHeight) / PostBlossomHalvingInterval), otherwise
      • -
      -
    • -
    • BlockSubsidy(height) := -
        -
      • SlowStartRate ¡ height, if height < SlowStartInterval / 2
      • -
      • SlowStartRate ¡ (height + 1), if SlowStartInterval / 2 ≤ height and height < SlowStartInterval
      • -
      • floor(MaxBlockSubsidy / 2Halving(*height*)), if SlowStartInterval ≤ height and not IsBlossomActivated(height)
      • -
      • floor(MaxBlockSubsidy / (BlossomPoWTargetSpacingRatio ¡ 2Halving(*height*))), otherwise
      • -
      -
    • +
    • add a + \(\mathsf{height}\) + parameter to each of these functions that does not already have one;
    • +
    • ensure that each reference to any of these values, or to + \(\mathsf{PoWTargetSpacing}\!\) + , are replaced with a function call passing the + \(\mathsf{height}\) + parameter.
    -

    Note: BlossomActivationHeight, PostBlossomHalvingInterval, and PostBlossomTargetSpacing are chosen so that:

    +

    In section 7.7 (Calculation of Block Subsidy and Founders’ Reward) [later moved to section 7.8], redefine the + \(\mathsf{Halving}\) + and + \(\mathsf{BlockSubsidy}\) + functions as follows:

    +
    \(\mathsf{Halving}(\mathsf{height}) := + \begin{cases} + \mathsf{floor}((\mathsf{height} - \mathsf{SlowStartShift}) / \mathsf{PreBlossomHalvingInterval}), &\!\!\text{if not } \mathsf{IsBlossomActivated}(\mathsf{height}) \\ + \mathsf{floor}((\mathsf{BlossomActivationHeight} - \mathsf{SlowStartShift}) / \mathsf{PreBlossomHalvingInterval} & \\ + \hspace{1em}+\; (\mathsf{height} - \mathsf{BlossomActivationHeight}) / \mathsf{PostBlossomHalvingInterval}) &\!\!\text{otherwise} + \end{cases}\)
    +
    \(\mathsf{BlockSubsidy}(\mathsf{height}) := + \begin{cases} + \mathsf{SlowStartRate} \cdot \mathsf{height}, &\!\!\text{if } \mathsf{height} < \mathsf{SlowStartInterval} / 2 \\ + \mathsf{SlowStartRate} \cdot (\mathsf{height} + 1), &\!\!\text{if } \mathsf{SlowStartInterval} / 2 \leq \mathsf{height} \text{ and } \mathsf{height} < \mathsf{SlowStartInterval} \\ + \mathsf{floor}(\mathsf{MaxBlockSubsidy} / 2^{\mathsf{Halving}(\mathsf{height})}), &\!\!\text{if } \mathsf{SlowStartInterval} \leq \mathsf{height} \text{ and not } \mathsf{IsBlossomActivated}(\mathsf{height}) \\ + \mathsf{floor}(\mathsf{MaxBlockSubsidy} / & \\ + \hspace{1em}(\mathsf{BlossomPoWTargetSpacingRatio} \cdot 2^{\mathsf{Halving}(\mathsf{height})})) &\!\!\text{otherwise} + \end{cases}\)
    +

    Note: + \(\mathsf{BlossomActivationHeight}\!\) + , + \(\mathsf{PostBlossomHalvingInterval}\!\) + , and + \(\mathsf{PostBlossomTargetSpacing}\) + are chosen so that:

      -
    • (BlossomActivationHeight - SlowStartShift) / PreBlossomHalvingInterval + (height - BlossomActivationHeight) / PostBlossomHalvingInterval) is exactly 1 for some integer height.
    • -
    • MaxBlockSubsidy / (BlossomPoWTargetSpacingRatio ¡ 2Halving(*height*)) is an integer for the next few periods.
    • +
    • + \((\mathsf{BlossomActivationHeight} - \mathsf{SlowStartShift}) / \mathsf{PreBlossomHalvingInterval}\hspace{-3em}\) + \(\hspace{3em}+\; (\mathsf{height} - \mathsf{BlossomActivationHeight}) / \mathsf{PostBlossomHalvingInterval}\) + is exactly + \(1\) + for some integer + \(\mathsf{height}\!\) + .
    • +
    • + \(\mathsf{MaxBlockSubsidy} / (\mathsf{BlossomPoWTargetSpacingRatio} \cdot 2^{\mathsf{Halving}(\mathsf{height})})\) + is an integer for the next few periods.

    In section 7.8 (Payment of Founders’ Reward) [later moved to section 7.9], define:

    -
      -
    • FounderAddressAdjustedHeight(height) := -
        -
      • height, if not IsBlossomActivated(height)
      • -
      • BlossomActivationHeight + floor((height - BlossomActivationHeight) / BlossomPoWTargetSpacingRatio), otherwise
      • -
      -
    • -
    -

    and in the definition of FounderAddressIndex, replace the use of height with FounderAddressAdjustedHeight(height).

    +
    \(\mathsf{FounderAddressAdjustedHeight}(\mathsf{height}) := + \begin{cases} + \mathsf{height}, &\!\!\text{if not } \mathsf{IsBlossomActivated}(\mathsf{height}) \\ + \mathsf{BlossomActivationHeight} + \mathsf{floor}((\mathsf{height} - \mathsf{BlossomActivationHeight}) / \\ + \hspace{1em}\mathsf{BlossomPoWTargetSpacingRatio}) &\!\!\text{otherwise} + \end{cases}\)
    +

    and in the definition of + \(\mathsf{FounderAddressIndex}\!\) + , replace the use of + \(\mathsf{height}\) + with + \(\mathsf{FounderAddressAdjustedHeight}(\mathsf{height})\!\) + .

    Also define:

      -
    • FoundersRewardLastBlockHeight := max({ height ⦂ N | Halving(height) < 1 })
    • +
    • + \(\mathsf{FoundersRewardLastBlockHeight} := \mathsf{max}(\{ \mathsf{height} \;{\small ⦂}\; \mathbb{N} | \mathsf{Halving}(\mathsf{height}) < 1 \})\) +

    Replace the first note in that section with:

      -
    • No Founders’ Reward is required to be paid for height > FoundersRewardLastBlockHeight (i.e. after the first halving), or for height = 0 (i.e. the genesis block).
    • +
    • No Founders’ Reward is required to be paid for + \(\mathsf{height} > \mathsf{FoundersRewardLastBlockHeight}\) + (i.e. after the first halving), or for + \(\mathsf{height} = 0\) + (i.e. the genesis block).
    -

    and in the second note, replace SlowStartShift + PreBlossomHalvingInterval - 1 with FoundersRewardLastBlockHeight.

    +

    and in the second note, replace + \(\mathsf{SlowStartShift} + \mathsf{PreBlossomHalvingInterval} - 1\) + with + \(\mathsf{FoundersRewardLastBlockHeight}\!\) + .

    Effect on difficulty adjustment

    -

    The difficulty adjustment parameters PoWAveragingWindow and PoWMedianBlockSpan refer to numbers of blocks, but do not change at Blossom activation. This is because the amount of damping/averaging required is expected to be roughly the same, in terms of the number of blocks, after the change in block target spacing.

    -

    The change in the effective value of PoWTargetSpacing will cause the block spacing to adjust to the new target, at the normal rate for a difficulty adjustment. The results of simulations are consistent with this expected behaviour.

    -

    Note that the change in AveragingWindowTimespan(height) takes effect immediately when calculating the target difficulty starting from the block at the Blossom activation height, even though the difficulty of the preceding PoWAveragingWindow blocks will have been adjusted using the pre-Blossom target spacing. Therefore it is likely that the difficulty adjustment for the first few blocks after activation will be limited by PoWMaxAdjustDown. This is not anticipated to cause any problem.

    +

    The difficulty adjustment parameters + \(\mathsf{PoWAveragingWindow}\) + and + \(\mathsf{PoWMedianBlockSpan}\) + refer to numbers of blocks, but do not change at Blossom activation. This is because the amount of damping/averaging required is expected to be roughly the same, in terms of the number of blocks, after the change in block target spacing.

    +

    The change in the effective value of + \(\mathsf{PoWTargetSpacing}\) + will cause the block spacing to adjust to the new target, at the normal rate for a difficulty adjustment. The results of simulations are consistent with this expected behaviour.

    +

    Note that the change in + \(\mathsf{AveragingWindowTimespan(\mathsf{height})\) + takes effect immediately when calculating the target difficulty starting from the block at the Blossom activation height, even though the difficulty of the preceding + \(\mathsf{PoWAveragingWindow}\) + blocks will have been adjusted using the pre-Blossom target spacing. Therefore it is likely that the difficulty adjustment for the first few blocks after activation will be limited by + \(\mathsf{PoWMaxAdjustDown}\!\) + . This is not anticipated to cause any problem.

    Minimum difficulty blocks on Testnet

    On Testnet from block height 299188 onward, the difficulty adjustment algorithm 6 allows minimum-difficulty blocks, as described in 10, when the block time is greater than a given threshold. This specification changes this threshold to be proportional to the block target spacing.

    -

    That is, if the block time of a block at height height ≥ 299188 is greater than 6 · PoWTargetSpacing(height) seconds after that of the preceding block, then the block is a minimum-difficulty block. In that case its nBits field MUST be set to ToCompact(PoWLimit), where PoWLimit is the value defined for Testnet in section 5.3 of the Zcash Protocol Specification 5, and ToCompact is as defined in section 7.7.4 of that specification 7.

    +

    That is, if the block time of a block at height + \(\mathsf{height} \geq 299188\) + is greater than + \(6 \cdot \mathsf{PoWTargetSpacing}(\mathsf{height})\) + seconds after that of the preceding block, then the block is a minimum-difficulty block. In that case its nBits field MUST be set to + \(\mathsf{ToCompact}(\mathsf{PoWLimit})\!\) + , where + \(\mathsf{PoWLimit}\) + is the value defined for Testnet in section 5.3 of the Zcash Protocol Specification 5, and + \(\mathsf{ToCompact}\) + is as defined in section 7.7.4 of that specification 7.

    Note: a previous revision of this ZIP (and 10) incorrectly said that only the target threshold of minimum-difficulty blocks is affected. In fact the nBits field is modified as well, and this affects difficulty adjustment for subsequent blocks.

    This change does not affect Mainnet.

    @@ -162,7 +265,9 @@

    If pruning is enabled, when zcashd responds to an "getblocks" peer-to-peer message, it will only include blocks that it has on disk, and is likely to still have on disk an hour after responding to the message:

    // If pruning, don't inv blocks unless we have on disk and are likely to still have
     // for some reasonable time window (1 hour) that block relay might require.
    -

    For each block, when estimating whether it will still be on disk after an hour, we take MIN_BLOCKS_TO_KEEP = 288 blocks, minus approximately the number of blocks expected in one hour at the target block spacing as of that block. Around Blossom activation, this might underestimate the number of blocks in the next hour, but given the value of MIN_BLOCKS_TO_KEEP, this is not anticipated to cause any problem.

    +

    For each block, when estimating whether it will still be on disk after an hour, we take MIN_BLOCKS_TO_KEEP = + \(288\) + blocks, minus approximately the number of blocks expected in one hour at the target block spacing as of that block. Around Blossom activation, this might underestimate the number of blocks in the next hour, but given the value of MIN_BLOCKS_TO_KEEP, this is not anticipated to cause any problem.

    Estimation of fully synced chain height

    zcashd uses the EstimateNetHeight function to estimate the approximate height of the fully synced chain, so that the progress of block download can be displayed to the node operator. This function has been rewritten, simplified, and changed to take account of cases where the time period that needs to be estimated crosses Blossom activation.

    @@ -200,7 +305,9 @@

    This proposal intentionally creates what is known as a "bilateral consensus rule change". Use of this mechanism requires that all network participants upgrade their software to a compatible version within the upgrade window. Older software will treat post-upgrade blocks as invalid, and will follow any pre-upgrade consensus branch that persists.

    Reference Implementation

    -

    https://github.com/zcash/zcash/pull/4025

    +

    References

    diff --git a/rendered/zip-0212.html b/rendered/zip-0212.html index 2c755bc84..846588b62 100644 --- a/rendered/zip-0212.html +++ b/rendered/zip-0212.html @@ -3,7 +3,9 @@ ZIP 212: Allow Recipient to Derive Ephemeral Secret from Note Plaintext - + + +
    diff --git a/rendered/zip-0213.html b/rendered/zip-0213.html index f40ada08c..cc6874324 100644 --- a/rendered/zip-0213.html +++ b/rendered/zip-0213.html @@ -23,7 +23,7 @@

    This proposal defines modifications to the Zcash consensus rules that enable coinbase funds to be mined to Sapling (and later Orchard) addresses. It does not disable the use of transparent addresses in coinbase transactions.

    Motivation

    -

    Zcash inherited the concept of "coinbase transactions" from Bitcoin: special transactions inside each block that are allowed to have no inputs. These transactions are created by miners during block creation, and collect the block reward and transaction fees into new transparent outputs that can then be spent. They are also leveraged in Zcash for the Founders' Reward (and potentially for funding streams 4).

    +

    Zcash inherited the concept of "coinbase transactions" from Bitcoin: special transactions inside each block that are allowed to have no inputs. These transactions are created by miners during block creation, and collect the block subsidy and transaction fees into new transparent outputs that can then be spent. They are also leveraged in Zcash for the Founders' Reward (and potentially for funding streams 4).

    On the path to deprecating and removing Bitcoin-inherited transparent addresses within the Zcash network, a required step is to be able to create coinbase transactions that have no transparent outputs. However, Zcash was launched with a consensus rule preventing coinbase transactions from containing shielded outputs, instead enforcing that coinbase funds could not be spent in transactions with transparent outputs. This was partly in order to reduce the complexity of the original Zcash modifications to the Bitcoin Core codebase, but also because at the time, shielded transactions required significant memory and CPU resources to create.

    The Sapling network upgrade 3 deployed architectural changes and performance improvements that make shielding funds directly in the coinbase transaction feasible. In order to reduce the complexity of the Sapling network upgrade, the existing consensus rules preventing coinbase transactions from containing shielded outputs were extended to cover Sapling outputs. Therefore, it is now necessary to modify the consensus rules in order to enable miners to start using Sapling addresses. It will also be possible for miners to use Orchard addresses starting from activation of the NU5 upgrade 6.

    diff --git a/rendered/zip-0214.html b/rendered/zip-0214.html index f92bedcbc..75a60ab89 100644 --- a/rendered/zip-0214.html +++ b/rendered/zip-0214.html @@ -29,7 +29,7 @@

    Abstract

    Revision 0 of this ZIP describes consensus rule changes interpreting the proposed structure of the Zcash Development Fund, which is to be enacted in Network Upgrade 4 and last for 4 years.

    -

    Revision 1 of this ZIP describes consensus rule changes related to funding of Zcash development via block rewards, to be enacted at Network Upgrade 6 and lasting for 1 year.

    +

    Revision 1 of this ZIP describes consensus rule changes related to funding of Zcash development via block subsidies, to be enacted at Network Upgrade 6 and lasting for 1 year.

    Applicability

    This ZIP concerns the Zcash Mainnet and Testnet, and is not intended to be applicable to other block chains using Zcash technology.

    @@ -467,7 +467,7 @@

    Rationale for Revision 0

    - +
    14ZIP 1015: Block Reward Allocation for Non-Direct Development FundingZIP 1015: Block Subsidy Allocation for Non-Direct Development Funding
    diff --git a/rendered/zip-0215.html b/rendered/zip-0215.html index 4fe952bc9..215315187 100644 --- a/rendered/zip-0215.html +++ b/rendered/zip-0215.html @@ -3,7 +3,9 @@ ZIP 215: Explicitly Defining and Modifying Ed25519 Validation Rules - + + +
    @@ -43,7 +45,7 @@ MUST represent an integer \(S\) less than - \(\ell\) + \(\ell\!\) ;
  • The group equation \([8][S]B = [8]R + [8][k]A\) @@ -61,12 +63,12 @@ and \(\underline{R}\) are canonical encodings; in other words, the integer encoding the - \(y\) + \(y\!\) -coordinate of the points may be unreduced modulo - \(2^{255}-19\) + \(2^{255}-19\!\) .

    Note: the alternate validation equation - \([S]B = R + [k]A\) + \([S]B = R + [k]A\!\) , allowed by RFC 8032, MUST NOT be used.

  • Rationale

    diff --git a/rendered/zip-0216.html b/rendered/zip-0216.html index 52bc7adab..32d031186 100644 --- a/rendered/zip-0216.html +++ b/rendered/zip-0216.html @@ -3,7 +3,9 @@ ZIP 216: Require Canonical Jubjub Point Encodings - + + +
    @@ -38,14 +40,14 @@ -coordinate zero:

    • - \((0, 1)\) + \((0, 1)\!\) , which is the identity;
    • - \((0, -1)\) + \((0, -1)\!\) , which is a point of order two.

    Each of these has a single non-canonical encoding in which the value of the sign bit is - \(1\) + \(1\!\) .

    This creates a consensus issue because (unlike other non-canonical point encodings that are rejected) either of the above encodings can be decoded, and then re-encoded to a different encoding. For example, if a non-canonical encoding appeared in a transaction field, then node implementations that store points internally as abstract curve points, and used those to derive transaction IDs, would derive different IDs than nodes which store transactions as bytes (such as zcashd).

    This issue is not known to cause any security vulnerability, beyond the risk of consensus incompatibility. In fact, for some of the fields that would otherwise be affected, the issue does not occur because there are already consensus rules that prohibit small-order points, and this incidentally prohibits non-canonical encodings.

    @@ -53,25 +55,25 @@

    Specification

    Let - \(\mathsf{abst}_{\mathbb{J}}\) + \(\mathsf{abst}_{\mathbb{J}}\!\) , - \(\mathsf{repr}_{\mathbb{J}}\) + \(\mathsf{repr}_{\mathbb{J}}\!\) , and \(q_{\mathbb{J}}\) be as defined in 6.

    Define a non-canonical compressed encoding of a Jubjub point to be a sequence of \(256\) bits, - \(b\) + \(b\!\) , such that \(\mathsf{abst}_{\mathbb{J}}(b) \neq \bot\) and - \(\mathsf{repr_{\mathbb{J}}}\big(\mathsf{abst}_{\mathbb{J}}(b)\big) \neq b\) + \(\mathsf{repr_{\mathbb{J}}}\big(\mathsf{abst}_{\mathbb{J}}(b)\big) \neq b\!\) .

    Non-normative note: There are two such bit sequences, \(\mathsf{I2LEOSP}_{\ell_{\mathbb{J}}}(2^{255} + 1)\) and - \(\mathsf{I2LEOSP}_{\ell_{\mathbb{J}}}(2^{255} + q_{\mathbb{J}} - 1)\) + \(\mathsf{I2LEOSP}_{\ell_{\mathbb{J}}}(2^{255} + q_{\mathbb{J}} - 1)\!\) . The Sapling protocol uses little-endian ordering when converting between bit and byte sequences, so the first of these sequences corresponds to a \(\mathtt{0x01}\) byte, followed by @@ -110,7 +112,7 @@

    • - \(\mathsf{pk}\star_{\mathsf{d}}\) + \(\mathsf{pk}\star_{\mathsf{d}}\!\) .
    @@ -136,20 +138,20 @@ \(\mathtt{cv}\)
  • - \(\mathtt{ephemeralKey}\) + \(\mathtt{ephemeralKey}\!\) .
  • These fields cannot by consensus contain small-order points. All of the points with non-canonical encodings are small-order.

    Implementations MAY choose to reject non-canonical encodings of the above four fields early in decoding of a transaction. This eliminates the risk that parts of the transaction could be re-serialized from their internal representation to a different byte sequence than in the original transaction, e.g. when calculating transaction IDs.

    In addition, Sapling addresses and full viewing keys MUST be considered invalid when imported if they contain non-canonical Jubjub point encodings, or encodings of points that are not in the prime-order subgroup - \(\mathbb{J}^{(r)}\) + \(\mathbb{J}^{(r)}\!\) . These requirements MAY be enforced in advance of NU5 activation.

    In Sapling addresses 8:

    • the encoding of - \(\mathsf{pk_d}\) + \(\mathsf{pk_d}\!\) .
    @@ -157,14 +159,14 @@
    • the encoding of - \(\mathsf{ak}\) + \(\mathsf{ak}\!\) .

    ( \(\mathsf{ak}\) also MUST NOT encode the zero point - \(\mathcal{O}_{\mathbb{J}}\) + \(\mathcal{O}_{\mathbb{J}}\!\) .)

    The above is intended to be a complete list of the places where compressed encodings of Jubjub points occur in the Zcash consensus protocol and in plaintext, address, or key formats.

    @@ -178,22 +180,22 @@

    The necessary checks are very simple and do not require cryptographic operations, therefore the performance impact will be negligible.

    The public inputs of Jubjub points to the Spend circuit ( - \(\mathsf{rk}\) + \(\!\mathsf{rk}\) and - \(\mathsf{cv^{old}}\) + \(\mathsf{cv^{old}}\!\) ) and Output circuit ( - \(\mathsf{cv^{new}}\) + \(\!\mathsf{cv^{new}}\) and - \(\mathsf{epk}\) + \(\mathsf{epk}\!\) ) are not affected because they are represented in affine coordinates as elements of the correct field ( - \(\mathbb{F}_{r_\mathbb{S}} = \mathbb{F}_{q_\mathbb{J}}\) + \(\!\mathbb{F}_{r_\mathbb{S}} = \mathbb{F}_{q_\mathbb{J}}\!\) ), and so no issue of encoding canonicity arises.

    Encodings of elliptic curve points on Curve25519, BN-254 - \(\mathbb{G}_1\) + \(\mathbb{G}_1\!\) , BN-254 - \(\mathbb{G}_2\) + \(\mathbb{G}_2\!\) , BLS12-381 - \(\mathbb{G}_1\) + \(\mathbb{G}_1\!\) , and BLS12-381 \(\mathbb{G}_2\) are not affected.

    diff --git a/rendered/zip-0221.html b/rendered/zip-0221.html index a4e119e7b..400295cfc 100644 --- a/rendered/zip-0221.html +++ b/rendered/zip-0221.html @@ -3,7 +3,9 @@ ZIP 221: FlyClient - Consensus-Layer Changes - + + +
    @@ -25,13 +27,13 @@
    A client that is not a full participant in the network of Zcash peers. It can send and receive payments, but does not store or validate a copy of the block chain.
    High probability
    An event occurs with high probability if it occurs with probability - \(1-O(1/2^\lambda)\) + \(1-O(1/2^\lambda)\!\) , where \(\lambda\) is a security parameter.
    Negligible probability
    An event occurs with negligible probability if it occurs with probability - \(O(1/2^\lambda)\) + \(O(1/2^\lambda)\!\) , where \(\lambda\) is the security parameter.
    @@ -46,7 +48,7 @@

    An MMR is a Merkle tree which allows for efficient appends, proofs, and verifications. Informally, appending data to an MMR consists of creating a new leaf and then iteratively merging neighboring subtrees with the same size. This takes at most \(\log(n)\) operations and only requires knowledge of the previous subtree roots, of which there are fewer than - \(\log(n)\) + \(\log(n)\!\) .

    (example adapted from 6) To illustrate this, consider a list of 11 leaves. We first construct the biggest perfect binary subtrees possible by joining any balanced sibling trees that are the same size. We do this starting from the left to the right, adding a parent as soon as 2 children exist. This leaves us with three subtrees ("mountains") of altitudes 3, 1, and 0:

       /\
    @@ -122,7 +124,7 @@
                  be the altitude of a given node. We can easily jump to the node's right sibling (if it has one) by adding
                     \(2^{h+1} - 1\)
                  to its position, and its left child (if it has one) by subtracting
    -                \(2^h\)
    +                \(2^h\!\)
                 . This allows us to efficiently find the subtree roots ("peaks") of the mountains.

    Once we have the positions of the mountain peaks, we "bag" them using the following algorithm:

      @@ -162,14 +164,14 @@

      The protocol requires that an MMR that commits to the inclusion of all blocks since the preceding network upgrade \((B_x, \ldots, B_{n-1})\) is formed for each block - \(B_n\) + \(B_n\!\) . The root \(M_n\) of the MMR MUST be included in the header of - \(B_n\) + \(B_n\!\) .

      ( - \(x\) + \(\!x\) is the activation height of the preceding network upgrade.)

      FlyClient reduces the number of block headers needed for light client verification of a valid chain, from linear (as in the current reference protocol) to logarithmic in block chain length. This verification is correct with high probability. It also allows creation of subtree proofs, so light clients need only check blocks later than the most recently verified block index. Following that, verification of a transaction inclusion within that block follows the usual reference protocol 13.

      A smaller proof size could enable the verification of Zcash SPV Proofs in block-chain protocols such as Ethereum, enabling efficient cross-chain communication and pegs. It also reduces bandwidth and storage requirements for resource-limited clients like mobile or IoT devices.

      @@ -184,14 +186,14 @@ of \(B_n\) to be the last network upgrade activation height in the chain that is less than - \(n\) + \(n\!\) . (For this definition, block height \(0\) is considered to be the height of a network upgrade activation. The preceding network upgrade height of the genesis block is undefined.)

      The leaves of the MMR at block \(B_n\) are hash commitments to the header data and metadata of each previous block - \(B_x, \ldots, B_{n-1}\) + \(B_x, \ldots, B_{n-1}\!\) , where \(x\) is defined as above. We extend the standard MMR to allow metadata to propagate upwards through the tree by either summing the metadata of both children, or inheriting the metadata of a specific child as necessary. This allows us to create efficient proofs of selected properties of a range of blocks without transmitting the entire range of blocks or headers.

      @@ -209,7 +211,7 @@
    1. For clarity, in a given consensus branch, the hashSubtreeCommitment field of leaf \(n-1\) is precisely equal to the hashPrevBlock field in the header of the block at height - \(x+n\) + \(x+n\!\) , where \(x\) is the network upgrade activation height of that consensus branch.
    2. @@ -286,7 +288,7 @@
      Leaf node
      The protocol-defined work of the block: - \(\mathsf{floor}(2^{256} / (\mathsf{ToTarget}(\mathsf{nBits}) + 1))\) + \(\mathsf{floor}(2^{256} / (\mathsf{ToTarget}(\mathsf{nBits}) + 1))\!\) . 4
      Internal or root node
      @@ -462,9 +464,9 @@

    Incremental push and pop (pseudocode)

    With each new block - \(B_n\) + \(B_n\!\) , we append a new MMR leaf node corresponding to block - \(B_{n-1}\) + \(B_{n-1}\!\) . The append operation is detailed below in pseudocode (adapted from 2):

    def get_peaks(node: ZcashMMRNode) -> List[ZcashMMRNode]:
         peaks: List[ZcashMMRNode] = []
    @@ -600,7 +602,7 @@
                                 
    • This commitment serves the same purpose as hashFinalSaplingRoot in current Sapling semantics.
    • However, because the MMR tree commits to blocks - \(B_x \ldots B_{n-1}\) + \(B_x \ldots B_{n-1}\!\) , the latest commitment will describe the final treestate of the previous block, rather than the current block.
    • Concretely: block 500 currently commits to the final treestate of block 500 in its header. With this ZIP, block 500 will commit to all roots up to block 499, but not the final root of block 500.
    • We feel this is an acceptable tradeoff. Using the most recent treestate as a transaction anchor is already unsafe in reorgs. Clients should never use the most recent treestate to generate transactions, so it is acceptable to delay commitment by one block.
    • @@ -631,7 +633,7 @@

      The calculation of hashChainHistoryRoot is not well-defined for the genesis block, since then \(n = 0\) and there is no block - \(B_{n-1}\) + \(B_{n-1}\!\) . Also, in the case of chains that activate this ZIP after genesis (including Zcash Mainnet and Testnet), the hashChainHistoryRoot of the activation block would commit to the whole previous epoch if a special case were not made. It would be impractical to calculate this commitment all at once, and so we specify that hashLightClientRoot is set to all zero bytes for that block instead. The hash of the final Sapling note commitment tree root for the activation block will not be encoded in that block, but will be committed to one block later in the hashLatestSaplingRoot field of the MMR root commitment.

    diff --git a/rendered/zip-0224.html b/rendered/zip-0224.html index 211d87e21..e88a49eec 100644 --- a/rendered/zip-0224.html +++ b/rendered/zip-0224.html @@ -3,7 +3,9 @@ ZIP 224: Orchard Shielded Protocol - + + +
    @@ -49,13 +51,13 @@
  • Vesta is used as the "circuit curve"; its scalar field (being the base field of Pallas) is the "word" type over which the circuit is implemented (c/f BLS12-381).
  • We use the "simplified SWU" algorithm to define an infallible - \(\mathsf{GroupHash}\) + \(\mathsf{GroupHash}\!\) , instead of the fallible BLAKE2s-based mechanism used for Sapling. It is intended to follow (version 10 of) the IETF hash-to-curve Internet Draft 33 (but the protocol specification takes precedence in the case of any discrepancy).

    The presence of the curve cycle is an explicit design choice. This proposal only uses half of the cycle (Pallas being an embedded curve of Vesta); the full cycle is expected to be leveraged by future protocol updates.

    • Curve specifications: 15
    • - \(\mathsf{GroupHash}\) + \(\mathsf{GroupHash}\!\) : 16
    • Supporting evidence: 34
    @@ -101,7 +103,7 @@
  • \(\mathsf{ovk}\) is derived from - \(\mathsf{fvk}\) + \(\mathsf{fvk}\!\) , instead of being a component of the spending key.
  • All diversifiers now result in valid payment addresses.
  • @@ -117,10 +119,10 @@

    Notes

    Orchard notes have the structure - \((addr, v, \rho, \psi, \mathsf{rcm}).\) - \(\rho\) + \((addr, v, \text{ρ}, \text{φ}, \mathsf{rcm}).\) + \(\text{ρ}\) is set to the nullifier of the spent note in the same action, which ensures it is unique. - \(\psi\) + \(\text{φ}\) and \(\mathsf{rcm}\) are derived from a random seed (as with Sapling after ZIP 212 30).

    @@ -131,7 +133,7 @@

    Nullifiers

    Nullifiers for Orchard notes are computed as:

    - \(\mathsf{nf} = [F_{\mathsf{nk}}(\rho) + \psi \pmod{p}] \mathcal{G} + \mathsf{cm}\) + \(\mathsf{nf} = [F_{\mathsf{nk}}(\text{ρ}) + \text{φ} \pmod{p}] \,\mathcal{G} + \mathsf{cm}\)

    where \(F\) diff --git a/rendered/zip-0225.html b/rendered/zip-0225.html index 1ab6b9415..2d381715d 100644 --- a/rendered/zip-0225.html +++ b/rendered/zip-0225.html @@ -3,7 +3,9 @@ ZIP 225: Version 5 Transaction Format - + + +

    @@ -212,7 +214,9 @@
    • enableSpendsOrchard
    • enableOutputsOrchard
    • -
    • The remaining bits are set to 0.
    • +
    • The remaining bits are set to + \(0\!\) + .
    @@ -235,7 +239,7 @@ sizeProofsOrchard compactSize Length in bytes of proofsOrchard. Value is - \(2720 + 2272 \cdot \mathtt{nActionsOrchard}\) + \(2720 + 2272 \cdot \mathtt{nActionsOrchard}\!\) . @@ -260,22 +264,28 @@
    • The fields valueBalanceSapling and bindingSigSapling are present if and only if - \(\mathtt{nSpendsSapling} + \mathtt{nOutputsSapling} > 0\) + \(\mathtt{nSpendsSapling} + \mathtt{nOutputsSapling} > 0\!\) . If valueBalanceSapling is not present, then - \(\mathsf{v^{balanceSapling}}`\) - is defined to be 0.
    • + \(\mathsf{v^{balanceSapling}}\) + is defined to be + \(0\!\) + .
    • The field anchorSapling is present if and only if - \(\mathtt{nSpendsSapling} > 0\) + \(\mathtt{nSpendsSapling} > 0\!\) .
    • The fields flagsOrchard, valueBalanceOrchard, anchorOrchard, sizeProofsOrchard, proofsOrchard, and bindingSigOrchard are present if and only if - \(\mathtt{nActionsOrchard} > 0\) + \(\mathtt{nActionsOrchard} > 0\!\) . If valueBalanceOrchard is not present, then \(\mathsf{v^{balanceOrchard}}\) - is defined to be 0.
    • + is defined to be + \(0\!\) + .
    • The elements of vSpendProofsSapling and vSpendAuthSigsSapling have a 1:1 correspondence to the elements of vSpendsSapling and MUST be ordered such that the proof or signature at a given index corresponds to the SpendDescriptionV5 at the same index.
    • The elements of vOutputProofsSapling have a 1:1 correspondence to the elements of vOutputsSapling and MUST be ordered such that the proof at a given index corresponds to the OutputDescriptionV5 at the same index.
    • The proofs aggregated in proofsOrchard, and the elements of vSpendAuthSigsOrchard, each have a 1:1 correspondence to the elements of vActionsOrchard and MUST be ordered such that the proof or signature at a given index corresponds to the OrchardAction at the same index.
    • -
    • For coinbase transactions, the enableSpendsOrchard bit MUST be set to 0.
    • +
    • For coinbase transactions, the enableSpendsOrchard bit MUST be set to + \(0\!\) + .

    The encodings of tx_in, and tx_out are as in a version 4 transaction (i.e. unchanged from Canopy). The encodings of SpendDescriptionV5, OutputDescriptionV5 and OrchardAction are described below. The encoding of Sapling Spends and Outputs has changed relative to prior versions in order to better separate data that describe the effects of the transaction from the proofs of and commitments to those effects, and for symmetry with this separation in the Orchard-related parts of the transaction format.

    @@ -333,7 +343,9 @@ 32 cmu byte[32] - The u-coordinate of the note commitment for the output note. + The + \(u\!\) + -coordinate of the note commitment for the output note. 32 @@ -390,13 +402,15 @@ 32 cmx byte[32] - The x-coordinate of the note commitment for the output note. + The + \(x\!\) + -coordinate of the note commitment for the output note. 32 ephemeralKey byte[32] - An encoding of an ephemeral Pallas public key + An encoding of an ephemeral Pallas public key. 580 @@ -460,7 +474,7 @@
    • The joinSplitPubKey and joinSplitSig fields were specified to be present if and only if - \(\mathtt{nJoinSplit} > 0\) + \(\mathtt{nJoinSplit} > 0\!\) .
    diff --git a/rendered/zip-0226.html b/rendered/zip-0226.html index 3d898a601..b315cf8c2 100644 --- a/rendered/zip-0226.html +++ b/rendered/zip-0226.html @@ -3,7 +3,9 @@ ZIP 226: Transfer and Burn of Zcash Shielded Assets - + + +
    @@ -83,7 +85,7 @@ , which is a global byte string (scoped across all future versions of Zcash). From this Asset description and the issuance validating key of the issuer, the specific Asset Identifier, \(\mathsf{AssetId}\!\) , the Asset Digest, and the Asset Base ( - \(\mathsf{AssetBase}\!\) + \(\!\mathsf{AssetBase}\!\) ) are derived as defined in ZIP 227 5.

    This Asset Base will be the base point of the value commitment for the specific Custom Asset. Note that the Asset Base of the ZEC Asset will be kept as the original value base point, \(\mathcal{V}^{\mathsf{Orchard}}\!\) @@ -116,27 +118,36 @@

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

    -
    \(\mathsf{NoteCommit}^{\mathsf{OrchardZSA}} : \mathsf{NoteCommit}^{\mathsf{Orchard}}.\!\mathsf{Trapdoor} \times \mathbb{B}^{[\ell_{\mathbb{P}}]} \times \mathbb{B}^{[\ell_{\mathbb{P}}]} \times \{0 .. 2^{\ell_{\mathsf{value}}} - 1\} \times \mathbb{F}_{q_{\mathbb{P}}} \times \mathbb{F}_{q_{\mathbb{P}}} \times \mathbb{P}^* \to \mathsf{NoteCommit}^{\mathsf{Orchard}}.\!\mathsf{Output}\)
    +
      +
    • + \(\mathsf{NoteCommit}^{\mathsf{OrchardZSA}} : \mathsf{NoteCommit^{Orchard}.Trapdoor}\hspace{-1em}\) + \(\hspace{1em}\times\, \mathbb{B}^{[\ell_{\mathbb{P}}]}\hspace{-1em}\) + \(\hspace{1em}\times\, \mathbb{B}^{[\ell_{\mathbb{P}}]}\hspace{-1em}\) + \(\hspace{1em}\times\, \{0 .. 2^{\ell_{\mathsf{value}}} - 1\}\hspace{-1em}\) + \(\hspace{1em}\times\, \mathbb{F}_{q_{\mathbb{P}}}\hspace{-1em}\) + \(\hspace{1em}\times\, \mathbb{F}_{q_{\mathbb{P}}}\hspace{-1em}\) + \(\hspace{1em}\times\, \mathbb{P}^* \to \mathsf{NoteCommit^{Orchard}.Output}\) +
    • +

    where \(\mathbb{P}, \ell_{\mathbb{P}}, q_{\mathbb{P}}\) are as defined for the Pallas curve 29, and where - \(\mathsf{NoteCommit^{Orchard}}.\!\mathsf{Trapdoor}\) - and - \(\mathsf{Orchard}.\!\mathsf{Output}\) + \(\mathsf{NoteCommit^{Orchard}.\{Trapdoor, Output\}}\) are as defined in the Zcash protocol specification 19. This note commitment scheme is instantiated using the Sinsemilla Commitment 28 as follows:

    -
    \(\begin{align} -\mathsf{NoteCommit^{OrchardZSA}_{rcm}}(\mathsf{g_d}\star, \mathsf{pk_d}\star, \mathsf{v}, \text{ρ}, \text{ψ}, \mathsf{AssetBase}) -:= \begin{cases} - \mathsf{NoteCommit^{Orchard}_{rcm}}(\mathsf{g_d}\star, \mathsf{pk_d}\star, \mathsf{v}, \text{ρ}, \text{ψ}), &\text{if } \mathsf{AssetBase} = \mathcal{V}^{\mathsf{Orchard}} \\ - \mathsf{cm_{ZSA}} &\text{otherwise} - \end{cases} -\end{align}\)
    +
    \(\mathsf{NoteCommit^{OrchardZSA}_{rcm}}(\mathsf{g_d}\star, \mathsf{pk_d}\star, \mathsf{v}, \text{ρ}, \text{ψ}, \mathsf{AssetBase}) := + \begin{cases} + \mathsf{NoteCommit^{Orchard}_{rcm}}(\mathsf{g_d}\star, \mathsf{pk_d}\star, \mathsf{v}, \text{ρ}, \text{ψ}), &\!\!\text{if } \mathsf{AssetBase} = \mathcal{V}^{\mathsf{Orchard}} \\ + \mathsf{cm_{ZSA}} &\!\!\text{otherwise} + \end{cases}\)

    where:

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

    Note that \(\mathsf{repr}_{\mathbb{P}}\) and @@ -156,7 +167,7 @@ \(\mathsf{NoteCommit^{Orchard}_{rcm}}\) in that for Custom Assets, the Asset Base will be added as an input to the commitment computation. In the case where the Asset is the ZEC Asset, the commitment is computed identically to the Orchard note commitment, without making use of the ZEC Asset Base as an input. As we will see, the nested structure of the Sinsemilla-based commitment 28 allows us to add the Asset Base as a final recursive step.

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

    -
    \(\mathsf{NoteCommit^{OrchardZSA}_{rcm}}(\mathsf{repr}_{\mathbb{P}}(\mathsf{g_d}), \mathsf{repr}_{\mathbb{P}}(\mathsf{pk_d}), \mathsf{v}, \text{ρ}, \text{ψ}, \mathsf{AssetBase}) \in \mathsf{NoteCommit^{Orchard}}.\!\mathsf{Output}\)
    +
    \(\mathsf{NoteCommit^{OrchardZSA}_{rcm}}(\mathsf{repr}_{\mathbb{P}}(\mathsf{g_d}), \mathsf{repr}_{\mathbb{P}}(\mathsf{pk_d}), \mathsf{v}, \text{ρ}, \text{ψ}, \mathsf{AssetBase}) \in \mathsf{NoteCommit^{Orchard}.Output}\)

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

    @@ -165,19 +176,22 @@
    \(\mathsf{cv^{net}} := \mathsf{ValueCommit^{OrchardZSA}_{rcv}}(\mathsf{AssetBase_{AssetId}}, \mathsf{v^{net}_{AssetId}}) = [\mathsf{v^{net}_{AssetId}}]\,\mathsf{AssetBase_{AssetId}} + [\mathsf{rcv}]\,\mathcal{R}^{\mathsf{Orchard}}\)

    where \(\mathsf{v^{net}_{AssetId}} = \mathsf{v^{old}_{AssetId}} - \mathsf{v^{new}_{AssetId}}\) - such that - \(\mathsf{v^{old}_{AssetId}}\) - and - \(\mathsf{v^{new}_{AssetId}}\) - are the values of the old and new notes of Asset Identifier - \(\mathsf{AssetId}\) - respectively,

    -

    - \(\mathsf{AssetBase_{AssetId}}\) - is defined in ZIP 227 5, and

    -

    - \(\mathcal{R}^{\mathsf{Orchard}} := \mathsf{GroupHash^{\mathbb{P}}}(\texttt{"z.cash:Orchard-cv"}, \texttt{"r"})\!\) - , as in the Orchard protocol.

    + such that

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

    For ZEC, we define \(\mathsf{AssetBase}_{\mathsf{AssetId}} := \mathcal{V}^{\mathsf{Orchard}}\) so that the value commitment for ZEC notes is computed identically to the Orchard protocol deployed in NU5 4. As such @@ -203,7 +217,7 @@ ) that is burnt in the transaction, the sender adds to \(\mathsf{assetBurn}\) the tuple - \((\mathsf{AssetBase}, \mathsf{v})\) + \((\mathsf{AssetBase}, \mathsf{v})\!\) , where \(\mathsf{v}\) is the amount of the Custom Asset the sender wants to burn. We denote by @@ -306,7 +320,7 @@ , \(\mathcal{K}^{\mathsf{Orchard}}\) is the Orchard Nullifier Base as defined in 22, and - \(\mathcal{L}^{\mathsf{Orchard}} := \mathsf{GroupHash^{\mathbb{P}}}(\texttt{"z.cash:Orchard"}, \texttt{"L"})\!\) + \(\mathcal{L}^{\mathsf{Orchard}} := \mathsf{GroupHash^{\mathbb{P}}}(\texttt{“z.cash:Orchard”}, \texttt{“L”})\!\) .

    Rationale for Split Notes

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

    @@ -384,67 +398,52 @@

    The

    Asset Identifier Consistency for Split Actions

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

      -
    • -
      -
      The Value Commitment Integrity should be changed:
      -
      -
        -
      • Replace the input note value by a generic value, - \(\mathsf{v}'\!\) - , as - \(\mathsf{cv^{net}} = \mathsf{ValueCommit_rcv^{OrchardZSA}}(\mathsf{AssetBase_{AssetId}}, \mathsf{v}' - \mathsf{v^{new}})\) -
      • -
      -
      -
      +
    • The Value Commitment Integrity should be changed: +
        +
      • Replace the input note value by a generic value, + \(\mathsf{v}'\!\) + , as + \(\mathsf{cv^{net}} = \mathsf{ValueCommit_rcv^{OrchardZSA}}(\mathsf{AssetBase_{AssetId}}, \mathsf{v}' - \mathsf{v^{new}})\) +
      • +
    • -
    • -
      -
      Add a boolean - \(\mathsf{split\_flag}\) - variable as an auxiliary witness. This variable is to be activated +
    • Add a boolean + \(\mathsf{split\_flag}\) + variable as an auxiliary witness. This variable is to be activated + \(\mathsf{split\_flag} = 1\) + if the Action in question has a Split Input and + \(\mathsf{split\_flag} = 0\) + if the Action is actually spending an input note: +
        +
      • If + \(\mathsf{split\_flag} = 1\) + then constrain + \(\mathsf{v}' = 0\) + otherwise constrain + \(\mathsf{v}' = \mathsf{v^{old}}\) + from the auxiliary input.
      • +
      • If \(\mathsf{split\_flag} = 1\) - if the Action in question has a Split Input and - \(\mathsf{split\_flag} = 0\) - if the Action is actually spending an input note:
    • -
      -
        -
      • If - \(\mathsf{split\_flag} = 1\) - then constrain - \(\mathsf{v}' = 0\) - otherwise constrain - \(\mathsf{v}' = \mathsf{v^{old}}\) - from the auxiliary input.
      • -
      • If - \(\mathsf{split\_flag} = 1\) - then constrain - \(\mathsf{is\_native\_asset} = 0\) - because split notes are only available for Custom Assets.
      • -
      -
      -
      + then constrain + \(\mathsf{is\_native\_asset} = 0\) + because split notes are only available for Custom Assets.
    • +
    -
  • -
    -
    The Merkle Path Validity should check the existence of the note commitment as usual (and not like with dummy notes):
    -
    -
      -
    • Check for all notes except dummy notes that - \((\mathsf{path}, \mathsf{pos})\) - is a valid Merkle path of depth - \(\mathsf{MerkleDepth^{Orchard}}\!\) - , from - \(\mathsf{cm^{old}}\) - to the anchor - \(\mathsf{rt^{Orchard}}\!\) - .
    • -
    • The new constraint is - \(\underbrace{(\mathsf{v^{old}} = 0 \land \mathsf{is\_native\_asset} = 1)}_\text{It is a dummy note} \lor \underbrace{(\mathsf{Valid\,Merkle\,Path})}_\text{The Merkle Path is valid}\!\) - .
    • -
    -
    -
    +
  • The Merkle Path Validity should check the existence of the note commitment as usual (and not like with dummy notes): +
      +
    • Check for all notes except dummy notes that + \((\mathsf{path}, \mathsf{pos})\) + is a valid Merkle path of depth + \(\mathsf{MerkleDepth^{Orchard}}\!\) + , from + \(\mathsf{cm^{old}}\) + to the anchor + \(\mathsf{rt^{Orchard}}\!\) + .
    • +
    • The new constraint is + \(\underbrace{(\mathsf{v^{old}} = 0 \land \mathsf{is\_native\_asset} = 1)}_\text{It is a dummy note} \lor \underbrace{(\mathsf{Valid\,Merkle\,Path})}_\text{The Merkle Path is valid}\!\) + .
    • +
  • The Nullifier Integrity will be changed to prevent the identification of notes as defined in the Split Notes section.
  • diff --git a/rendered/zip-0227.html b/rendered/zip-0227.html index 139369b2a..3039bb82a 100644 --- a/rendered/zip-0227.html +++ b/rendered/zip-0227.html @@ -3,7 +3,9 @@ ZIP 227: Issuance of Zcash Shielded Assets - + + +
    @@ -73,7 +75,7 @@

    Specification: Issuance Keys and Issuance Authorization Signature Scheme

    -

    The OrchardZSA Protocol adds the following keys to the key components 23 24:

    +

    The OrchardZSA Protocol adds the following keys to the key components 24 25:

    1. The issuance authorizing key, denoted as \(\mathsf{isk}\!\) @@ -90,7 +92,7 @@

      Issuance Authorization Signature Scheme

      We instantiate the issuance authorization signature scheme \(\mathsf{IssueAuthSig}\) - as a BIP-340 Schnorr signature over the secp256k1 curve. The signing and validation algorithms, signature encoding, and public key encoding MUST follow BIP 340 21.

      + as a BIP-340 Schnorr signature over the secp256k1 curve. The signing and validation algorithms, signature encoding, and public key encoding MUST follow BIP 340 22.

      Batch verification MAY be used. Precomputation MAY be used if and only if it produces equivalent results; for example, for a given verification key \(pk\) and @@ -102,16 +104,16 @@ signature scheme are as follows:

      • - \(\mathsf{IssueAuthSig}.\!\mathsf{Message} = \mathbb{B}^{\mathbb{Y}^{[\mathbb{N}]}}\) + \(\mathsf{IssueAuthSig.Message} = \mathbb{B}^{\mathbb{Y}^{[\mathbb{N}]}}\)
      • - \(\mathsf{IssueAuthSig}.\!\mathsf{Signature} = \mathbb{B}^{\mathbb{Y}^{[64]}} \cup \{\bot\}\) + \(\mathsf{IssueAuthSig.Signature} = \mathbb{B}^{\mathbb{Y}^{[64]}} \cup \{\bot\}\)
      • - \(\mathsf{IssueAuthSig}.\!\mathsf{Public} = \mathbb{B}^{\mathbb{Y}^{[32]}} \cup \{\bot\}\) + \(\mathsf{IssueAuthSig.Public} = \mathbb{B}^{\mathbb{Y}^{[32]}} \cup \{\bot\}\)
      • - \(\mathsf{IssueAuthSig}.\!\mathsf{Private} = \mathbb{B}^{\mathbb{Y}^{[32]}}\) + \(\mathsf{IssueAuthSig.Private} = \mathbb{B}^{\mathbb{Y}^{[32]}}\)

      where @@ -120,7 +122,7 @@ \(k\) bytes, and \(\mathbb{B}^{\mathbb{Y}^{[\mathbb{N}]}}\) - denotes the type of byte sequences of arbitrary length, as defined in the Zcash protocol specification 22.

      + denotes the type of byte sequences of arbitrary length, as defined in the Zcash protocol specification 23.

      The issuance authorizing key generation algorithm and the issuance validating key derivation algorithm are defined in the Issuance Key Derivation section, while the corresponding signing and validation algorithms are defined in the Issuance Authorization Signing and Validation section.

      Issuance Key Derivation

      @@ -130,10 +132,10 @@ context, we define the following constants:

      • - \(\mathsf{Issuance.\!MKGDomain} := \texttt{"ZcashSA_Issue_V1"}\) + \(\mathsf{Issuance.MKGDomain} := \texttt{“ZcashSA\_Issue\_V1”}\)
      • - \(\mathsf{Issuance.\!CKDDomain} := \mathtt{0x81}\!\) + \(\mathsf{Issuance.CKDDomain} := \mathtt{0x81}\)

      Let @@ -144,18 +146,18 @@

      We use hardened-only child key derivation as defined in ZIP 32 4 for the issuance authorizing key.

      \(\mathsf{CKDsk}((\mathsf{sk}_{par},\mathsf{c}_{par}), i) \rightarrow (\mathsf{sk}_{i}, \mathsf{c}_{i})\) -

      + :

      • Return - \(\mathsf{CKDh}^{\mathsf{Issuance}}((\mathsf{sk}_{par},\mathsf{c}_{par}), i)\!\) + \(\mathsf{CKDh}^{\mathsf{Issuance}}((\mathsf{sk}_{par},\mathsf{c}_{par}), i)\)

      We use the notation of ZIP 32 6 for shielded HD paths, and define the issuance authorizing key path as - \(m_{\mathsf{Issuance}} / \mathit{purpose}' / \mathit{coin\_type}' / \mathit{account}'\!\) - . We fix the path levels as follows:

      + \(m_{\mathsf{Issuance}} / \mathit{purpose}' / \mathit{coin\_type}' / \mathit{account}'.\) + We fix the path levels as follows:

      • - \(\mathit{purpose}\) + \(\mathit{purpose}\!\) : a constant set to \(227\) (i.e. @@ -166,12 +168,12 @@ \(227'\) (or \(\mathtt{0x800000e3}\!\) - ) following the BIP 43 recommendation.
      • + ) following the BIP 43 recommendation. 21
      • - \(\mathit{coin\_type}\) - : Defined as in ZIP 32 5.
      • + \(\mathit{coin\_type}\!\) + : Defined as in ZIP 32 5.
      • - \(\mathit{account}\) + \(\mathit{account}\!\) : fixed to index \(0\!\) .
      • @@ -184,7 +186,7 @@

      Derivation of issuance validating key

      Define - \(\mathsf{IssueAuthSig}.\!\mathsf{DerivePublic}\; : \; (\mathsf{isk}\; : \; \mathsf{IssueAuthSig}.\!\mathsf{Private}) \to \mathsf{IssueAuthSig}.\!\mathsf{Public}\) + \(\mathsf{IssueAuthSig.DerivePublic} \;{\small ⦂}\; (\mathsf{isk} \;{\small ⦂}\; \mathsf{IssueAuthSig.Private}) \to \mathsf{IssueAuthSig.Public}\) as:

      • @@ -200,24 +202,24 @@

      where the \(\textit{PubKey}\) - algorithm is defined in BIP 340 21. Note that the byte representation of + algorithm is defined in BIP 340 22. Note that the byte representation of \(\mathsf{ik}\) is in big-endian order as defined in BIP 340.

      It is possible for the \(\textit{PubKey}\) algorithm to fail with very low probability, which means that - \(\mathsf{IssueAuthSig}.\!\mathsf{DerivePublic}\) + \(\mathsf{IssueAuthSig.DerivePublic}\) could return \(\bot\) with very low probability. If this happens, discard the keys and repeat with a different \(\mathsf{isk}\!\) .

      -

      This allows the issuer to use the same wallet it usually uses to transfer Assets, while keeping a disconnect from the other keys. Specifically, this method is aligned with the requirements and motivation of ZIP 32 2. It provides further anonymity and the ability to delegate issuance of an Asset (or in the future, generate a multi-signature protocol) while the rest of the keys remain in the wallet safe.

      +

      This allows the issuer to use the same wallet it usually uses to transfer Assets, while keeping a disconnect from the other keys. Specifically, this method is aligned with the requirements and motivation of ZIP 32 2. It provides further anonymity and the ability to delegate issuance of an Asset (or in the future, generate a multi-signature protocol) while the rest of the keys remain in the wallet safe.

    Issuance Authorization Signing and Validation

    Define - \(\mathsf{IssueAuthSig}.\!\mathsf{Sign}\; : \; (\mathsf{isk}\; : \; \mathsf{IssueAuthSig}.\!\mathsf{Private}) \times (M\; : \; \mathsf{IssueAuthSig}.\!\mathsf{Message}) \to \mathsf{IssueAuthSig}.\!\mathsf{Signature}\) + \(\mathsf{IssueAuthSig.Sign} \;{\small ⦂}\; (\mathsf{isk} \;{\small ⦂}\; \mathsf{IssueAuthSig.Private}) \times (M \;{\small ⦂}\; \mathsf{IssueAuthSig.Message}) \to \mathsf{IssueAuthSig.Signature}\) as:

    • Let the auxiliary data @@ -238,13 +240,13 @@ \(\mathsf{Sign}\) algorithm is defined in BIP 340 and \(a\) - denotes the auxiliary data used in BIP 340 21. Note that - \(\mathsf{IssueAuthSig}.\!\mathsf{Sign}\) + denotes the auxiliary data used in BIP 340 22. Note that + \(\mathsf{IssueAuthSig.Sign}\) could return \(\bot\) with very low probability.

      Define - \(\mathsf{IssueAuthSig}.\!\mathsf{Validate}\; : \; (\mathsf{ik}\; : \; \mathsf{IssueAuthSig}.\!\mathsf{Public}) \times (M\; : \; \mathsf{IssueAuthSig}.\!\mathsf{Message}) \times (\text{σ}\; : \; \mathsf{IssueAuthSig}.\!\mathsf{Signature}) \to \mathbb{B}\) + \(\mathsf{IssueAuthSig.Validate} \;{\small ⦂}\; (\mathsf{ik} \;{\small ⦂}\; \mathsf{IssueAuthSig.Public}) \times (M \;{\small ⦂}\; \mathsf{IssueAuthSig.Message}) \times (\text{σ} \;{\small ⦂}\; \mathsf{IssueAuthSig.Signature}) \to \mathbb{B}\) as:

      • Return @@ -262,7 +264,7 @@

      where the \(\mathsf{Verify}\) - algorithm is defined in BIP 340 21.

      + algorithm is defined in BIP 340 22.

    Specification: Asset Identifier

    @@ -290,7 +292,7 @@ be the issuance validating key of the issuer, a public key used to verify the signature on the issuance transaction's SIGHASH.

    Define - \(\mathsf{AssetDigest_{AssetId}} := \textsf{BLAKE2b-512}(\texttt{"ZSA-Asset-Digest"},\; \mathsf{EncodeAssetId}(\mathsf{AssetId}))\!\) + \(\mathsf{AssetDigest_{AssetId}} := \textsf{BLAKE2b-512}(\texttt{“ZSA-Asset-Digest”},\; \mathsf{EncodeAssetId}(\mathsf{AssetId}))\!\) , where

    • @@ -307,7 +309,7 @@ \(\mathsf{ZSAValueBase}(\mathsf{AssetDigest_{AssetId}}) := \mathsf{GroupHash}^\mathbb{P}(\texttt{"z.cash:OrchardZSA"}, \mathsf{AssetDigest_{AssetId}})\) where \(\mathsf{GroupHash}^\mathbb{P}\) - is defined as in 26.

      + is defined as in 27.

      The relations between the Asset Identifier, Asset Digest, and Asset Base are shown in the following diagram:

      @@ -347,25 +349,25 @@

      The \(\mathsf{finalize}\) boolean is set by the Issuer to signal that there will be no further issuance of the specific Custom Asset. As we will see in Specification: Consensus Rule Changes, transactions that attempt to issue further amounts of a Custom Asset that has previously been finalized will be rejected.

      -

      The complete encoding of these fields into an IssueAction is defined in ZIP 230 15.

      +

      The complete encoding of these fields into an IssueAction is defined in ZIP 230 15.

      We note that the output note commitment of the recipient's notes are not included in the actual transaction, but when added to the global state of the chain, they will be added to the note commitment tree as a shielded note. This prevents future usage of the note from being linked to the issuance transaction, as the nullifier key is not known to the validators and chain observers.

    Issuance Bundle

    An issuance bundle is the aggregate of all the issuance-related information. Specifically, contains all the issuance actions and the issuer signature on the transaction SIGHASH that validates the issuance itself. It contains the following fields:

    • - \(\mathsf{ik}\) + \(\mathsf{ik}\!\) : the issuance validating key, that allows the validators to verify that the \(\mathsf{AssetId}\) is properly associated with the issuer.
    • vIssueActions: an array of issuance actions, of type IssueAction.
    • - \(\mathsf{issueAuthSig}\) + \(\mathsf{issueAuthSig}\!\) : the signature of the transaction SIGHASH, signed by the issuance authorizing key, \(\mathsf{isk}\!\) , that validates the issuance.
    -

    The issuance bundle is added within the transaction format as a new bundle. The detailed encoding of the issuance bundle as a part of the V6 transaction format is defined in ZIP 230 16.

    +

    The issuance bundle is added within the transaction format as a new bundle. The detailed encoding of the issuance bundle as a part of the V6 transaction format is defined in ZIP 230 16.

    Issuance Protocol

    The issuer program performs the following operations:

    @@ -396,7 +398,7 @@ \(\mathsf{finalize} = 1\!\) ).
  • for each recipient - \(i\) + \(i\!\) :
    • generate a ZSA output note that includes the Asset Base. For an OrchardZSA note this is @@ -424,9 +426,9 @@

      Specification: Global Issuance State

      Issuance requires the following additions to the global state:

      A map, - \(\mathsf{issued\_assets} : \mathbb{P}^* \to \{0 .. \mathsf{MAX\_ISSUE}\} \times \mathbb{B} \!\) + \(\mathsf{issued\_assets} : \mathbb{P}^* \to \{0 .. \mathsf{MAX\_ISSUE}\} \times \mathbb{B}\!\) , from the Asset Base, - \(\mathsf{AssetBase} : \mathbb{P}^*\) + \(\mathsf{AssetBase} : \mathbb{P}^*\!\) , to a tuple \((\mathsf{balance}, \mathsf{final})\!\) , for every Asset that has been issued. We use the notation @@ -466,7 +468,7 @@ .

    The maximum total supply of any issued Custom Asset is denoted by the constant - \(\mathsf{MAX\_ISSUE} := 2^{64} - 1 \!\) + \(\mathsf{MAX\_ISSUE} := 2^{64} - 1\!\) .

    Management of the Global Issuance State

    The issuance state, that is, the @@ -481,7 +483,7 @@

    We describe the consensus rule changes that govern the management of the global issuance state in the Specification: Consensus Rule Changes section. We use \(\mathsf{issued\_assets}_{\mathsf{IN}}\) and - \(\mathsf{issued\_assets}_{\mathsf{OUT}}\!\) + \(\mathsf{issued\_assets}_{\mathsf{OUT}}\) to denote the input issuance state and output issuance state for a transaction, respectively.

  • @@ -493,7 +495,7 @@ .
  • The \(\mathsf{assetBurn}\) - set MUST satisfy the consensus rules specified in ZIP 226 12.
  • + set MUST satisfy the consensus rules specified in ZIP 226 12.
  • It MUST be the case that for all \((\mathsf{AssetBase}, \mathsf{v}) \in \mathsf{assetBurn}\!\) , @@ -507,7 +509,7 @@ .
  • Let \(\mathsf{SigHash}\) - be the SIGHASH transaction hash of this transaction, as defined in §4.10 of the protocol specification 25 with the modifications described in ZIP 226 13, using + be the SIGHASH transaction hash of this transaction, as defined in §4.10 of the protocol specification 26 with the modifications described in ZIP 226 13, using \(\mathsf{SIGHASH\_ALL}\!\) .
  • The issuance authorization signature, @@ -520,7 +522,7 @@ \(\mathsf{IssueAuthSig}.\!\mathsf{Validate}(\mathsf{ik}, \mathsf{SigHash}, \mathsf{issueAuthSig}) = 1\!\) .
  • For every issuance action description ( - \(\!\mathsf{IssueAction}_\mathsf{i},\ 1 \leq i \leq \mathtt{nIssueActions}\!\) + \(\mathsf{IssueAction}_\mathsf{i},\ 1 \leq i \leq \mathtt{nIssueActions}\!\) ) in the issuance bundle:
    • It MUST be the case that @@ -532,7 +534,7 @@ \(\mathtt{assetDescSize}\) bytes.
    • Elements of every issue note description in IssueAction MUST be valid encodings of the types given in Issue Note Description, and MUST encode the same - \(\mathsf{AssetBase}\) + \(\mathsf{AssetBase}\!\) .
    • This \(\mathsf{AssetBase}\) @@ -541,7 +543,7 @@ \(\mathsf{issued\_assets}_{\mathsf{OUT}}(\mathsf{AssetBase}).\!\mathsf{final} \neq 1\!\) .
    • For every issue note description ( - \(\!\mathsf{note}_{\mathsf{j}},\ 1 \leq j \leq \mathtt{nNotes}\!\) + \(\mathsf{note}_{\mathsf{j}},\ 1 \leq j \leq \mathtt{nNotes}\!\) ) in IssueAction:
      • It MUST be the case that @@ -549,13 +551,13 @@ , where \(\mathsf{v}\) is the value of - \(\mathsf{note}_{\mathsf{j}}\) + \(\mathsf{note}_{\mathsf{j}}\!\) . The node then MUST update \(\mathsf{issued\_assets}_{\mathsf{OUT}}.\!\mathsf{balance} = \mathsf{issued\_assets}_{\mathsf{OUT}}.\!\mathsf{balance} + \mathsf{v}\!\) .
      • The node MUST compute the note commitment, \(\mathsf{cm}_{\mathsf{i,j}}\!\) - , as defined in the Note Structure and Commitment section of ZIP 226 11.
      • + , as defined in the Note Structure and Commitment section of ZIP 226 11.
    • If @@ -592,9 +594,9 @@
    • We require non-zero fees in the presence of an issue bundle, in order to preclude the possibility of a transaction containing only an issue bundle. If a transaction includes only an issue bundle, the SIGHASH transaction hash would be computed solely based on the issue bundle. A duplicate bundle would have the same SIGHASH transaction hash, potentially allowing for a replay attack.

    Rationale for Global Issuance State

    -

    It is necessary to ensure that the balance of any issued Custom Asset never becomes negative within a shielded pool, along the lines of ZIP 209 8. However, unlike for the shielded ZEC pools, there is no individual transaction field that directly corresponds to both the issued and burnt amounts for a given Asset. Therefore, we require that all nodes maintain a record of the current amount in circulation for every issued Custom Asset, and update this record based on the issuance and burn transactions processed. This allows for efficient detection of balance violations for any Asset, in which scenario we specify a consensus rule to reject the transaction or block.

    +

    It is necessary to ensure that the balance of any issued Custom Asset never becomes negative within a shielded pool, along the lines of ZIP 209 8. However, unlike for the shielded ZEC pools, there is no individual transaction field that directly corresponds to both the issued and burnt amounts for a given Asset. Therefore, we require that all nodes maintain a record of the current amount in circulation for every issued Custom Asset, and update this record based on the issuance and burn transactions processed. This allows for efficient detection of balance violations for any Asset, in which scenario we specify a consensus rule to reject the transaction or block.

    We limit the total issuance of any Asset to a maximum of - \(\mathsf{MAX\_ISSUE}\) + \(\mathsf{MAX\_ISSUE}\!\) . This is a practical limit that also allows an issuer to issue the complete supply of an Asset in a single transaction.

    Nodes also need to reject transactions that issue Custom Assets that have been previously finalized. The \(\mathsf{issued\_assets}\) @@ -605,7 +607,7 @@

    • By using the \(\mathsf{finalize}\) - boolean and the burning mechanism defined in 10, issuers can control the supply production of any Asset associated to their issuer keys. For example, + boolean and the burning mechanism defined in 10, issuers can control the supply production of any Asset associated to their issuer keys. For example,
      • by setting \(\mathsf{finalize} = 1\) @@ -638,7 +640,7 @@
  • TxId Digest - Issuance

    -

    This section details the construction of the subtree of hashes in the transaction digest that corresponds to issuance transaction data. Details of the overall changes to the transaction digest due to the OrchardZSA protocol can be found in ZIP 226 13. As in ZIP 244 18, the digests are all personalized BLAKE2b-256 hashes, and in cases where no elements are available for hashing, a personalized hash of the empty byte array is used.

    +

    This section details the construction of the subtree of hashes in the transaction digest that corresponds to issuance transaction data. Details of the overall changes to the transaction digest due to the OrchardZSA protocol can be found in ZIP 226 13. As in ZIP 244 18, the digests are all personalized BLAKE2b-256 hashes, and in cases where no elements are available for hashing, a personalized hash of the empty byte array is used.

    A new issuance transaction digest algorithm is defined that constructs the subtree of the transaction digest tree of hashes for the issuance portion of a transaction. Each branch of the subtree will correspond to a specific subset of issuance transaction data. The overall structure of the hash is as follows; each name referenced here will be described in detail below:

    issuance_digest
     ├── issue_actions_digest
    @@ -674,7 +676,7 @@
                             

    In case the transaction has no Issue Notes, ''issue_notes_digest'' is:

    BLAKE2b-256("ZTxIdIAcNoteHash", [])
    T.5a.i.1: recipient
    -

    This is the raw encoding of an Orchard shielded payment address as defined in the protocol specification 27.

    +

    This is the raw encoding of an Orchard shielded payment address as defined in the protocol specification 28.

    T.5a.i.2: value

    Note value encoded as little-endian 8-byte representation of 64-bit unsigned integer (e.g. u64 in Rust) raw value.

    @@ -708,7 +710,7 @@

    Signature Digest

    -

    The per-input transaction digest algorithm to generate the signature digest in ZIP 244 19 is modified so that a signature digest is produced for each transparent input, each Sapling input, each Orchard action, and additionally for each Issuance Action. For Issuance Actions, this algorithm has the exact same output as the transaction digest algorithm, thus the txid may be signed directly.

    +

    The per-input transaction digest algorithm to generate the signature digest in ZIP 244 19 is modified so that a signature digest is produced for each transparent input, each Sapling input, each Orchard action, and additionally for each Issuance Action. For Issuance Actions, this algorithm has the exact same output as the transaction digest algorithm, thus the txid may be signed directly.

    The overall structure of the hash is as follows. We highlight the changes for the OrchardZSA protocol via the [ADDED FOR ZSA] text label, and we omit the descriptions of the sections that do not change for the OrchardZSA protocol:

    signature_digest
     ├── header_digest
    @@ -723,14 +725,14 @@
     S.3: sapling_digest         (32-byte hash output)
     S.4: orchard_digest         (32-byte hash output)
     S.5: issuance_digest        (32-byte hash output)  [ADDED FOR ZSA]
    -

    The personalization field remains the same as in ZIP 244 18.

    +

    The personalization field remains the same as in ZIP 244 18.

    S.5: issuance_digest

    Identical to that specified for the transaction identifier.

    Authorizing Data Commitment - Issuance

    -

    This section covers the construction of the subtree of hashes in the authorizing data commitment that corresponds to issuance transaction data. Details of the overall changes to the authorizing data commitment due to the OrchardZSA protocol can be found in ZIP 226 14.

    +

    This section covers the construction of the subtree of hashes in the authorizing data commitment that corresponds to issuance transaction data. Details of the overall changes to the authorizing data commitment due to the OrchardZSA protocol can be found in ZIP 226 14.

    A.4: issuance_auth_digest

    In the case that Issuance Actions are present, this is a BLAKE2b-256 hash of the field encoding of the issueAuthSig field of the transaction:

    A.4a: issueAuthSig            (field encoding bytes)
    @@ -741,7 +743,7 @@

    OrchardZSA Fee Calculation

    -

    In addition to the parameters defined in the Fee calculation section of ZIP 317 20, the OrchardZSA protocol upgrade defines the following additional parameters:

    +

    In addition to the parameters defined in the Fee calculation section of ZIP 317 20, the OrchardZSA protocol upgrade defines the following additional parameters:

    @@ -761,7 +763,7 @@

    Wallets implementing this specification SHOULD use a conventional fee, viz. - \(zsa\_conventional\_fee\) + \(zsa\_conventional\_fee\!\) , that is calculated in zatoshis. Additional definitions that are used in the formula for the calculation are in the table below:

    @@ -795,10 +797,10 @@
    -

    The other inputs to this formula are taken from transaction fields defined in the Zcash protocol specification 28 and the global state. They are defined in the Fee calculation section of ZIP 317 20. Note that - \(nOrchardActions\) +

    The other inputs to this formula are taken from transaction fields defined in the Zcash protocol specification 29 and the global state. They are defined in the Fee calculation section of ZIP 317 20. Note that + \(nOrchardActions\!\) , that is used in the computation of - \(logical\_actions\) + \(logical\_actions\!\) , is redefined in the above table, and now combines the actions for native ZEC as well as OrchardZSA transfer actions for Custom Assets.

    The formula for the computation of the \(zsa\_logical\_actions\) @@ -840,7 +842,7 @@

    Bridging Assets

    -

    For bridging purposes, the secure method of off-boarding Assets is to burn an Asset with the burning mechanism in ZIP 226 10. Users should be aware of issuers that demand the Assets be sent to a specific address on the Zcash chain to be redeemed elsewhere, as this may not reflect the real reserve value of the specific Wrapped Asset.

    +

    For bridging purposes, the secure method of off-boarding Assets is to burn an Asset with the burning mechanism in ZIP 226 10. Users should be aware of issuers that demand the Assets be sent to a specific address on the Zcash chain to be redeemed elsewhere, as this may not reflect the real reserve value of the specific Wrapped Asset.

    Other Considerations

    @@ -854,7 +856,7 @@ in order to properly keep track of the total supply for different Asset Identifiers. This is useful for wallets and other applications that need to keep track of the total supply of Assets.

    Fee Structures

    -

    The fee mechanism described in this ZIP will follow the mechanism described in ZIP 317, and is described in ZIP 230 17.

    +

    The fee mechanism described in this ZIP will follow the mechanism described in ZIP 317, and is described in ZIP 230 17.

    Test Vectors

    @@ -1032,10 +1034,18 @@ - +
    + + + +
    21BIP 43: Purpose Field for Deterministic Wallets
    + + + + @@ -1043,7 +1053,7 @@
    22 BIP 340: Schnorr Signatures for secp256k1
    - + @@ -1051,7 +1061,7 @@
    2223 Zcash Protocol Specification, Version 2024.5.1 [NU6]. Section 2: Notation
    - + @@ -1059,7 +1069,7 @@
    2324 Zcash Protocol Specification, Version 2024.5.1 [NU6]. Section 3.1: Payment Addresses and Keys
    - + @@ -1067,7 +1077,7 @@
    2425 Zcash Protocol Specification, Version 2024.5.1 [NU6]. Section 4.2.3: Orchard Key Components
    - + @@ -1075,7 +1085,7 @@
    2526 Zcash Protocol Specification, Version 2024.5.1 [NU6]. Section 4.10: SIGHASH Transaction Hashing
    - + @@ -1083,7 +1093,7 @@
    2627 Zcash Protocol Specification, Version 2024.5.1 [NU6]. Section 5.4.9.8: Group Hash into Pallas and Vesta
    - + @@ -1091,7 +1101,7 @@
    2728 Zcash Protocol Specification, Version 2024.5.1 [NU6]. Section 5.6.4.2: Orchard Raw Payment Addresses
    - + diff --git a/rendered/zip-0230.html b/rendered/zip-0230.html index 9877595db..0373bee5f 100644 --- a/rendered/zip-0230.html +++ b/rendered/zip-0230.html @@ -3,7 +3,9 @@ ZIP 230: Version 6 Transaction Format - + + +
    @@ -36,18 +38,18 @@

    Abstract

    This proposal defines a new Zcash peer-to-peer transaction format, which includes data that supports the OrchardZSA protocol and all operations related to Zcash Shielded Assets (ZSAs). The new format adds and describes new fields containing ZSA-specific elements. Like the existing v5 transaction format, it keeps well-bounded regions of the serialized form to serve each pool of funds.

    This ZIP also depends upon and defines modifications to the computation of the values TxId Digest, Signature Digest, and Authorizing Data Commitment defined by ZIP 244 11.

    -

    This ZIP additionally defines the fee mechanism associated with the Orchard Zcash Shielded Assets (OrchardZSA) protocol as described in ZIP 226 8 and ZIP 227 9. The fee mechanism is defined in terms of modifications to the Proportionak Transfer Fee Mechanism 12.

    +

    This ZIP additionally defines the fee mechanism associated with the Orchard Zcash Shielded Assets (OrchardZSA) protocol as described in ZIP 226 8 and ZIP 227 9. The fee mechanism is defined in terms of modifications to the Proportionak Transfer Fee Mechanism 13.

    Motivation

    The OrchardZSA protocol requires serialized data elements that are distinct from any previous Zcash transaction. Since ZIP 244 was activated in NU5, the v5 and later serialized transaction formats are not consensus-critical. Thus, this ZIP defines format that can easily accommodate future extensions, where elements or a given pool are kept separate.

    -

    The upgrade to the OrchardZSA protocol will also need to define a fee structure consistent with the objectives of ZIP 317 12. This involves adaptation for the transfer protocol 8, as well as additional considerations for the issuance protocol 9 such as fees for asset issuance. Specifically, the OrchardZSA Transfer and Burn mechanism should follow the same fee mechanism in order to not discriminate between transfer bundle types. When it comes to Issuance of ZSA, however, there should be a disincentive that will stop users from flooding the chain with useless asset identifiers. In the case of Issuance, the computational power needed to verify the bundle is not large. The transaction size, however, can be an issue as the number of output notes can be large. Furthermore, as defined in ZIP 227 9, there is an additional data structure in the global state that needs to be maintained as part of the consensus. This motivates further the addition of an Issuance-specific fee.

    +

    The upgrade to the OrchardZSA protocol will also need to define a fee structure consistent with the objectives of ZIP 317 13. This involves adaptation for the transfer protocol 8, as well as additional considerations for the issuance protocol 9 such as fees for asset issuance. Specifically, the OrchardZSA Transfer and Burn mechanism should follow the same fee mechanism in order to not discriminate between transfer bundle types. When it comes to Issuance of ZSA, however, there should be a disincentive that will stop users from flooding the chain with useless asset identifiers. In the case of Issuance, the computational power needed to verify the bundle is not large. The transaction size, however, can be an issue as the number of output notes can be large. Furthermore, as defined in ZIP 227 9, there is an additional data structure in the global state that needs to be maintained as part of the consensus. This motivates further the addition of an Issuance-specific fee.

    Requirements

    The new format must fully support the OrchardZSA protocol.

    The new format should lend itself to future extension or pruning to add or remove value pools.

    The computation of the non-malleable transaction identifier hash must include all newly incorporated elements except those that attest to transaction validity.

    The computation of the commitment to authorizing data for a transaction must include all newly incorporated elements that attest to transaction validity.

    -

    In addition to the requirements of ZIP 317 12, the fee mechanism for the OrchardZSA protocol should satisfy the following requirements:

    +

    In addition to the requirements of ZIP 317 13, the fee mechanism for the OrchardZSA protocol should satisfy the following requirements:

    • The conventional fee should not leak private information used in constructing the transaction; that is, it should be computable from only the public data of the transaction.
    • Users should be discouraged from issuing new “garbage” custom Assets. The fee should reflect the cost of adding new data to the global state.
    • @@ -281,7 +283,7 @@
    • The fields valueBalanceSapling and bindingSigSapling are present if and only if \(\mathtt{nSpendsSapling} + \mathtt{nOutputsSapling} > 0\!\) . If valueBalanceSapling is not present, then - \(\mathsf{v^{balanceSapling}}`\) + \(\mathsf{v^{balanceSapling}}\) is defined to be \(0\!\) .
    • @@ -661,6 +663,9 @@
    2829 Zcash Protocol Specification, Version 2024.5.1 [NU6]. Section 7.1: Transaction Encoding and Consensus
    +

    Deployment

    +

    Version 6 transactions are proposed to be allowed on the network starting from Network Upgrade 7. 12

    +

    Reference implementation

    TODO

    @@ -753,10 +758,18 @@ - +
    + + + +
    12ZIP 254: Deployment of the NU7 Network Upgrade
    + + + + @@ -764,7 +777,7 @@
    13 ZIP 317: Proportional Transfer Fee Mechanism
    - + diff --git a/rendered/zip-0231.html b/rendered/zip-0231.html index c0607bf03..54e094867 100644 --- a/rendered/zip-0231.html +++ b/rendered/zip-0231.html @@ -3,7 +3,9 @@ ZIP 231: Memo Bundles - + + + @@ -19,709 +21,730 @@ Category: Consensus / Wallet Created: 2024-04-26 License: MIT -Discussions-To: <https://github.com/zcash/zips/issues/627> -

    Terminology

    -

    The key words “MUST”, “MUST NOT”, “SHOULD”, and “MAY” in this -document are to be interpreted as described in BCP 14 1 -when, and only when, they appear in all capitals.

    -

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

    -

    Abstract

    -

    Currently, the memo sent in a shielded output is limited to at most -512 bytes. This ZIP proposes to allow larger memos, and to enable memo -data to be shared between multiple recipients of a transaction.

    -

    Motivation

    -

    In Zcash transaction versions v2 to v5 inclusive, each Sapling or -Orchard shielded output contains a ciphertext comprised of a 52-byte -note plaintext, and a corresponding 512-byte memo field. 3 -Recipients can only decrypt the outputs sent to them, and thus can also -only observe the memo fields included with the outputs they can -decrypt.

    -

    The shielded transaction protocol hides the sender(s) (that is, the -addresses corresponding to the keys used to spend the input notes) from -all of the recipients. For certain kinds of transactions, it is -desirable to make one or more sender addresses available to one or more -recipients (for example, a reply address). In such circumstances it is -important to authenticate the sender addresses, to give the recipient a -guarantee that the address is controlled by a sender of the transaction; -failure to authenticate this address can enable phishing attacks. These -Authenticated Reply Addresses require zero-knowledge proofs, and for the -Orchard protocol these proofs are too large to fit into a 512-byte memo -field.

    -

    It is also desirable, for clients with more stringent bandwidth -constraints, to be able to transmit encrypted notes to the client -without including the encrypted memo data. In the current light client -protocol 4, this is done by truncating the note -ciphertext to just the part that encrypts the memo. However, that has -the effect of truncating the authentication tag, and so the resulting -decryption algorithm does not meet standard security notions for an -authenticated encryption scheme. It is a goal of this proposal to +Discussions-To: <https://github.com/zcash/zips/issues/627> + + +

    Terminology

    + +

    The key words “MUST”, “MUST NOT”, “SHOULD”, and “MAY” in this document are to +be interpreted as described in BCP 14 1 when, and only when, they appear +in all capitals.

    + +

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

    + +

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

    + +

    The terms “Mainnet” and “Testnet” are to be interpreted as described in +§ 3.12 ‘Mainnet and Testnet’. 4

    + +

    Abstract

    + +

    Currently, the memo sent in a shielded output is limited to at most 512 bytes. +This ZIP proposes to allow larger memos, and to enable memo data to be shared +between multiple recipients of a transaction.

    + +

    Motivation

    + +

    In Zcash transaction versions v2 to v5 inclusive, each Sapling or Orchard +shielded output contains a ciphertext comprised of a 52-byte note plaintext, +and a corresponding 512-byte memo field. 5 Recipients +can only decrypt the outputs sent to them, and thus can also only observe the +memo fields included with the outputs they can decrypt.

    + +

    The shielded transaction protocol hides the sender(s) (that is, the addresses +corresponding to the keys used to spend the input notes) from all of the +recipients. For certain kinds of transactions, it is desirable to make one or +more sender addresses available to one or more recipients (for example, a reply +address). In such circumstances it is important to authenticate the sender +addresses, to give the recipient a guarantee that the address is controlled by +a sender of the transaction; failure to authenticate this address can enable +phishing attacks. These Authenticated Reply Addresses require zero-knowledge +proofs, and for the Orchard protocol these proofs are too large to fit into a +512-byte memo field.

    + +

    It is also desirable, for clients with more stringent bandwidth constraints, +to be able to transmit encrypted notes to the client without including the +encrypted memo data. In the current light client protocol 6, this +is done by truncating the note ciphertext to just the part that encrypts the +memo. However, that has the effect of truncating the authentication tag, and +so the resulting decryption algorithm does not meet standard security notions +for an authenticated encryption scheme. It is a goal of this proposal to rectify this, simplifying the security argument.

    -

    Instead of the memo data, this ZIP proposes that it is possible to -indicate whether a memo is present for the recipient. When using the -light client protocol, a recipient need not download full transaction -information if this indication tells them that they have not received -any memo in the transaction.

    -

    At present, it is not possible to transmit the same memo data to -multiple transaction recipients without redundantly encoding that data, -and sending memo data greater than 512 bytes requires sending multiple -outputs; the problem is compounded when attempting to send more than 512 -bytes to each recipient. By separating memo data from the decryption -capability for those memos, it admits a greater variety of applications -that utilize memo data, while decreasing the amount of data that needs -to be stored on-chain overall.

    -

    Requirements

    + +

    Instead of the memo data, this ZIP proposes that it is possible to indicate whether +a memo is present for the recipient. When using the light client protocol, a recipient +need not download full transaction information if this indication tells them that they +have not received any memo in the transaction.

    + +

    At present, it is not possible to transmit the same memo data to multiple +transaction recipients without redundantly encoding that data, and sending +memo data greater than 512 bytes requires sending multiple outputs; the +problem is compounded when attempting to send more than 512 bytes to each +recipient. By separating memo data from the decryption capability for those +memos, it admits a greater variety of applications that utilize memo data, +while decreasing the amount of data that needs to be stored on-chain overall.

    + +

    Requirements

    +
      -
    • Recipients can receive memo data that is greater than 512 bytes in -length.
    • -
    • Multiple recipients, across any of the shielded pools, can be given -the capability to view the same memo data.
    • -
    • The exact number and exact lengths of distinct decryptable memos -should not be revealed, even to the transaction recipients, although an -upper bound on the total length of memo data that the observer does not -have the capability to view will be leaked to transaction recipients, -and the overall maximum possible length of memo data will be revealed -on-chain.
    • -
    • A recipient can determine whether or not they have been given the -capability to view any memo solely by decrypting the note -ciphertext.
    • -
    • Memo chunks within a transaction can be individually pruned from -block storage without preventing the transaction from being verified -when transmitting block data to peers.
    • -
    • The ciphertext of the note alone can be decrypted using a scheme -that meets a standard security notion for authenticated encryption, -without more than a small constant overhead in ciphertext size.
    • +
    • Recipients can receive memo data that is greater than 512 bytes in length.
    • +
    • Multiple recipients, across any of the shielded pools, can be given the +capability to view the same memo data.
    • +
    • The exact number and exact lengths of distinct decryptable memos should not +be revealed, even to the transaction recipients, although an upper bound on +the total length of memo data that the observer does not have the capability +to view will be leaked to transaction recipients, and the overall maximum +possible length of memo data will be revealed on-chain.
    • +
    • A recipient can determine whether or not they have been given the capability +to view any memo solely by decrypting the note ciphertext.
    • +
    • Memo chunks within a transaction can be individually pruned from block storage +without preventing the transaction from being verified when transmitting block +data to peers.
    • +
    • The ciphertext of the note alone can be decrypted using a scheme that meets +a standard security notion for authenticated encryption, without more than a +small constant overhead in ciphertext size.
    -

    Non-requirements

    + +

    Non-requirements

    +
      -
    • Recipients do not need to be able to receive multiple memos per -note. This capability can however be enabled under the existing proposal -by “chaining” memos, including the decryption key for another memo -within the memo that is decryptabble by a recipient.
    • +
    • Recipients do not need to be able to receive multiple memos per note. This +capability can however be enabled under the existing proposal by “chaining” +memos, including the decryption key for another memo within the memo that +is decryptable by a recipient.
    -

    Specification

    -

    Since this proposal is defined only for v6 and later transactions, it -is not necessary to consider Sprout JoinSplit outputs. The following -sections apply to both Sapling and Orchard outputs.

    -

    Changes to the -Zcash Protocol Specification

    -

    The following changes affecting the definitions of note plaintexts -and note ciphertexts, and the algorithms for encryption and -decryption.

    + +

    Specification

    + +

    Since this proposal is defined only for v6 and later transactions, it is not +necessary to consider Sprout JoinSplit outputs. The following sections apply +to both Sapling and Orchard outputs.

    + +

    Memo bundle

    + +

    A memo bundle consists of a sequence of 256-byte memo chunks, each individually +encrypted. These memo chunks represent zero or more encrypted memos.

    + +

    Each transaction may contain a single memo bundle, and a memo bundle may contain +at most memo_chunk_limit memo chunks. This limits the total amount of memo data +that can be conveyed within a single transaction to memo_chunk_limit * 256 bytes.

    + +

    memo_chunk_limit is a parameter to this specification, to be decided upon +by the community. The authors of this ZIP propose a maximum of 64 chunks, +resulting in a maximum total memo data length of 16 KiB.

    + +

    Memo bundles are encoded in transactions in a prunable manner: each memo chunk +can be replaced by its representative digest.

    + +

    Memo encryption

    + +

    During transaction construction, each output with memo data is assigned a 32-byte +memo key \(\mathsf{K^{memo}}\). These keys SHOULD be generated randomly, and MUST NOT +be used to encrypt more than one memo within a single transaction. If an output has +no memo data, it is assigned the memo key consisting of 32 \(\mathtt{0xFF}\) bytes.

    + +

    In note plaintexts of v6-onward transactions, the 512-byte memo field is replaced +by \(\mathsf{K^{memo}}\).

    + +

    The transaction builder generates a 32-byte salt value \(\mathsf{salt}\) from a CSPRNG. +A new salt MUST be generated for each memo bundle.

    + +

    The symmetric encryption key for a memo is derived from its \(\mathsf{K^{memo}}\) as follows:

    + +

    \(\hspace{2em}\mathsf{encryption\_key} = \mathsf{PRF^{expand}_{K^{memo}}}([\mathtt{0xE0}] \,||\, \mathsf{salt})\)

    + +

    The first byte \(\mathtt{0xE0}\) should be added to the documentation of inputs to +\(\mathsf{PRF^{expand}}\) in § 4.1.2 ‘Pseudo Random Functions’ 7.

    + +

    If the generated key is 32 \(\mathtt{0xFF}\) bytes, the transaction constructor MAY +repeat this procedure with a different salt, in order to avoid the recipient +misinterpreting the output as having no memo data. Since that has negligible +probability, it alternatively MAY omit this check.

    + +

    Each memo is padded to a multiple of 256 bytes with zeroes, and split into +256-byte chunks. Each memo chunk is encrypted with ChaCha20Poly1305 8 +as follows:

    + +

    \(\hspace{2em}\mathsf{IETF\_AEAD\_CHACHA20\_POLY1305}(\mathsf{encryption\_key}, \mathsf{nonce}, \mathsf{memo\_chunk})\)

    + +

    where \(\mathsf{nonce} = \mathsf{I2BEOSP}_{88}(\mathsf{counter}) \,||\, [\mathsf{final\_chunk}]\).

    + +

    This is a variant of the STREAM construction 9.

    + +
      +
    • \(\mathsf{counter}\) is a big-endian chunk counter starting at zero and incrementing +by one for each subsequent chunk within a particular memo.
    • +
    • \(\mathsf{final\_chunk}\) is the byte \(\mathtt{0x01}\) for the final memo chunk, and +\(\mathtt{0x00}\) for all preceding chunks.
    • +
    + +

    Finally, the encrypted memo chunks for all memos are combined into a single +sequence using an order-preserving shuffle. Memo chunks from different memos MAY +be interleaved in any order, but memo chunks from the same memo MUST have the +same relative order. The following diagram shows an example shuffle of three +memos:

    + +
    [
    +    (memo_a, 0),
    +    (memo_b, 0),
    +    (memo_a, 1),
    +    (memo_c, 0),
    +    (memo_c, 1),
    +    (memo_a, 2),
    +]
    +
    + +

    Memo decryption

    + +

    When a recipient decrypts a shielded output, they obtain a memo key \(\mathsf{K^{memo}}\). +From this they derive encryption_key as above, and then proceed as follows:

    + +
      +
    • Set counter = 0 and final_chunk = 0x00.
    • +
    • Attempt to decrypt each memo chunk in order. Pruned memo chunks are skipped.
    • +
    • Each time decryption succeeds for a memo chunk, increment counter by 1, and +then continue attempting to decrypt subsequent chunks.
    • +
    • Once all memo chunks have been trial-decrypted once, set final_chunk = 0x01 +and then attempt to decrypt the memo chunks again, starting immediately after +the last successfully-decrypted chunk (or at the start if none were), and +without incrementing counter.
    • +
    • This step can be made secret-independent by attempting to decrypt every memo +chunk again, and ignoring the results of all chunks up to and including the +last successfully-decrypted chunk.
    • +
    • If no memo chunk decrypts successfully with final_chunk = 0x01, discard any +memo chunks that were decrypted, and return nothing. Otherwise, concatenate +the decrypted memo chunks in order and return the concatenation as the memo.
    • +
    + +

    If any chunk of the memo encrypted to memo_key has been pruned, the decryption +process above returns nothing (as final_chunk will be set to 0x01 with the +wrong counter value), ensuring that a malformed memo is not returned.

    + +

    Encoding in transactions

    + +
    1314 ZIP 317: Proportional Transfer Fee Mechanism, Fee calculation
    ++++++ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
    Bytes Name Data Type Description
    1 fAllPruned uint8 1 if all chunks have been pruned, otherwise 0.
    32 nonceOrHash byte[32] The nonce for deriving encryption keys, or the overall hash.
    † varies nMemoChunks compactSize The number of memo chunks.
    † varies pruned byte[\(\mathsf{ceiling}(\mathtt{nMemoChunks}/8)\)] Bitflags indicating the type of each entry in vMemoChunks.
    † varies vMemoChunks MemoChunk[nMemoChunks] A sequence of encrypted memo chunks.
    + +

    † These fields are present if and only if fAllPruned == 0.

    + +

    If fAllPruned == 0, then:

    + +
      +
    • nonceOrHash represents the nonce for deriving encryption keys.
    • +
    • Each bit of pruned, in little-endian order, indicates the type of the +corresponding entry in vMemoChunks. A bit value of 0 indicates that +the entry will be of type byte[272] representing an encrypted memo +chunk. A bit value of 1 indicates the entry will be a byte[32] and +contains the memo_chunk_digest for a pruned chunk.
    • +
    + +

    If fAllPruned == 1, then:

    + +
      +
    • nonceOrHash represents the overall hash for the memo bundle as defined in +Transaction sighash.
    • +
    • The nMemoChunks, pruned, and vMemoChunks fields will be absent.
    • +
    + +

    Transaction sighash

    + +
    memo_chunk_digest = H(AEAD(MemoChunk, memo_key))
    +memo_bundle_digest = H(concat(memo_chunk_digests))
    +
    + +

    The memo bundle digest structure is a performance optimization for the case +where all memo chunks in a transaction have been pruned.

    + +

    TODO: finish this to be a modification to the equivalent of ZIP 244 for +transaction v6.

    + +

    Transaction fees

    + +

    (This section will become a modification to ZIP 317.)

    + +

    A memo bundle may contain two free chunks if there are any shielded outputs in +the transaction. Otherwise, each memo chunk requires marginal_fee as defined +in ZIP 317 10.

    + +

    Network protocol

    + +

    Nodes must reject GetData responses having an fAllPruned value that is nonzero, +or any byte of pruned that is nonzero.

    + +

    Changes to the Zcash Protocol Specification

    + +

    The following changes affecting the definitions of note plaintexts and note ciphertexts, +and the algorithms for encryption and decryption.

    +

    In § 3.2.1 ‘Note Plaintexts and Memo Fields’:

    +
    • Change

      +
      -

      Each Sapling or Orchard note plaintext (denoted np) -consists of

      -

         (leadByte ⦂ 𝔹𝕐, d ⦂ 𝔹[ℓd], rseed ⦂ 𝔹𝕐[𝟛𝟚], memo ⦂ 𝔹𝕐[𝟝𝟙𝟚])

      +

      Each Sapling or Orchard note plaintext (denoted \(\mathbf{np}\)) consists of

      + +

      \(\hspace{2em}(\mathsf{leadByte} \;⦂\; \mathbb{B^{Y}}, \mathsf{d} \;⦂\; \mathbb{B^{[\ell_{\mathsf{d}}]}}, \mathsf{rseed} \;⦂\; \mathbb{B^{Y[32]}}, \mathsf{memo} \;⦂\; \mathbb{B^{Y[512]}})\)

      +

      to

      +
      -

      The form of a Sapling or Orchard note plaintext depends on the -version of the transaction in which it will be included; specifically -whether that version is pre-v6, or v6-onward.

      -

      Each pre-v6 Sapling or Orchard note plaintext (denoted np) -consists of

      -

         (leadByte ⦂ 𝔹𝕐, d ⦂ 𝔹[ℓd], rseed ⦂ 𝔹𝕐[𝟛𝟚], memo ⦂ 𝔹𝕐[𝟝𝟙𝟚])

      -

      Each v6-onward Sapling or Orchard note plaintext (denoted np) -consists of

      -

         (leadByte ⦂ 𝔹𝕐, d ⦂ 𝔹[ℓd], rseed ⦂ 𝔹𝕐[𝟛𝟚], Kmemo ⦂ 𝔹𝕐[𝟛𝟚])

      +

      The form of a Sapling or Orchard note plaintext depends on the version of +the transaction in which it will be included; specifically whether that +version is pre-v6, or v6-onward.

      + +

      Each pre-v6 Sapling or Orchard note plaintext (denoted \(\mathbf{np}\)) consists of

      + +

      \(\hspace{2em}(\mathsf{leadByte} \;⦂\; \mathbb{B^{Y}}, \mathsf{d} \;⦂\; \mathbb{B^{[\ell_{\mathsf{d}}]}}, \mathsf{rseed} \;⦂\; \mathbb{B^{Y[32]}}, \mathsf{memo} \;⦂\; \mathbb{B^{Y[512]}})\)

      + +

      Each v6-onward Sapling or Orchard note plaintext (denoted \(\mathbf{np}\)) consists of

      + +

      \(\hspace{2em}(\mathsf{leadByte} \;⦂\; \mathbb{B^{Y}}, \mathsf{d} \;⦂\; \mathbb{B^{[\ell_{\mathsf{d}}]}}, \mathsf{rseed} \;⦂\; \mathbb{B^{Y[32]}}, \mathsf{K^{memo}} \;⦂\; \mathbb{B^{Y[32]}})\)

    -

    In § 5.5 ‘Encodings of Note Plaintexts and Memo Fields’ 5:

    + +

    In § 5.5 ‘Encodings of Note Plaintexts and Memo Fields’ 11:

    +
      -
    • Change the paragraph that describes “The encoding of a Sapling or -Orchard note plaintext” to refer to “The encoding of a pre-v6 Sapling or -Orchard note plaintext”.

    • +
    • Change the paragraph that describes “The encoding of a Sapling or Orchard note plaintext” +to refer to “The encoding of a pre-v6 Sapling or Orchard note plaintext”.

    • Add a new paragraph at the end of the section:

      +
      -

      The encoding of a v6-onward Sapling or Orchard note plaintext -consists of:

      - ------- - - - - - - - - - -
      8-bit leadByte88-bit d64-bit v256-bit rseed32-byte Kmemo
      +

      The encoding of a v6-onward Sapling or Orchard note plaintext consists of:

      + +

      | | | | | | +|—————————|———————|———————|————————–|—————————–| +| 8-bit \(\mathsf{leadByte}\) | 88-bit \(\mathsf{d}\) | 64-bit \(\mathsf{v}\) | 256-bit \(\mathsf{rseed}\) | 32-byte \(\mathsf{K^{memo}}\) |

      +
      • A byte 0x03, indicating this version of the encoding of a v6-onward Sapling or Orchard note plaintext.
      • -
      • 11 bytes specifying d.
      • -
      • 8 bytes specifying v.
      • -
      • 32 bytes specifying rseed.
      • -
      • 32 bytes specifying Kmemo.
      • +
      • 11 bytes specifying \(\mathsf{d}\).
      • +
      • 8 bytes specifying \(\mathsf{v}\).
      • +
      • 32 bytes specifying \(\mathsf{rseed}\).
      • +
      • 32 bytes specifying \(\mathsf{K^{memo}}\).
      -

      A value consisting of 32 0xFF -bytes for Kmemo is used to -indicate that there is no memo for this note plaintext.

      + +

      A value consisting of 32 \(\mathtt{0xFF}\) bytes for \(\mathsf{K^{memo}}\) is used +to indicate that there is no memo for this note plaintext.

    -

    In § 4.7.2 ‘Sending Notes (Sapling)’ 6 and -§ 4.7.3 ‘Sending Notes (Orchard)’ 7:

    + +

    In § 4.7.2 ‘Sending Notes (Sapling)’ 12 and +§ 4.7.3 ‘Sending Notes (Orchard)’ 13:

    +
      -
    • Add a reference to this ZIP specifying the construction of the -memo bundle and derivation of Kmemo in the case of a v6-onward -note plaintext.

    • +
    • Add a reference to this ZIP specifying the construction of the memo bundle and +derivation of \(\mathsf{K^{memo}}\) in the case of a v6-onward note plaintext.

    • Change

      +
      -

      Let np = (leadByte, d, v, rseed, memo) .

      +

      Let \(\mathbf{np} = (\mathsf{leadByte}, \mathsf{d}, \mathsf{v}, \mathsf{rseed}, \mathsf{memo})\).

      +

      to

      +
      -

      Let np be the -encoding of a Sapling note plaintext using leadByte, d, -v, rseed, and either memo for a pre-v6 note plaintext or Kmemo for a v6-onward note -plaintext.

      +

      Let \(\mathbf{np}\) be the encoding of a Sapling note plaintext using \(\mathsf{leadByte}\), \(\mathsf{d}\), +\(\mathsf{v}\), \(\mathsf{rseed}\), and either \(\mathsf{memo}\) for a pre-v6 note plaintext or +\(\mathsf{K^{memo}}\) for a v6-onward note plaintext.

      -

      replacing “Sapling” with Orchard in the case of § 4.7.3.

    • + +

      replacing “Sapling” with Orchard in the case of § 4.7.3.

    -

    In § 4.20.1 ‘Encryption (Sapling and Orchard)’ 8:

    + +

    In § 4.20.1 ‘Encryption (Sapling and Orchard)’ 14:

    +
    • Change

      +
      -

      Let np = (leadByte, d, v, rseed, memo) -be the Sapling or Orchard note plaintext. np is -encoded as defined in § 5.5 ‘Encodings of Note Plaintexts and Memo -Fields’.

      +

      Let \(\mathbf{np} = (\mathsf{leadByte}, \mathsf{d}, \mathsf{v}, \mathsf{rseed}, \mathsf{memo})\) +be the Sapling or Orchard note plaintext. \(\mathbf{np}\) is encoded as defined +in § 5.5 ‘Encodings of Note Plaintexts and Memo Fields’.

      +

      to

      +
      -

      Let np be the -encoding of the Sapling or Orchard note plaintext (which may be pre-v6 -or v6-onward), as defined in § 5.5 ‘Encodings of Note Plaintexts and -Memo Fields’.

      +

      Let \(\mathbf{np}\) be the encoding of the Sapling or Orchard note plaintext (which may be +pre-v6 or v6-onward), as defined in § 5.5 ‘Encodings of Note Plaintexts and Memo Fields’.

    • Add another normative note to that section:

      +
        -
      • Cenc will be of length -either 580 or 100 bytes, depending on whether np is a -pre-v6 or v6-onward note plaintext.
      • +
      • \(\mathsf{C^{enc}}\) will be of length either 580 or 100 bytes, depending on whether +\(\mathbf{np}\) is a pre-v6 or v6-onward note plaintext.
    -

    In § 4.20.2 ‘Decryption using an Incoming Viewing Key (Sapling and -Orchard)’ 9 and § 4.20.3 ‘Decryption using a -Full Viewing Key (Sapling and Orchard)’ 10:

    + +

    In § 4.20.2 ‘Decryption using an Incoming Viewing Key (Sapling and Orchard)’ 15 +and § 4.20.3 ‘Decryption using a Full Viewing Key (Sapling and Orchard)’ 16:

    +
      -
    • Replace memo ⦂ 𝔹𝕐[𝟝𝟙𝟚] -with memoOrKey.
    • -
    • Specify that the type of memoOrKey -is 𝔹𝕐[𝟝𝟙𝟚] when decrypting a -pre-v6 note ciphertext, or 𝔹𝕐[𝟛𝟚] when decrypting a v6-onward -note ciphertext. In the latter case, it is used as Kmemo to decrypt the memo bundle -as described in subsequent sections of this ZIP.
    • +
    • Replace \(\mathsf{memo} \;⦂\; \mathbb{B^{Y[512]}}\) with \(\mathsf{memoOrKey}\).
    • +
    • Specify that the type of \(\mathsf{memoOrKey}\) is \(\mathbb{B^{Y[512]}}\) when +decrypting a pre-v6 note ciphertext, or \(\mathbb{B^{Y[32]}}\) when decrypting a +v6-onward note ciphertext. In the latter case, it is used as \(\mathsf{K^{memo}}\) +to decrypt the memo bundle as described in Memo bundle.
    -

    Memo bundle

    -

    A memo bundle consists of a sequence of 256-byte memo chunks, each -individually encrypted. These memo chunks represent zero or more -encrypted memos.

    -

    Each transaction may contain a single memo bundle, and a memo bundle -may contain at most memo_chunk_limit memo chunks. This -limits the total amount of memo data that can be conveyed within a -single transaction to memo_chunk_limit * 256 bytes.

    -

    memo_chunk_limit is a parameter to this specification, -to be decided upon by the community. The authors of this ZIP propose a -maximum of 64 chunks, resulting in a maximum total memo data length of -16 KiB.

    -

    Memo bundles are encoded in transactions in a prunable manner: each -memo chunk can be replaced by its representative digest.

    -

    Memo encryption

    -

    During transaction construction, each output with memo data is -assigned a 32-byte memo key Kmemo. These keys SHOULD be -generated randomly, and MUST NOT be used to encrypt more than one memo -within a single transaction. If an output has no memo data, it is -assigned the memo key consisting of 32 0xFF -bytes.

    -

    In note plaintexts of v6-onward transactions, the 512-byte memo field -is replaced by Kmemo .

    -

    The transaction builder generates a 32-byte salt value salt from a CSPRNG. A new salt MUST be -generated for each memo bundle.

    -

    The symmetric encryption key for a memo is derived from its Kmemo as follows:

    -

       encryption_key = PRFKmemoexpand([0xE0] || salt)

    -

    The first byte 0xE0 -should be added to the documentation of inputs to PRFexpand in § 4.1.2 ‘Pseudo -Random Functions’ 11.

    -

    If the generated key is 32 0xFF -bytes, the transaction constructor MAY repeat this procedure with a -different salt, in order to avoid the recipient misinterpreting the -output as having no memo data. Since that has negligible probability, it -alternatively MAY omit this check.

    -

    Each memo is padded to a multiple of 256 bytes with zeroes, and split -into 256-byte chunks. Each memo chunk is encrypted with ChaCha20Poly1305 -12 as follows:

    -

       IETF_AEAD_CHACHA20_POLY1305(encryption_key, nonce, memo_chunk)

    -

    where nonce = I2BEOSP88(counter)||[final_chunk] .

    -

    This is a variant of the STREAM construction 13.

    -
      -
    • counter is a big-endian chunk -counter starting at zero and incrementing by one for each subsequent -chunk within a particular memo.
    • -
    • final_chunk is the byte 0x01 -for the final memo chunk, and 0x00 -for all preceding chunks.
    • -
    -

    Finally, the encrypted memo chunks for all memos are combined into a -single sequence using an order-preserving shuffle. Memo chunks from -different memos MAY be interleaved in any order, but memo chunks from -the same memo MUST have the same relative order. The following diagram -shows an example shuffle of three memos:

    -
    [
    -    (memo_a, 0),
    -    (memo_b, 0),
    -    (memo_a, 1),
    -    (memo_c, 0),
    -    (memo_c, 1),
    -    (memo_a, 2),
    -]
    -

    Memo decryption

    -

    When a recipient decrypts a shielded output, they obtain a memo key -Kmemo. From this they derive -encryption_key as above, and then proceed as follows:

    -
      -
    • Set counter = 0 and -final_chunk = 0x00.
    • -
    • Attempt to decrypt each memo chunk in order. Pruned memo chunks are -skipped.
    • -
    • Each time decryption succeeds for a memo chunk, increment -counter by 1, and then continue attempting to decrypt -subsequent chunks.
    • -
    • Once all memo chunks have been trial-decrypted once, set -final_chunk = 0x01 and then attempt to decrypt the memo -chunks again, starting immediately after the last successfully-decrypted -chunk (or at the start if none were), and without incrementing -counter. -
        -
      • This step can be made secret-independent by attempting to decrypt -every memo chunk again, and ignoring the results of all chunks up to and -including the last successfully-decrypted chunk.
      • -
    • -
    • If no memo chunk decrypts successfully with -final_chunk = 0x01, discard any memo chunks that were -decrypted, and return nothing. Otherwise, concatenate the decrypted memo -chunks in order and return the concatenation as the memo.
    • -
    -

    If any chunk of the memo encrypted to memo_key has been -pruned, the decryption process above returns nothing (as -final_chunk will be set to 0x01 with the wrong -counter value), ensuring that a malformed memo is not returned.

    -

    Encoding in transactions

    + +

    Applicability

    + +

    All of these changes apply identically to Mainnet and Testnet.

    + +

    Open issues

    + +

    Limit on the number of memo chunks

    + +

    memo_chunk_limit == 64 is recommended. This results in a maximum of 16 KiB +of memo data per transaction.

    + +

    Interaction with ZIP 302 17

    + +

    TBD

    + +

    Rationale

    + +

    Memo bundle size restriction

    + +

    Restricting the total amount of memo data in a bundle, for example to 16 KiB, +limits the rate at which the chain size can grow cheaply (from a computational +perspective; memo bundles are much easier to produce than proofs or signatures).

    + +

    The current behaviour for previous transaction versions (no limit on the number +of memos) is not altered by this ZIP, because memos in those transactions are +tied to individual shielded outputs (incurring their computational cost), and +are not natively aggregatable.

    + +

    Memo chunk size

    + +

    TODO: this table needs to be recalculated with a 16 KiB limit.

    + +

    With 10 KiB limit on amount of memo data as the constant in this table, the +maximum number of unique memos you can create, and the cost in bytes of that +memo data plus auth when using a 32-byte memo key, is:

    + ----+++ + - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
    BytesNameData TypeDescription
    1fAllPruneduint81 if all chunks have been pruned, otherwise 0.
    32nonceOrHashbyte[32]The nonce for deriving encryption keys, or the overall hash.
    † variesnMemoChunkscompactSizeThe number of memo chunks.
    † variesprunedbyte[ceiling(nMemoChunks/8)]Bitflags indicating the type of each entry in -vMemoChunks.
    † variesvMemoChunksMemoChunk[nMemoChunks]A sequence of encrypted memo chunks.
    -

    † These fields are present if and only if -fAllPruned == 0.

    -

    If fAllPruned == 0, then:

    -
      -
    • nonceOrHash represents the nonce for deriving -encryption keys.
    • -
    • Each bit of pruned, in little-endian order, indicates -the type of the corresponding entry in vMemoChunks. A bit -value of 0 indicates that the entry will be of type -byte[272] representing an encrypted memo chunk. A bit value -of 1 indicates the entry will be a byte[32] and contains -the memo_chunk_digest for a pruned chunk.
    • -
    -

    If fAllPruned == 1, then:

    -
      -
    • nonceOrHash represents the overall hash for the memo -bundle as defined in Transaction -sighash.
    • -
    • The nMemoChunks, pruned, and -vMemoChunks fields will be absent.
    • -
    -

    Transaction sighash

    -
    memo_chunk_digest = H(AEAD(MemoChunk, memo_key))
    -memo_bundle_digest = H(concat(memo_chunk_digests))
    -

    The memo bundle digest structure is a performance optimization for -the case where all memo chunks in a transaction have been pruned.

    -

    TODO: finish this to be a modification to the equivalent of ZIP 244 -for transaction v6.

    -

    Transaction fees

    -

    (This section will become a modification to ZIP 317.)

    -

    A memo bundle may contain two free chunks if there are any shielded -outputs in the transaction. Otherwise, each memo chunk requires -marginal_fee as defined in ZIP 317 14.

    -

    Network protocol

    -

    Nodes must reject GetData responses having an -fAllPruned value that is nonzero, or any byte of -pruned that is nonzero.

    -

    Open issues

    -

    Limit on the number of memo -chunks

    -

    memo_chunk_limit == 64 is recommended. This results in a -maximum of 16 KiB of memo data per transaction.

    -

    Rationale

    -

    Memo bundle size restriction

    -

    Restricting the total amount of memo data in a bundle, for example to -16 KiB, limits the rate at which the chain size can grow cheaply (from a -computational perspective; memo bundles are much easier to produce than -proofs or signatures).

    -

    The current behaviour for previous transaction versions (no limit on -the number of memos) is not altered by this ZIP, because memos in those -transactions are tied to individual shielded outputs (incurring their -computational cost), and are not natively aggregatable.

    -

    Memo chunk size

    -

    TODO: this table needs to be recalculated with a 16 KiB limit.

    -

    With 10 KiB limit on amount of memo data as the constant in this -table, the maximum number of unique memos you can create, and the cost -in bytes of that memo data plus auth when using a 32-byte memo key, -is:

    - - - - - - + + + + + - - - - - - - - - + + + + - - - - + + + + - - - - + + + + - - - - - - - - - + + + +
    Memo size
    Chunk size Memo size ≤ 256 bytes Memo size = 512 bytes
    Chunk size≤ 256 bytes512 bytes
    ========================================================
    Pre-231 20 @ 10240 ( 0.00%) 20 @ 10240 ( 0.00%)
    Pre-23120 @ 10240 ( 0.00%)20 @ 10240 ( 0.00%)
    512 20 @ 11220 (+ 9.57%) 20 @ 11220 (+ 9.57%)
    51220 @ 11220 (+ 9.57%)20 @ 11220 (+ 9.57%)
    256 40 @ 12200 (+19.14%) 20 @ 11540 (+12.70%)
    25640 @ 12200 (+19.14%)20 @ 11540 (+12.70%)
    256 20-out20 @ 6100 (-40.43%)
    256 20-out 20 @ 6100 (-40.43%)
    -

    In the “256 20-out” case you have a distinguisher compared to old -transactions, in that you can tell the transaction is sending at most -256 bytes per recipient rather than 512 if it is sending the max number -of memos. But that’s inherently baked into the decision to use a smaller -memo chunk size (and it is still possible for the chunks to all be a -single memo sent to all outputs, or anything in between).

    -

    Memo key size

    -

    If we used a 16-byte memo key instead of 32 bytes, the transaction -size overhead becomes:

    + +

    In the “256 20-out” case you have a distinguisher compared to old transactions, +in that you can tell the transaction is sending at most 256 bytes per recipient +rather than 512 if it is sending the max number of memos. But that’s inherently +baked into the decision to use a smaller memo chunk size (and it is still +possible for the chunks to all be a single memo sent to all outputs, or anything +in between).

    + +

    Memo key size

    + +

    If we used a 16-byte memo key instead of 32 bytes, the transaction size overhead +becomes:

    + +++++ + - - - - + + + + + - - - - - - - - - - - - - - + + + + - - - - + + + + - - - - + + + + - - - - + + + +
    Memo size
    Chunk size Memo size ≤ 256 bytes Memo size = 512 bytes
    Chunk size≤ 256 bytes512 bytes
    ========================================================
    Pre-23120 @ 10240 ( 0.00%)20 @ 10240 ( 0.00%)
    Pre-231 20 @ 10240 ( 0.00%) 20 @ 10240 ( 0.00%)
    51220 @ 10900 (+ 6.45%)20 @ 10900 (+ 6.45%)
    512 20 @ 10900 (+ 6.45%) 20 @ 10900 (+ 6.45%)
    25640 @ 11560 (+12.89%)20 @ 11220 (+ 9.57%)
    256 40 @ 11560 (+12.89%) 20 @ 11220 (+ 9.57%)
    256 20-out20 @ 5780 (-43.55%)
    256 20-out 20 @ 5780 (-43.55%)
    -

    The decrease in overhead is relatively modest in most cases, but more -noticeable for small memos with a 256-byte memo chunk.

    -

    However, 128-bit keys don’t meet Zcash’s target security level of 125 -bits, as argued in 15.

    + +

    The decrease in overhead is relatively modest in most cases, but more noticeable +for small memos with a 256-byte memo chunk.

    + +

    However, 128-bit keys don’t meet Zcash’s target security level of 125 bits, +as argued in 18.

    +

    The benefits of 256-bit keys are:

    +
      -
    • They incur only a small transaction size overhead above the minimum -key size that would meet the target security level.
    • -
    • This key length matches what we already use elsewhere for symmetric -keys.
    • +
    • They incur only a small transaction size overhead above the minimum key size +that would meet the target security level.
    • +
    • This key length matches what we already use elsewhere for symmetric keys.
    -

    Encryption format

    -

    Including a per-transaction salt in -the derivation of encryptionkey gives protection -against accidental (or intentional) reuse of Kmemo reuse across multiple -transactions. We do not protect against Kmemo reuse within a transaction; -it is up to the transaction builder to ensure that the same Kmemo is not used to encrypt two -different memos (and if they did so, normal clients would either never -observe the second memo, or would decrypt parts of each memo and get a -nonsensical and potentially insecure “spliced” memo).

    -

    We do not include commitments to the shielded outputs in the -derivation of encryptionkey -for two reasons:

    + +

    Encryption format

    + +

    Including a per-transaction \(\mathsf{salt}\) in the derivation of +\(\mathsf{encryption_key}\) gives protection against accidental (or intentional) +reuse of \(\mathsf{K^{memo}}\) reuse across multiple transactions. We do not +protect against \(\mathsf{K^{memo}}\) reuse within a transaction; it is up to +the transaction builder to ensure that the same \(\mathsf{K^{memo}}\) is not +used to encrypt two different memos (and if they did so, normal clients would +either never observe the second memo, or would decrypt parts of each memo and +get a nonsensical and potentially insecure “spliced” memo).

    + +

    We do not include commitments to the shielded outputs in the derivation of +\(\mathsf{encryption_key}\) for two reasons:

    +
      -
    • It would force the transaction builder to fully define all shielded -outputs before encrypting the memos, which might prevent potential use -cases of PCZTs 16.
    • -
    • We don’t want to unnecessarily prevent the ability to create a -transaction with a memo bundle and no shielded outputs, as there may be -use cases for, e.g. a fully-transparent transaction with encrypted memo, -or a ZSA issuance transaction with exposed memo data using a well-known -Kmemo.
    • +
    • It would force the transaction builder to fully define all shielded outputs +before encrypting the memos, which might prevent potential use cases of PCZTs 19.
    • +
    • We don’t want to unnecessarily prevent the ability to create a transaction +with a memo bundle and no shielded outputs, as there may be use cases for, +e.g. a fully-transparent transaction with encrypted memo, or a ZSA issuance +transaction with exposed memo data using a well-known \(\mathsf{K^{memo}}\).
    -

    Pruned encoding

    -

    The separation of memo data from note data, and the new ability to -easily store variable-length memo data, opens up an attack vector -against node operators for storing arbitrary data. The transaction -digest commitments to the memo bundle are structured such that if a node -operator is presented with a memo key (i.e. they are given the -capability to decrypt a particular memo), they can identify and prune -the corresponding memo chunks, while still enabling the transaction to -be validated as part of its corresponding block and broadcast over the -network.

    -

    The transaction encoding permits pruning at the individual chunk -level in order to facilitate pruning an individual memo from a -transaction without affecting the other memos. This enables node -operators to be responsive to, for example, GDPR deletion requests.

    -

    Note that broadcasting a partially-pruned transaction means that the -pruned chunks no longer contribute to the upper bound on memo data.

    -

    The prunable structure does not introduce a censorship axis; memo -bundles do not reveal which memo chunks correspond to which memos, and -therefore a network adversary cannot selectively censor individual -memos. They can censor any/all chunks within specific transactions, -however shielded transactions do not reveal their senders, recipients, -or amounts, and thus also cannot be individually targeted for -censorship.

    -

    Transaction fees

    -

    Making the fee linear in the number of chunks has the following -properties:

    + +

    Pruned encoding

    + +

    The separation of memo data from note data, and the new ability to easily store +variable-length memo data, opens up an attack vector against node operators for +storing arbitrary data. The transaction digest commitments to the memo bundle +are structured such that if a node operator is presented with a memo key (i.e. +they are given the capability to decrypt a particular memo), they can identify +and prune the corresponding memo chunks, while still enabling the transaction to +be validated as part of its corresponding block and broadcast over the network.

    + +

    The transaction encoding permits pruning at the individual chunk level in order +to facilitate pruning an individual memo from a transaction without affecting the +other memos. This enables node operators to be responsive to, for example, GDPR +deletion requests.

    + +

    Note that broadcasting a partially-pruned transaction means that the pruned +chunks no longer contribute to the upper bound on memo data.

    + +

    The prunable structure does not introduce a censorship axis; memo bundles do not +reveal which memo chunks correspond to which memos, and therefore a network +adversary cannot selectively censor individual memos. They can censor any/all +chunks within specific transactions, however shielded transactions do not reveal +their senders, recipients, or amounts, and thus also cannot be individually +targeted for censorship.

    + +

    Transaction fees

    + +

    Making the fee linear in the number of chunks has the following properties:

    +
      -
    • The required fee to add more memo chunks scales at the same rate as -adding logical actions, so it isn’t a cheaper mechanism for an adversary -to bloat chain size.
    • -
    • A “baseline transaction” (one spent note, one output to an external -recipient with a memo, one change output without a memo) has the same -fee as before.
    • -
    • A “broadcast transaction” (many outputs to different recipients all -given the same memo) is the same fee as before (but a smaller -transaction).
    • -
    • A “many memos transaction” (many outputs to different recipients all -with unique memos) is at most around twice the fee as before.
    • +
    • The required fee to add more memo chunks scales at the same rate as adding +logical actions, so it isn’t a cheaper mechanism for an adversary to bloat +chain size.
    • +
    • A “baseline transaction” (one spent note, one output to an external recipient +with a memo, one change output without a memo) has the same fee as before.
    • +
    • A “broadcast transaction” (many outputs to different recipients all given the +same memo) is the same fee as before (but a smaller transaction).
    • +
    • A “many memos transaction” (many outputs to different recipients all with +unique memos) is at most around twice the fee as before.
    -

    Combined with the memo bundle size restriction, the maximum -additional fee for a memo bundle over prior transactions is 0.0019 -ZEC.

    -

    Reference implementation

    + +

    Combined with the memo bundle size restriction, the maximum additional fee for +a memo bundle over prior transactions is 0.0019 ZEC.

    + +

    Deployment

    + +

    This ZIP is proposed to activate with Network Upgrade 7. 20

    + +

    Reference implementation

    +

    TBD

    -

    References

    -
    + +

    References

    + +

      -
    1. Information on BCP 14 — -“RFC 2119: Key words for use in RFCs to Indicate Requirement Levels” and -“RFC 8174: Ambiguity of Uppercase vs Lowercase in RFC 2119 Key -Words”↩︎

    2. -
    3. Zcash Protocol -Specification, Version 2024.5.1 [NU6] or later↩︎

    4. -
    5. Zcash -Protocol Specification, Version 2024.5.1 [NU6]. Section 3.2.1: Note -Plaintexts and Memo Fields↩︎

    6. -
    7. ZIP 307: Light Client Protocol -for Payment Detection↩︎

    8. -
    9. Zcash -Protocol Specification, Version 2024.5.1 [NU6]. Section 5.5: Encodings -of Note Plaintexts and Memo Fields↩︎

    10. -
    11. Zcash -Protocol Specification, Version 2024.5.1 [NU6]. Section 4.7.2: Sending -Notes (Sapling)↩︎

    12. -
    13. Zcash -Protocol Specification, Version 2024.5.1 [NU6]. Section 4.7.3: Sending -Notes (Orchard)↩︎

    14. -
    15. Zcash Protocol -Specification, Version 2024.5.1 [NU6]. Section 4.20.1: Encryption -(Sapling and Orchard)↩︎

    16. -
    17. Zcash -Protocol Specification, Version 2024.5.1 [NU6]. Section 4.20.2: -Decryption using an Incoming Viewing Key (Sapling and Orchard)↩︎

    18. -
    19. Zcash -Protocol Specification, Version 2024.5.1 [NU6]. Section 4.20.3: -Decryption using a Full Viewing Key (Sapling and Orchard)↩︎

    20. -
    21. Zcash -Protocol Specification, Version 2024.5.1 [NU6]. Section 4.1.2: Pseudo -Random Functions↩︎

    22. -
    23. RFC 8439: ChaCha20 -and Poly1305 for IETF Protocols↩︎

    24. -
    25. Online -Authenticated-Encryption and its Nonce-Reuse Misuse-Resistance↩︎

    26. -
    27. ZIP 317: Proportional Transfer -Fee Mechanism↩︎

    28. -
    29. Zcash -Protocol Specification, Version 2024.5.1 [NU6]. Section 8.7: In-band -secret distribution↩︎

    30. -
    31. zcash/zips issue #693: -Standardize a protocol for creating shielded transactions offline↩︎

    32. + +
    33. +

      Information on BCP 14 — “RFC 2119: Key words for use in RFCs to Indicate Requirement Levels” and “RFC 8174: Ambiguity of Uppercase vs Lowercase in RFC 2119 Key Words”  ↩︎

      +
    34. + +
    35. +

      ZIP 200: Network Upgrade Mechanism  ↩︎

      +
    36. + +
    37. +

      Zcash Protocol Specification, Version 2024.5.1 [NU6] or later  ↩︎

      +
    38. + +
    39. +

      Zcash Protocol Specification, Version 2024.5.1 [NU6]. Section 3.12: Mainnet and Testnet  ↩︎

      +
    40. + +
    41. +

      Zcash Protocol Specification, Version 2024.5.1 [NU6]. Section 3.2.1: Note Plaintexts and Memo Fields  ↩︎

      +
    42. + +
    43. +

      ZIP 307: Light Client Protocol for Payment Detection  ↩︎

      +
    44. + +
    45. +

      Zcash Protocol Specification, Version 2024.5.1 [NU6]. Section 4.1.2: Pseudo Random Functions  ↩︎

      +
    46. + +
    47. +

      RFC 8439: ChaCha20 and Poly1305 for IETF Protocols  ↩︎

      +
    48. + +
    49. +

      Online Authenticated-Encryption and its Nonce-Reuse Misuse-Resistance  ↩︎

      +
    50. + +
    51. +

      ZIP 317: Proportional Transfer Fee Mechanism  ↩︎

      +
    52. + +
    53. +

      Zcash Protocol Specification, Version 2024.5.1 [NU6]. Section 5.5: Encodings of Note Plaintexts and Memo Fields  ↩︎

      +
    54. + +
    55. +

      Zcash Protocol Specification, Version 2024.5.1 [NU6]. Section 4.7.2: Sending Notes (Sapling)  ↩︎

      +
    56. + +
    57. +

      Zcash Protocol Specification, Version 2024.5.1 [NU6]. Section 4.7.3: Sending Notes (Orchard)  ↩︎

      +
    58. + +
    59. +

      Zcash Protocol Specification, Version 2024.5.1 [NU6]. Section 4.20.1: Encryption (Sapling and Orchard)  ↩︎

      +
    60. + +
    61. +

      Zcash Protocol Specification, Version 2024.5.1 [NU6]. Section 4.20.2: Decryption using an Incoming Viewing Key (Sapling and Orchard)  ↩︎

      +
    62. + +
    63. +

      Zcash Protocol Specification, Version 2024.5.1 [NU6]. Section 4.20.3: Decryption using a Full Viewing Key (Sapling and Orchard)  ↩︎

      +
    64. + +
    65. +

      ZIP 302: Standardized Memo Field Format  ↩︎

      +
    66. + +
    67. +

      Zcash Protocol Specification, Version 2024.5.1 [NU6]. Section 8.7: In-band secret distribution  ↩︎

      +
    68. + +
    69. +

      zcash/zips issue #693: Standardize a protocol for creating shielded transactions offline  ↩︎

      +
    70. + +
    71. +

      ZIP 254: Deployment of the NU7 Network Upgrade  ↩︎

      +
    72. +
    -
    + diff --git a/rendered/zip-0233.html b/rendered/zip-0233.html index f6585d35a..e486657c4 100644 --- a/rendered/zip-0233.html +++ b/rendered/zip-0233.html @@ -3,7 +3,9 @@ ZIP 233: Network Sustainability Mechanism: Burning - + + + @@ -20,132 +22,238 @@ Category: Consensus / Ecosystem Created: 2023-08-16 License: BSD-2-Clause -Discussions-To: <https://github.com/zcash/zips/issues/922> -

    Terminology

    -

    The key words “MUST”, “SHOULD”, “SHOULD NOT”, “MAY”, “RECOMMENDED”, -“OPTIONAL”, and “REQUIRED” in this document are to be interpreted as -described in RFC 2119. [1]

    -

    The term “network upgrade” in this document is to be interpreted as -described in ZIP 200. [2]

    -

    “Block Subsidy” - the algorithmic issuance of ZEC on block creation. -Part of the consensus rules. Split between the miner and the Dev Fund. -Also known as Block Reward.

    -

    “Issuance” - The method by which ZEC becomes available for -circulation on the network.

    -

    “We” - the ZIP Owners and Authors, listed in the above front -matter.

    -

    “MAX_MONEY” is the total ZEC supply cap, defined as -21,000,000 ZEC. This is slightly larger than the supply cap for the -current issuance mechanism, but is the value used in existing critical -consensus checks.

    -

    Abstract

    -

    We propose the introduction of a mechanism to voluntarily burn funds, -removing those funds entirely from circulation on the network. This -mechanism, in combination with ZIPs 234 and 235, comprises a long-term -strategy for the sustainability of the network. We will refer to the -combined effects of these three ZIPs as the “Network Sustainability -Mechanism”.

    -

    Motivation

    -

    This mechanism seeks to address concerns about the sustainability of -the network design shared by Bitcoin-like systems:

    -
      -
    1. Long Term Consensus Sustainability: By enabling the -burning of funds, the network gains the ability to create “headroom” -between the chain value and MAX_MONEY. This lays necessary -groundwork for extending the miner reward system, which currently has a -clear final end date.
    2. -
    3. Benefits to ZEC Holders: Burning funds reduces the -supply of ZEC, benefiting network users in proportion to their holdings -without requiring them to opt into any scheme, introducing extra risk, -active oversight, or accounting complexity.
    4. +Discussions-To: <https://github.com/zcash/zips/issues/922> + + +

      Terminology

      + +

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

      + +

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

      + +

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

      + +

      The terms “Mainnet” and “Testnet” are to be interpreted as described in +§ 3.12 ‘Mainnet and Testnet’. 4

      + +

      “ZEC/TAZ” refers to the native currency of Zcash on a given network, i.e. +ZEC on Mainnet and TAZ on Testnet.

      + +

      “Block Subsidy” - The algorithmic issuance of ZEC/TAZ on block creation, as +defined by consensus. This is split between the miner and Funding Streams.

      + +

      “Issuance” - The method by which ZEC/TAZ becomes available for circulation +on the network. [TODO: there is a potential terminology conflict between +this and issuance as defined in ZIP 227.]

      + +

      “Burning” - The method by which ZEC/TAZ becomes unavailable for circulation +on the network.

      + +

      \(\mathsf{MAX\_MONEY}\), as defined in § 5.3 ‘Constants’ 5, +is the total ZEC/TAZ supply cap measured in zatoshi, corresponding to +21,000,000 ZEC. This is slightly larger than the supply cap for the current +issuance mechanism, but is the value used in existing critical consensus +checks.

      + +

      Abstract

      + +

      This ZIP proposes the introduction of a mechanism to voluntarily burn funds, +removing those funds entirely from circulation on the network. This mechanism, +in combination with ZIP 234 6 and ZIP 235 7, comprises a +long-term strategy for the sustainability of the network. We will refer to the +combined effects of these three ZIPs as the “Network Sustainability Mechanism”.

      + +

      Motivation

      + +

      This mechanism seeks to address concerns about the sustainability of the network +design shared by Bitcoin-like systems:

      + +
        +
      1. Long Term Consensus Sustainability: By enabling the burning of funds, the +network gains the ability to create “headroom” between the chain value and +\(\mathsf{MAX\_MONEY}\). This lays necessary groundwork for extending the +block subsidy system, which currently has a clear final end date.
      2. +
      3. Benefits to ZEC Holders: Burning funds reduces the supply of ZEC, +benefiting network users in proportion to their holdings without requiring +them to opt into any scheme, introducing extra risk, active oversight, or +accounting complexity.
      -

      Specification

      -

      The modifications required are:

      -
        -
      1. The addition of a transaction field representing an amount to burn -for a given transaction.
      2. -
      3. The inclusion of the burn amount in the calculated total output -value for a given transaction.
      4. -
      5. Consensus rules to ensure the burned amount is no longer available -for circulation on the network.
      6. -
      -

      Transaction Format

      -

      The following field is added to the v6 transaction format [3]:

      - + +

      Specification

      + +

      Burn amount

      + +

      Each transaction gains a \(\mathsf{burn\_amount}\) property, specifying the +value in zatoshis that is burned when the transaction is mined. The burned value +subtracts from the remaining value in the “transparent transaction value pool” +as described in § 3.4 ‘Transactions and Treestates’ 8.

      + +

      \(\mathsf{burn\_amount}\) does not result in an output being produced in any +chain value pool, and therefore from the point at which the transaction is +applied to the global chain state, \(\mathsf{burn\_amount}\) is subtracted from the +issued supply. It is unavailable for circulation on the network at least through +to the end of the block in which the transaction is mined. ZIP 234 6 +specifies a potential mechanism by which the burned funds would again become +available.

      + +

      Changes to ZIP 230 9

      + +

      The following field is appended to the Common Transaction Fields of the v6 +transaction format after nExpiryHeight 10:

      + +
      ----++++ + - - - - - + + + + + + - - - - - + + + + +
      BytesNameData TypeDescription
      Bytes Name Data Type Description
      8burnAmountuint64The amount of input value to be burned, in zatoshis.
      8 burnAmount uint64 The value to be burned in this transaction, in zatoshis.
      -

      Note: Older transaction versions can continue to be -supported after a network upgrade, but burning is not possible for these -transactions. For example, NU5 supports both v4 and v5 transaction -formats, for both coinbase and non-coinbase transactions.

      -

      Consensus Rules

      -

      The burned value must now be considered when calculating the total -output value of a transaction. It should be treated similarly to a -transparent output, except that there is no way for this value to be -used as an input in a future transaction.

      -

      Digests

      -

      The transaction digest algorithm defined in ZIP 244 [4] is to be -modified for v6 transactions as follows:

      -

      Section T.1: header_digest [5] is specified in draft-txv6-sighash [6] -to read:

      + +

      The \(\mathsf{burn\_amount}\) of a transaction is defined to be the value of the +burnAmount field if present, and otherwise 0.

      + +

      Notes:

      + +
        +
      • If both this ZIP and ZIP 2002 are selected for inclusion in the same Network +Upgrade, then the ambiguity in ordering of the fields added by these ZIPs +would need to be resolved.
      • +
      • Older transaction versions can continue to be supported after a network upgrade, +but burning is not possible for these transactions. For example, NU5 supports +both v4 and v5 transaction formats, for both coinbase and non-coinbase transactions.
      • +
      + +

      Changes to the Zcash Protocol Specification

      + +

      Make a change to § 3.4 ‘Transactions and Treestates’ 8 +implementing the specification in Burn amount.

      + +

      In § 7.1 ‘Transaction Encoding and Consensus’ 11, add:

      + +
      +

      [NU7 onward] \(\mathsf{burn\_amount}\) MUST be in the range \(\{ 0 .. \mathsf{MAX\_MONEY} \}\).

      +
      + +

      Modifications relative to ZIP 244 12

      + +

      Relative to the sighash algorithm defined in ZIP 244, the sighash algorithm +that applies to v6 transactions differs by appending the encoding of +\(\mathsf{burn\_amount}\) to the Common Transaction Fields that are the input +to the digest in T.1: header_digest 13:

      +
      -

      A BLAKE2b-256 hash of the following values:

      -
      T.1a: version             (4-byte little-endian version identifier including ``fOverwintered`` flag)
      -T.1b: version_group_id    (4-byte little-endian version group identifier)
      -T.1c: consensus_branch_id (4-byte little-endian consensus branch id)
      -T.1d: lock_time           (4-byte little-endian ``nLockTime`` value)
      -T.1e: expiry_height       (4-byte little-endian block height)
      -T.1f: burn_amount         (8-byte little-endian burn amount value)
      -

      The personalization field of this hash is set to:

      -
      ZTxIdHeadersHash
      +
       T.1f: burn_amount (8-byte little-endian burn amount)
      +
      -

      Rationale

      -

      All technical decisions in this ZIP are balanced between the -necessary robustness of the NSM mechanics, and simplicity of -implementation.

      -

      New transaction field for -burn amount

      -

      An explicit value distinguishes the burned ZEC from the transaction -fee. Explicitness also ensures any arithmetic flaws in any -implementations are more likely to be observed and caught -immediately.

      -

      Deployment

      -

      This ZIP is proposed to activate with Network Upgrade 7.

      -

      References

      -

      [1]: Key words for use in -RFCs to Indicate Requirement Levels

      -

      [2]: ZIP 200: Network Upgrade -Mechanism

      -

      [3]: ZIP 230: Version 6 Transaction -Format

      -

      [4]: ZIP 244: Transaction Identifier -Non-Malleability

      -

      [5]: ZIP 244: -Transaction Identifier Non-Malleability. Section T.1: Header -Digest

      -

      [6]: Draft Tx v6 -Sighash

      + +

      Note: If both this ZIP and ZIP 2002 are selected for inclusion in the same +Network Upgrade, then the ambiguity in ordering of the fields added by these +ZIPs would need to be resolved.

      + +

      Applicability

      + +

      All of these changes apply identically to Mainnet and Testnet.

      + +

      Rationale

      + +

      All technical decisions in this ZIP are balanced between the necessary +robustness of the NSM mechanics, and simplicity of implementation.

      + +

      New transaction field for burn amount

      + +

      An explicit value distinguishes the burned ZEC from the transaction fee. +Explicitness also ensures any arithmetic flaws in any implementations are more +likely to be observed and caught immediately.

      + +

      Deployment

      + +

      This ZIP is proposed to activate with Network Upgrade 7. 14

      + +

      References

      + + diff --git a/rendered/zip-0234.html b/rendered/zip-0234.html index 683aecc53..7898fb543 100644 --- a/rendered/zip-0234.html +++ b/rendered/zip-0234.html @@ -3,7 +3,9 @@ ZIP 234: Network Sustainability Mechanism: Issuance Smoothing - + + + @@ -19,195 +21,300 @@ Status: Draft Category: Consensus Created: 2023-08-23 -License: BSD-2-Clause -

      Terminology

      -

      The key words “MUST”, “SHOULD”, “SHOULD NOT”, “MAY”, “RECOMMENDED”, -“OPTIONAL”, and “REQUIRED” in this document are to be interpreted as -described in RFC 2119. [1]

      -

      “Network upgrade” - to be interpreted as described in ZIP 200. -[2]

      -

      “Block Subsidy” - the algorithmic issuance of ZEC on block creation. -Part of the consensus rules. Split between the miner and the Dev Fund. -Also known as Block Reward.

      -

      “Issuance” - The method by which ZEC becomes available for -circulation on the network.

      -

      Let PostBlossomHalvingInterval be as defined in -[#protocol-diffadjustment]_.

      -

      “Money Reserve” - MAX_MONEY - ChainValue, where -ChainValue includes all ZEC available on the network, -across all value pools.

      -

      Abstract

      -

      This ZIP proposes a change to how nodes calculate the block -subsidy.

      -

      Instead of following a step function around the 4-year halving -intervals inherited from Bitcoin, we propose a smooth logarithmic curve, -defined as a fixed portion of the current value of the Money Reserve at -a given block height.

      -

      The new issuance scheme would approximate the current issuance over -4-year intervals, assuming no ZEC is burned during that time, and -retains the overall supply cap of MAX_MONEY.

      -

      Motivation

      +License: BSD-2-Clause +Discussions-To: <https://github.com/zcash/zips/issues/923> + + +

      Terminology

      + +

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

      + +

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

      + +

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

      + +

      The terms “Mainnet” and “Testnet” are to be interpreted as described in +§ 3.12 ‘Mainnet and Testnet’. 4

      + +

      The symbol “\(\,\cdot\,\)” means multiplication, as described in § 2 ‘Notation’. +5

      + +

      “ZEC/TAZ” refers to the native currency of Zcash on a given network, i.e. +ZEC on Mainnet and TAZ on Testnet.

      + +

      The terms “Block Subsidy”, “Issuance”, and “Burning” are to be interpreted +as described in ZIP 233. 6

      + +

      Let \(\mathsf{PostBlossomHalvingInterval}\) be as defined in 7.

      + +

      \(\mathsf{MAX\_MONEY}\), as defined in § 5.3 ‘Constants’ 8, +is the total ZEC/TAZ supply cap measured in zatoshi, corresponding to +21,000,000 ZEC. This is slightly larger than the supply cap for the current +issuance mechanism, but is the value used in existing critical consensus +checks.

      + +

      “Issued Supply” - The Issued Supply at a given height of a block chain is +the total ZEC/TAZ value in all chain value pool balances at that height, as +calculated by \(\mathsf{IssuedSupply}(\mathsf{height})\) defined in +§ 4.17 ‘Chain Value Pool Balances’. 9

      + +

      “Money Reserve” - The Money Reserve at a given height of a block chain is +the total ZEC/TAZ value remaining to be issued, as calculated by +\(\mathsf{MAX\_MONEY} - \mathsf{IssuedSupply}(\mathsf{height})\).

      + +

      Abstract

      + +

      This ZIP proposes a change to how nodes calculate the block subsidy.

      + +

      Instead of following a step function around the 4-year halving intervals +inherited from Bitcoin, we propose a smooth logarithmic curve, defined as a +fixed portion of the current value of the Money Reserve at a given block height.

      + +

      The new issuance scheme would approximate the current issuance over 4-year +intervals, assuming no ZEC/TAZ is burned during that time, and retains the +overall supply cap of MAX_MONEY.

      + +

      Motivation

      +

      Key Objectives:

      -
        -
      1. We want to introduce an automated mechanism that allows users of the -network to contribute to the long-term sustainability of the -network.
      2. -
      3. We want to enable ZEC that has been burned to be recreated in the -future to benefit network sustainability.
      4. + +
          +
        1. We want to introduce an automated mechanism that allows users of the network +to contribute to the long-term sustainability of the network.
        2. +
        3. We want to enable ZEC that has been burned to be recreated in the future to +benefit network sustainability.
        4. We want to retain the existing ZEC supply cap of 21 million.
        5. -
        6. We want the issuance rate to remain similar to the historical rate -for Zcash (and before that, Bitcoin).
        7. -
        8. We want issuance to be easy for all network users to understand and -predict.
        9. -
        10. We want the new issuance to activate at a block with as minimal a -delta from the current issuance as possible.
        11. +
        12. We want the issuance rate to remain similar to the historical rate for Zcash +(and before that, Bitcoin).
        13. +
        14. We want issuance to be easy for all network users to understand and predict.
        15. +
        16. We want the new issuance to activate at a block with as minimal a delta from +the current issuance as possible.
        -

        The current Zcash economic model, inherited from Bitcoin, includes a -halving mechanism that dictates the issuance of new coins. While this -has been foundational, halvings can lead to abrupt changes in the rate -of new coins being introduced to the market. Such sudden shifts can -potentially disrupt the network’s economic model, potentially impacting -its security and stability. Furthermore, the halvings schedule is fixed -and does not provide any way to “recycle” funds into future -issuance.

        -

        This new NSM-based issuance scheme solves these problems by ensuring -a more consistent and predictable rate of coin issuance, while -preserving the core aspects of Zcash’s issuance policy and the 21 -million coin cap. At the same time, it introduces the first mechanism to -recreate and distribute ZEC that has been removed from circulation, as -well as unclaimed transaction fees, across future block subsidies.

        -

        Requirements

        -

        Smoothing the issuance curve is possible using an exponential decay -formula that satisfies the following requirements:

        -
          -
        1. The issuance can be summarized into a reasonably simple -explanation
        2. -
        3. Block subsidies approximate a continuous function
        4. -
        5. If the Money Reserve is greater than 0, then the block subsidy must -be non-zero, preventing any final “unmined” zatoshis
        6. -
        7. For any 4 year period, all paid out block subsidies are -approximately equal to half of the Money Reserve at the beginning of -that 4 year period, if no ZEC is burned during those 4 years
        8. -
        9. Decrease the short-term impact of the deployment of this ZIP on -block reward recipients, and minimize the potential reputation risk to -Zcash of changing the block reward amount.
        10. + +

          The current Zcash economic model, inherited from Bitcoin, includes a halving +mechanism that dictates the issuance of new coins. While this has been +foundational, halvings can lead to abrupt changes in the rate of new coins +being introduced to the market. Such sudden shifts can potentially disrupt the +network’s economic model, potentially impacting its security and stability. +Furthermore, the halvings schedule is fixed and does not provide any way to +“recycle” funds into future issuance.

          + +

          This new NSM-based issuance scheme solves these problems by ensuring a more +consistent and predictable rate of coin issuance, while preserving the core +aspects of Zcash’s issuance policy and the 21-million-coin cap. At the same +time, it introduces the first mechanism to recreate and distribute ZEC that has +been removed from circulation, as well as unclaimed transaction fees, across +future block subsidies.

          + +

          Requirements

          + +

          Smoothing the issuance curve is possible using an exponential decay formula +that satisfies the following requirements:

          + +
            +
          1. The issuance can be summarized into a reasonably simple explanation.
          2. +
          3. Block subsidies approximate a continuous function.
          4. +
          5. If the Money Reserve is greater than 0, then the block subsidy must be +non-zero, preventing any final “unmined” zatoshis.
          6. +
          7. For any 4-year period, all paid out block subsidies are approximately equal +to half of the Money Reserve at the beginning of that 4-year period, if no +ZEC is burned during those 4 years.
          8. +
          9. Decrease the short-term impact of the deployment of this ZIP on block subsidy +recipients, and minimize the potential reputation risk to Zcash of changing +the block subsidy amount.
          10. +
          11. The immediate change in issuance when this mechanism activates should be +minimal.
          -

          TODO daira: add a requirement that makes the initial total issuance -match the previous total issuance

          -

          Specification

          -

          Parameters

          -

          BLOCK_SUBSIDY_FRACTION = 4126 / 10,000,000,000 or -0.0000004126

          -

          DEPLOYMENT_BLOCK_HEIGHT = TBD

          + +

          Specification

          + +

          Parameters

          + +

          \(\mathsf{BLOCK\_SUBSIDY\_FRACTION} = 4126 / 10\_000\_000\_000 = 0.0000004126\)

          + +

          \(\mathsf{DEPLOYMENT\_BLOCK\_HEIGHT} = \mathsf{TBD}\)

          +

          The block height will be chosen by the following criteria:

          +
          • It is after NU7 activation height.
          • -
          • It is calculated to be the lowest height after the the second -halving at which the NSM issuance would be less than the current -BTC-style issuance neglecting any burnt ZEC (ie. assuming the -amount of ZEC burnt is exactly 0).
          • +
          • It is calculated to be the lowest height after the second halving at +which the NSM issuance would be less than the current BTC-style issuance +neglecting any burnt ZEC (i.e. assuming the amount of ZEC burnt is +exactly 0).
          -

          This selection is intended to achieve Key Objective 6 while still -being a constant height. An alternative would be to have a dynamic -“latch” style activation which would calculate the activation height by -testing the “less than” conditional with every block after the second -halving. We prefer the pre-defined constant height parameter to give -everyone more time certainty at the cost of issuance -level certainty. The difference in up-front calculation versus -dynamic calculation is whether or not burns are accounted for (since -future burns cannot be calculated up-front). This means with the -pre-defined constant parameter approach, issuance will jump up -some amount at activation. This amount should be equivalent to all ZEC -burnt prior to that height times BLOCK_SUBSIDY_FRACTION. -For example, if a total of 100,000 ZEC were burnt prior to the -pre-defined constant activation height, then at activation the issuance -would be larger than BTC-style issuance by -100_000 ZEC * BLOCK_SUBSIDY_FRACTION which we calculate -equals 0.04126 ZEC. This example is chosen to demonstrate -that a very large burn amount (much larger than expected) would elevate -issuance by a relatively small amount. For this reason, we believe a -pre-defined constant is a better approach to achieving Key Objective 6 -than a “dynamic latch” logic because it is so much simpler to implement + +

          This selection is intended to achieve Key Objective 6 while still being at +a constant, predictable height. An alternative would be to have a dynamic +“latch”-style activation, which would calculate the activation height by +testing the “less than” conditional with every block after the second halving. +We prefer the pre-defined constant height parameter, to give everyone more +time certainty at the cost of issuance level certainty.

          + +

          The difference in up-front calculation versus dynamic calculation is in +whether or not burns are accounted for (since future burns cannot be +calculated up-front). This means with the pre-defined constant parameter +approach, issuance will jump up some amount at activation. This amount +should be equivalent to all ZEC burnt prior to that height times +\(\mathsf{BLOCK\_SUBSIDY\_FRACTION}\). For example, if a total of 100,000 ZEC +were burnt prior to the pre-defined constant activation height, then at +activation the issuance would be larger than BTC-style issuance by +\(100\_000\textsf{ ZEC} \cdot \mathsf{BLOCK\_SUBSIDY\_FRACTION}\), +which we calculate equals \(0.04126\) ZEC. This example is chosen to +demonstrate that a very large burn amount (much larger than expected) would +elevate issuance by a relatively small amount. For this reason, we believe +a pre-defined constant is a better approach to achieving Key Objective 6 +than a “dynamic latch” logic because it is so much simpler to implement and reason about.

          -

          MoneyReserveAfter(block_height) = The value of the Money -Reserve after the specified block height.

          -

          Issuance Calculation

          -

          At the DEPLOYMENT_BLOCK_HEIGHT, nodes should switch from -the current issuance calculation, to the following:

          -

          BlockSubsidy(block_height) = ceiling(BLOCK_SUBSIDY_FRACTION * MoneyReserveAfter(block_height - 1))

          -

          Rationale

          + +

          \(\mathsf{MoneyReserveAfter}(\mathsf{height}) =\) The value of the Money Reserve +after the specified block height.

          + +

          Issuance Calculation

          + +

          At the \(\mathsf{DEPLOYMENT\_BLOCK\_HEIGHT}\), nodes should switch from the current issuance +calculation, to the following:

          + +

          \(\mathsf{BlockSubsidy}(\mathsf{height}) = \mathsf{ceiling}(\mathsf{BLOCK\_SUBSIDY\_FRACTION} \cdot \mathsf{MoneyReserveAfter}(\mathsf{height} - 1))\)

          + +

          Applicability

          + +

          All of these changes apply identically to Mainnet and Testnet.

          + +

          Rationale

          +
            -
          • Using an exponential decay function satisfies Requirements -1 and 2 above.
          • -
          • We round up to the next zatoshi to satisfy Requirement -3 above.
          • +
          • Using an exponential decay function satisfies Requirements 1 and 2 above.
          • +
          • We round up to the next zatoshi to satisfy Requirement 3 above.
          -

          BLOCK_SUBSIDY_FRACTION

          -

          Let IntendedMoneyReserveFractionRemainingAfterFourYears -= 0.5.

          -

          The value 4126 / 10_000_000_000 satisfies the -approximation within +0.002%:

          -

          (1 - BLOCK_SUBSIDY_FRACTION)^PostBlossomHalvingInterval ≈ IntendedMoneyReserveFractionRemainingAfterFourYears

          -

          Meaning after a period of 4 years around half of Money Reserve will -be issued as block subsidies, thus satisfying Requirement -4.

          -

          The largest possible value in the Money Reserve is -MAX_MONEY, in the theoretically possible case that all -issued funds are burned. If this happened, the largest interim sum in -the block subsidy calculation would be -MAX_MONEY * 4126 / 10000000000.

          -

          This uses 62.91 bits, which is just under the 63 bit limit for 64-bit -signed two’s-complement integer amount types.

          + +

          BLOCK_SUBSIDY_FRACTION

          + +

          Let \(\mathsf{IntendedMoneyReserveFractionRemainingAfterFourYears} = 0.5\).

          + +

          The value \(4126 / 10\_000\_000\_000\) satisfies the approximation within \(\pm 0.002\%\):

          + +

          \((1 - \mathsf{BLOCK\_SUBSIDY\_FRACTION})^\mathsf{PostBlossomHalvingInterval} \approx \mathsf{IntendedMoneyReserveFractionRemainingAfterFourYears}\)

          + +

          This implies that after a period of 4 years around half of Money Reserve will +have been issued as block subsidies, thus satisfying Requirement 4.

          + +

          The largest possible value in the Money Reserve is \(\mathsf{MAX\_MONEY}\), in the +theoretically possible case that all issued funds are burned. If this happened, +the largest interim sum in the block subsidy calculation would be +\(\mathsf{MAX\_MONEY} \cdot 4126 / 10\_000\_000\_000\).

          + +

          This uses 62.91 bits, which is just under the 63-bit limit for signed +two’s complement 64-bit integer amount types.

          +

          The numerator could be brought closer to the limit by using a larger -denominator, but the difference in the amount issued would be very -small. So we chose a power-of-10 denominator for simplicity.

          +denominator, but the difference in the amount issued would be very small. So we +chose a power-of-10 denominator for simplicity.

          +

          TODO for ZIP owners: How many ZEC per day?

          -

          Visualization of the -Smoothed Curve

          -

          The following graph compares issuance for the current halving-based -step function vs the smoothed curve.

          + +

          Visualization of the Smoothed Curve

          + +

          The following graph compares issuance for the current halving-based step +function vs the smoothed curve.

          +
          - - +A graph showing a comparison of the halving-based step function vs the smoothed curve +
          A graph showing a comparison of the halving-based step function vs the smoothed curve
          -

          The graph below shows the balance of the Money Reserve assuming -smooth issuance is implemented.

          + +

          The graph below shows the balance of the Money Reserve assuming smooth issuance +is implemented.

          +
          - - +A graph showing the balance of the Money Reserve assuming smooth issuance is implemented +
          A graph showing the balance of the Money Reserve assuming smooth issuance is implemented
          -

          Deployment

          -

          The implementation of this ZIP MUST be deployed at the same time or -after the Network Sustainability Mechanism Burning function is deployed -(ZIP-0233).

          -

          Appendix: Simulation

          -

          The NSM -Simulator allows us to simulate the effects of this ZIP on the Money -Reserve and the block subsidy, as well as generate plots like the ones -above. Its output:

          -
          Last block is 47917869 in ~113.88 years
          -

          indicates that, assuming that no ZEC is ever burned, the Money -Reserve will be depleted after 113.88 years, and the block subsidy will -be 0 ZEC after that point.

          + +

          Appendix: Simulation

          + +

          The NSM Simulator allows us to +simulate the effects of this ZIP on the Money Reserve and the block subsidy, as +well as generate plots like the ones above. Its output:

          + +
          Last block is 47917869 in ~113.88 years
          +
          + +

          indicates that, assuming that no ZEC is ever burned, the Money Reserve will be +depleted after 113.88 years, and the block subsidy will be 0 ZEC after that +point.

          +

          This fragment of the output:

          +
          Halving  1 at block  1680000:
             NSM subsidies:    262523884819889 (~ 2625238.848 ZEC,        1.563 ZEC per block)
             legacy subsidies: 262500000000000 (~ 2625000.000 ZEC,        1.562 ZEC per block)
          -  difference:           23884819889 (~         238 ZEC),         NSM/legacy: 1.0001
          -

          shows that the difference between the smoothed out and the current -issuance schemes is 238 ZEC after 1680000 blocks (around 4 years).

          -

          Appendix: Considerations -for the Future

          -

          Future protocol changes may not increase the payout rate to a -reasonable approximation beyond the four year half-life constraint.

          -

          References

          -

          [1] RFC-2119: https://datatracker.ietf.org/doc/html/rfc2119

          -

          [2] ZIP-200: Network Upgrade Mechanism

          -

          [3] ZIP_233: Network Sustainability Mechanism: -Burning

          + difference: 23884819889 (~ 238 ZEC), NSM/legacy: 1.0001 + + +

          shows that the difference between the smoothed out and the current issuance +schemes is 238 ZEC after 1680000 blocks (around 4 years).

          + +

          Appendix: Considerations for the Future

          + +

          Future protocol changes may not increase the payout rate to a reasonable +approximation beyond the four year half-life constraint.

          + +

          Deployment

          + +

          This ZIP is proposed to activate with Network Upgrade 7. 10 +It MUST be deployed at the same time or after ZIP 233 (“NSM: Burning” 6).

          + +

          References

          + + diff --git a/rendered/zip-0235.html b/rendered/zip-0235.html index 24114d165..c893b8541 100644 --- a/rendered/zip-0235.html +++ b/rendered/zip-0235.html @@ -3,7 +3,9 @@ ZIP 235: Burn 60% of Transaction Fees - + + + @@ -20,108 +22,146 @@ Category: Ecosystem Created: 2023-09-21 License: BSD-2-Clause -Discussions-To: <https://github.com/zcash/zips/issues/924> -

          Terminology

          -

          The key words “MUST”, “SHOULD”, “SHOULD NOT”, “MAY”, “RECOMMENDED”, -“OPTIONAL”, and “REQUIRED” in this document are to be interpreted as -described in RFC 2119. [1]

          -

          The term “network upgrade” in this document is to be interpreted as -described in ZIP 200. [2]

          -

          “Block Subsidy” - the algorithmic issuance of ZEC on block creation. -Part of the consensus rules. Split between the miner and the Dev Fund. -Also known as Block Reward.

          -

          “Issuance” - The method by which ZEC becomes available for -circulation on the network.

          -

          “We” - the ZIP authors, owners listed in the above front matter

          -

          Abstract

          -

          We propose to burn 60% of transaction fees, while the remaining 40% -be directed as before, providing a deflationary effect, and building the -groundwork for long-term support of the Zcash network via the new block -subsidy rules proposed by ZIP-234.

          -

          Motivation

          -

          ZIP-233 (“Network Sustainability Mechanism: Burning”) describes a +Discussions-To: <https://github.com/zcash/zips/issues/924> + + +

          Terminology

          + +

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

          + +

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

          + +

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

          + +

          The terms “Mainnet” and “Testnet” are to be interpreted as described in +§ 3.12 ‘Mainnet and Testnet’. 4

          + +

          The symbol “\(\,\cdot\,\)” means multiplication, as described in § 2 ‘Notation’. +5

          + +

          “ZEC/TAZ” refers to the native currency of Zcash on a given network, i.e. +ZEC on Mainnet and TAZ on Testnet.

          + +

          The terms “Block Subsidy”, “Issuance”, and “Burning” are to be interpreted +as described in ZIP 233. 6

          + +

          Abstract

          + +

          This ZIP proposes to burn 60% of transaction fees, while the remaining 40% is +directed as before, providing a deflationary effect, and building the groundwork +for long-term support of the Zcash network via the new block subsidy rules +proposed by ZIP 234 7.

          + +

          Motivation

          + +

          ZIP 233 (“Network Sustainability Mechanism: Burning” 6) describes a method by which ZEC can be burned to support network sustainability.

          -

          By introducing a requirement that a certain proportion of transaction -fees be burned, we ensure that ZEC will be removed from circulating -supply to contribute to the long-term sustainability of the network as -described below:

          -

          Benefits to the Network

          -
            -
          1. Network Sustainability: This mechanism involves -temporarily reducing the supply of ZEC, similar to asset burning in -Ethereum’s EIP-1559, but with long-term sustainability benefits, as the -burned funds effectively boost future mining rewards, making it an -attractive option for current and future Zcash users.
          2. -
          3. Incentivizing Transaction Inclusion: By maintaining -a 40% share of transaction fees for miners, we continue incentivizing -miners to prioritize including transactions in their blocks. This helps -ensure the continued efficient processing of transactions and supports a -robust and responsive network.
          4. -
          5. Aligning Interests: Burning transaction fees aligns -the interests of miners with the long-term health of the network, -incentivizing them to prioritize security and efficiency. As miners -focus on maintaining a robust network, overall adoption and usage can -increase, leading to higher transaction volumes in the long run. This -structure discourages short-term profit-seeking behaviors, as miners -benefit more from a stable and thriving ecosystem than from engaging in -malicious activities that could undermine the network’s reputation and -security.
          6. -
          7. Future-Proofing the Network: Burning a portion of -transaction fees is a forward-looking approach that prepares the Zcash -network for future challenges and opportunities. It establishes a -financial buffer that can be instrumental in addressing unforeseen -issues and seizing strategic advantages as the Zcash ecosystem -evolves.
          8. + +

            By introducing a requirement that a certain proportion of transaction fees be +burned, we ensure that ZEC will be removed from circulating supply to contribute +to the long-term sustainability of the network as described below:

            + +

            Benefits to the Network

            + +
              +
            1. Network Sustainability: This mechanism involves temporarily reducing the +supply of ZEC, similar to asset burning in Ethereum’s EIP-1559 8, +but with long-term sustainability benefits, as the burned funds effectively +boost future mining rewards, making it an attractive option for current and +future Zcash users.
            2. +
            3. Incentivizing Transaction Inclusion: By maintaining a 40% share of +transaction fees for miners, we continue incentivizing miners to prioritize +including transactions in their blocks. This helps ensure the continued +efficient processing of transactions and supports a robust and responsive +network.
            4. +
            5. Aligning Interests: Burning transaction fees aligns the interests +of miners with the long-term health of the network, incentivizing them +to prioritize security and efficiency. As miners focus on maintaining a +robust network, overall adoption and usage can increase, leading to higher +transaction volumes in the long run. This structure discourages short-term +profit-seeking behaviors, as miners benefit more from a stable and thriving +ecosystem than from engaging in malicious activities that could undermine the +network’s reputation and security.
            6. +
            7. Future-Proofing the Network: Burning a portion of transaction fees +is a forward-looking approach that prepares the Zcash network for future +challenges and opportunities. It establishes a financial buffer that can be +instrumental in addressing unforeseen issues and seizing strategic advantages +as the Zcash ecosystem evolves.
            -

            Requirements

            + +

            Requirements

            +
              -
            • For each block, at least 60% (rounded down) of the total fees are to -be burned.
            • -
            • No restrictions are placed on the destination of the remaining -proportion of fees.
            • +
            • For each block, at least 60% (rounded down) of the total fees are to be +burned.
            • +
            • No restrictions are placed on the destination of the remaining proportion of +fees.
            • Any fractions are rounded in favor of the miner.
            -

            Specification

            -

            Consensus Rule Changes

            -

            For a given block, the coinbase transaction MUST have a -burnAmount that is greater than or equal to -floor(transactionFees * 6 / 10).

            -

            Previous transaction versions are not supported for coinbase -transactions, due to there being no explicit mechanism to burn the -required funds.

            -

            Deployment

            -

            The implementation of this ZIP MUST be deployed at the same time or -after ZIP-233 (“NSM: Burning”), and ZIP-234 (“NSM: Issuance -Smoothing”).

            -

            Rationale

            -

            We believe the proposed changes to be relatively low-impact in terms -of implementation and protocol changes. Additionally, transaction fees -are currently small enough that the reduction in miner fees is unlikely -to be a concern.

            -

            Estimated impact on miners

            -

            Over 100,000 blocks starting at block 2235515, there were 316130 -transactions. 60608 of them are categorized as ‘sandblasting’ -transactions. The remaining transactions have an average of 5.46 logical -actions (see ZIP-317 [4]).

            -

            The total fees paid to miners from those transactions, assuming the -ZIP-317 regime, would be 87.86 ZEC. 100,000 blocks is approximately 3 -months of blocks. Extrapolating to a year, we would expect 351.44 ZEC in -fees paid to miners over a year.

            -

            If 60% of these fees burned, that would be 210.864 ZEC per year. -[5]

            -

            Considerations for the -Future

            -

            If transaction fees were to increase, further modifications can -easily be proposed to alter the 60%/40% split. Finding the optimal fee -split may require an iterative approach involving adjustments based on -real-world data and network dynamics.

            -

            Looking further into the future, there may come a time when the -transaction fees become greater than the block subsidy issuance. At that -time we may need to reconsider the 60/40 split. However, this will -likely not be the case for the next 8-10 years due to forecasts based on -issuance models and network traffic.

            -

            Further ZIPs may be proposed to burn ZEC in various ways to support -network sustainability, including but not limited to:

            + +

            Specification

            + +

            Consensus Rule Changes

            + +

            For a given block, the coinbase transaction MUST have a \(\mathsf{burn\_amount}\), +as defined in 6, that is greater than or equal to +\(\mathsf{floor}(\mathsf{transactionFees} \cdot 6 / 10)\).

            + +

            The version of a coinbase transaction MUST be v6 or later 9.

            + +

            Applicability

            + +

            All of these changes apply identically to Mainnet and Testnet.

            + +

            Rationale

            + +

            We believe the proposed changes to be relatively low-impact in terms of +implementation and protocol changes. Additionally, transaction fees are +currently small enough that the reduction in miner fees is unlikely to be a +concern.

            + +

            Rationale for requiring the coinbase transaction to be v6 or later

            + +

            There is no explicit mechanism in prior transaction versions to burn the +required funds. Since \(\mathsf{burn\_amount} = 0\) for transaction versions +prior to v6, absent the rule about the coinbase transaction version it +would be technically possible to satisfy the constraint on \(\mathsf{burn\_amount}\) +with earlier versions than v6, but only when \(\mathsf{transactionFees} = 0\). +That would introduce a corner case in the transaction consensus rules that +is not useful, since it is expected that the \(\mathsf{transactionFees}\) +will normally be non-zero.

            + +

            Estimated impact on miners

            + +

            Over 100,000 blocks starting at block 2235515, there were 316130 transactions. +60608 of them are categorized as ‘sandblasting’ transactions. The remaining +transactions have an average of 5.46 logical actions (see ZIP 317 10).

            + +

            The total fees paid to miners from those transactions, assuming the ZIP 317 +regime, would be 87.86 ZEC. 100,000 blocks is approximately 3 months of blocks. +Extrapolating to a year, we would expect 351.44 ZEC in fees paid to miners over +a year.

            + +

            If 60% of these fees burned, that would be 210.864 ZEC per year. 11

            + +

            Considerations for the Future

            + +

            If transaction fees were to increase, further modifications can easily be +proposed to alter the 60%/40% split. Finding the optimal fee split may require +an iterative approach involving adjustments based on real-world data and network +dynamics.

            + +

            Looking further into the future, there may come a time when the transaction fees +become greater than the block subsidy issuance. At that time we may need to +reconsider the 60/40 split. However, this will likely not be the case for the +next 8–10 years due to forecasts based on issuance models and network traffic.

            + +

            Further ZIPs may be proposed to burn ZEC in various ways to support network +sustainability, including but not limited to:

            +
            • ZSA fees
            • Fees and donations specific to decentralized applications
            • @@ -129,13 +169,64 @@

              Considerations for the
            • Cross-chain bridge usage / Cross-chain messaging
            • Note sorting micro-transactional fees
            -

            References

            -

            [1] RFC-2119: https://datatracker.ietf.org/doc/html/rfc2119

            -

            [2] ZIP 200: Network Upgrade Mechanism

            -

            [3] ZIP 233: Establish the Zcash Sustainability -Fund on the Protocol Level

            -

            [4] ZIP 317: Proportional Transfer Fee -Mechanism

            -

            [5] https://github.com/eigerco/zsf-fee-estimator

            + +

            Deployment

            + +

            The implementation of this ZIP MUST be deployed at the same time or after +ZIP 233 (“NSM: Burning” 6), and ZIP 234 (“NSM: Issuance Smoothing” +7).

            + +

            References

            + + diff --git a/rendered/zip-0244.html b/rendered/zip-0244.html index e607a6d65..538b63d65 100644 --- a/rendered/zip-0244.html +++ b/rendered/zip-0244.html @@ -3,7 +3,9 @@ ZIP 244: Transaction Identifier Non-Malleability - + + +
            @@ -391,11 +393,11 @@

            The nonmalleable transaction identifier specified by this ZIP will be used in the place of the current malleable transaction identifier within the Merkle tree committed to by the hashMerkleRoot value. However, this change now means that hashMerkleRoot is not sufficient to fully commit to the transaction data, including witnesses, that appear within the block.

            As a consequence, we now need to add a new commitment to the block header. This commitment will be the root of a Merkle tree having leaves that are transaction authorizing data commitments, produced according to the Authorizing Data Commitment part of this specification. The insertion order for this Merkle tree MUST be identical to the insertion order of transaction identifiers into the Merkle tree that is used to construct hashMerkleRoot, such that a path through this Merkle tree to a transaction identifies the same transaction as that path reaches in the tree rooted at hashMerkleRoot.

            This new commitment is named hashAuthDataRoot and is the root of a binary Merkle tree of transaction authorizing data commitments having height - \(\mathsf{ceil(log_2(tx\_count))}\) + \(\mathsf{ceil(log_2(tx\_count))}\!\) , padded with leaves having the "null" hash value [0u8; 32]. Note that \(\mathsf{log_2(tx\_count)}\) is well-defined because - \(\mathsf{tx\_count} > 0\) + \(\mathsf{tx\_count} > 0\!\) , due to the coinbase transaction in each block. Non-leaf hashes in this tree are BLAKE2b-256 hashes personalized by the string "ZcashAuthDatHash".

            Changing the block header format to allow space for an additional commitment is somewhat invasive. Instead, the name and meaning of the hashLightClientRoot field, described in ZIP 221 4, is changed.

            hashLightClientRoot is renamed to hashBlockCommitments. The value of this hash is the BLAKE2b-256 hash personalized by the string "ZcashBlockCommit" of the following elements:

            diff --git a/rendered/zip-0253.html b/rendered/zip-0253.html index ebe35ea36..1c4dadbae 100644 --- a/rendered/zip-0253.html +++ b/rendered/zip-0253.html @@ -3,7 +3,6 @@ ZIP 253: Deployment of the NU6 Network Upgrade - @@ -14,140 +13,120 @@ Category: Consensus / Network Created: 2024-07-17 License: MIT -Discussions-To: <https://github.com/zcash/zips/issues/806> -

            Terminology

            -

            The key word “MUST” in this document are to be interpreted as -described in BCP 14 1 when, and only when, they appear in -all capitals.

            -

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

            -

            The terms “Testnet” and “Mainnet” are to be interpreted as described -in section 3.12 of the Zcash Protocol Specification 3.

            -

            Abstract

            +Discussions-To: <https://github.com/zcash/zips/issues/806> + + +

            Terminology

            + +

            The key word “MUST” in this document are to be interpreted as described in +BCP 14 1 when, and only when, they appear in all capitals.

            + +

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

            + +

            The terms “Testnet” and “Mainnet” are to be interpreted as described in +section 3.12 of the Zcash Protocol Specification 3.

            + +

            Abstract

            +

            This proposal defines the deployment of the NU6 network upgrade.

            -

            Specification

            -

            NU6 deployment

            -

            The primary sources of information about NU6 consensus protocol -changes are:

            + +

            Specification

            + +

            NU6 deployment

            + +

            The primary sources of information about NU6 consensus protocol changes are:

            +
              -
            • The Zcash Protocol Specification 4.
            • -
            • ZIP 200: Network Upgrade Mechanism 5.
            • -
            • ZIP 236: Blocks should balance exactly 6.
            • -
            • ZIP 1015: Block Reward Allocation for Non-Direct Development Funding -7.
            • -
            • ZIP 2001: Lockbox Funding Streams 8.
            • +
            • The Zcash Protocol Specification 4.
            • +
            • ZIP 200: Network Upgrade Mechanism 2.
            • +
            • ZIP 236: Blocks should balance exactly 5.
            • +
            • ZIP 1015: Block Reward Allocation for Non-Direct Development Funding 6.
            • +
            • ZIP 2001: Lockbox Funding Streams 7.
            -

            The network handshake and peer management mechanisms defined in ZIP -201 9 also apply to this upgrade.

            -

            The following ZIPs have been updated in varying degrees to take into -account NU6:

            + +

            The network handshake and peer management mechanisms defined in ZIP 201 8 also apply to this upgrade.

            + +

            The following ZIPs have been updated in varying degrees to take into account NU6:

            +
              -
            • ZIP 207: Funding Streams 10.
            • -
            • ZIP 214: Consensus rules for a Zcash Development Fund 11.
            • +
            • ZIP 207: Funding Streams 9.
            • +
            • ZIP 214: Consensus rules for a Zcash Development Fund 10.
            -

            The following network upgrade constants 12 -are defined for the NU6 upgrade:

            + +

            The following network upgrade constants 2 are defined for the NU6 upgrade:

            +
            CONSENSUS_BRANCH_ID
            -
            -0xC8E71055 -
            +
            0xC8E71055
            +
            ACTIVATION_HEIGHT (NU6)
            -
            -Testnet: 2976000 -
            -
            -Mainnet: 2726400 -
            +
            Testnet: 2976000
            + +
            Mainnet: 2726400
            +
            MIN_NETWORK_PROTOCOL_VERSION (NU6)
            -
            -Testnet: 170110 -
            -
            -Mainnet: 170120 -
            +
            Testnet: 170110
            + +
            Mainnet: 170120
            -

            For each network (Testnet and Mainnet), nodes compatible with NU6 -activation on that network MUST advertise a network protocol version -that is greater than or equal to the MIN_NETWORK_PROTOCOL_VERSION (NU6) -for that activation.

            -

            Backward compatibility

            -

            Prior to the network upgrade activating on each network, NU6 and -pre-NU6 nodes are compatible and can connect to each other. However, NU6 -nodes will have a preference for connecting to other NU6 nodes, so -pre-NU6 nodes will gradually be disconnected in the run up to -activation.

            -

            Once the network upgrades, even though pre-NU6 nodes can still accept -the numerically larger protocol version used by NU6 as being valid, NU6 -nodes will always disconnect peers using lower protocol versions.

            -

            NU6 does not define a new transaction version or impose a new minimum -transaction version. NU6 transactions are therefore in the same v4 or v5 -formats as NU5 transactions. This does not imply that transactions are -valid across the NU6 activation, since signatures MUST use the -appropriate consensus branch ID.

            -

            References

            -
            + +

            For each network (Testnet and Mainnet), nodes compatible with NU6 activation on that network MUST advertise a network protocol version that is greater than or equal to the MIN_NETWORK_PROTOCOL_VERSION (NU6) for that activation.

            + +

            Backward compatibility

            + +

            Prior to the network upgrade activating on each network, NU6 and pre-NU6 nodes are compatible and can connect to each other. However, NU6 nodes will have a preference for connecting to other NU6 nodes, so pre-NU6 nodes will gradually be disconnected in the run up to activation.

            + +

            Once the network upgrades, even though pre-NU6 nodes can still accept the numerically larger protocol version used by NU6 as being valid, NU6 nodes will always disconnect peers using lower protocol versions.

            + +

            NU6 does not define a new transaction version or impose a new minimum transaction version. NU6 transactions are therefore in the same v4 or v5 formats as NU5 transactions. This does not imply that transactions are valid across the NU6 activation, since signatures MUST use the appropriate consensus branch ID.

            + +

            References

            + +

              -
            1. Information on BCP 14 — -“RFC 2119: Key words for use in RFCs to Indicate Requirement Levels” and -“RFC 8174: Ambiguity of Uppercase vs Lowercase in RFC 2119 Key -Words”↩︎

            2. -
            3. ZIP 200: -Network Upgrade Mechanism↩︎

            4. -
            5. Zcash Protocol Specification, -Version 2024.5.1 [NU6]. Section 3.12: Mainnet and Testnet↩︎

            6. -
            7. Zcash -Protocol Specification, Version 2024.5.1 or later↩︎

            8. -
            9. ZIP 200: -Network Upgrade Mechanism↩︎

            10. -
            11. ZIP 236: -Blocks should balance exactly↩︎

            12. -
            13. ZIP 1015: -Block Reward Allocation for Non-Direct Development Funding↩︎

            14. -
            15. ZIP 2001: -Lockbox Funding Streams↩︎

            16. -
            17. ZIP 201: -Network Peer Management for Overwinter↩︎

            18. -
            19. ZIP 207: -Funding Streams↩︎

            20. -
            21. ZIP 214: -Consensus rules for a Zcash Development Fund↩︎

            22. -
            23. ZIP 200: -Network Upgrade Mechanism↩︎

            24. + +
            25. +

              Information on BCP 14 — “RFC 2119: Key words for use in RFCs to Indicate Requirement Levels” and “RFC 8174: Ambiguity of Uppercase vs Lowercase in RFC 2119 Key Words”  ↩︎

              +
            26. + +
            27. +

              ZIP 200: Network Upgrade Mechanism  ↩︎

              +
            28. + +
            29. +

              Zcash Protocol Specification, Version 2024.5.1 [NU6]. Section 3.12: Mainnet and Testnet  ↩︎

              +
            30. + +
            31. +

              Zcash Protocol Specification, Version 2024.5.1 or later  ↩︎

              +
            32. + +
            33. +

              ZIP 236: Blocks should balance exactly  ↩︎

              +
            34. + +
            35. +

              ZIP 1015: Block Reward Allocation for Non-Direct Development Funding  ↩︎

              +
            36. + +
            37. +

              ZIP 2001: Lockbox Funding Streams  ↩︎

              +
            38. + +
            39. +

              ZIP 201: Network Peer Management for Overwinter  ↩︎

              +
            40. + +
            41. +

              ZIP 207: Funding Streams  ↩︎

              +
            42. + +
            43. +

              ZIP 214: Consensus rules for a Zcash Development Fund  ↩︎

              +
            44. +
            -
            + diff --git a/rendered/zip-0254.html b/rendered/zip-0254.html index 63c5e528b..8e33af549 100644 --- a/rendered/zip-0254.html +++ b/rendered/zip-0254.html @@ -3,7 +3,6 @@ ZIP 254: Deployment of the NU7 Network Upgrade - @@ -14,102 +13,101 @@ Category: Consensus / Network Created: 2024-10-31 License: MIT -Discussions-To: <https://github.com/zcash/zips/issues/839> -

            Terminology

            -

            The key word “MUST” in this document are to be interpreted as -described in BCP 14 1 when, and only when, they appear in -all capitals.

            -

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

            -

            The terms “Testnet” and “Mainnet” are to be interpreted as described -in section 3.12 of the Zcash Protocol Specification 3.

            -

            Abstract

            +Discussions-To: <https://github.com/zcash/zips/issues/839> + + +

            Terminology

            + +

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

            + +

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

            + +

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

            + +

            The terms “Mainnet” and “Testnet” are to be interpreted as described in +§ 3.12 ‘Mainnet and Testnet’. 4

            + +

            Abstract

            +

            This proposal defines the deployment of the NU7 network upgrade.

            -

            Specification

            -

            NU7 deployment

            -

            The primary sources of information about NU7 consensus protocol -changes are:

            + +

            Specification

            + +

            NU7 deployment

            + +

            The primary sources of information about NU7 consensus protocol changes are:

            +
              -
            • The Zcash Protocol Specification 4.
            • -
            • ZIP 200: Network Upgrade Mechanism 5.
            • +
            • The Zcash Protocol Specification 3.
            • +
            • ZIP 200: Network Upgrade Mechanism 2.
            -

            The network handshake and peer management mechanisms defined in ZIP -201 6 also apply to this upgrade.

            -

            The following network upgrade constants 7 are -defined for the NU7 upgrade:

            + +

            The network handshake and peer management mechanisms defined in ZIP 201 +5 also apply to this upgrade.

            + +

            The following network upgrade constants 2 are defined for the +NU7 upgrade:

            +
            CONSENSUS_BRANCH_ID
            -
            -0x77190AD8 -
            +
            0x77190AD8
            +
            ACTIVATION_HEIGHT (NU7)
            -
            -Testnet: TBD -
            -
            -Mainnet: TBD -
            +
            Testnet: TBD
            + +
            Mainnet: TBD
            +
            MIN_NETWORK_PROTOCOL_VERSION (NU7)
            -
            -Testnet: 170130 -
            -
            -Mainnet: 170140 -
            +
            Testnet: 170130
            + +
            Mainnet: 170140
            -

            For each network (Testnet and Mainnet), nodes compatible with NU7 -activation on that network MUST advertise a network protocol version -that is greater than or equal to the MIN_NETWORK_PROTOCOL_VERSION (NU7) -for that activation.

            -

            Backward compatibility

            -

            Prior to the network upgrade activating on each network, NU7 and -pre-NU7 nodes are compatible and can connect to each other. However, NU7 -nodes will have a preference for connecting to other NU7 nodes, so -pre-NU7 nodes will gradually be disconnected in the run up to -activation.

            -

            Once the network upgrades, even though pre-NU7 nodes can still accept -the numerically larger protocol version used by NU7 as being valid, NU7 -nodes will always disconnect peers using lower protocol versions.

            -

            References

            -
            + +

            For each network (Testnet and Mainnet), nodes compatible with NU7 activation +on that network MUST advertise a network protocol version that is greater +than or equal to the MIN_NETWORK_PROTOCOL_VERSION (NU7) for that activation.

            + +

            Backward compatibility

            + +

            Prior to the network upgrade activating on each network, NU7 and pre-NU7 +nodes are compatible and can connect to each other. However, NU7 nodes will +have a preference for connecting to other NU7 nodes, so pre-NU7 nodes will +gradually be disconnected in the run up to activation.

            + +

            Once the network upgrades, even though pre-NU7 nodes can still accept the +numerically larger protocol version used by NU7 as being valid, NU7 nodes +will always disconnect peers using lower protocol versions.

            + +

            References

            + +
            + diff --git a/rendered/zip-0304.html b/rendered/zip-0304.html index 453038ad0..0adfd5ac9 100644 --- a/rendered/zip-0304.html +++ b/rendered/zip-0304.html @@ -3,7 +3,9 @@ ZIP 304: Sapling Address Signatures - + + +
            @@ -52,11 +54,11 @@ \(\mathsf{PRF}^\mathsf{nfSapling}_\mathsf{nk}(ρ)\) 10
          9. - \(\mathsf{SpendAuthSig.RandomizePrivate}(ι, \mathsf{sk})\) + \(\mathsf{SpendAuthSig.RandomizePrivate}(ι, \mathsf{sk})\!\) , - \(\mathsf{SpendAuthSig.RandomizePublic}(ι, \mathsf{vk})\) + \(\mathsf{SpendAuthSig.RandomizePublic}(ι, \mathsf{vk})\!\) , - \(\mathsf{SpendAuthSig.Sign}(\mathsf{sk}, m)\) + \(\mathsf{SpendAuthSig.Sign}(\mathsf{sk}, m)\!\) , and \(\mathsf{SpendAuthSig.Verify}(\mathsf{vk}, m, σ)\) 11
          10. @@ -74,7 +76,7 @@ means the concatenation of sequences \(a\) then - \(b\) + \(b\!\) .
          11. \(\mathsf{repr}_\mathbb{J}(P)\) @@ -84,9 +86,9 @@
          12. \(\mathsf{BLAKE2b}\text{-}\mathsf{256}(p, x)\) refers to unkeyed BLAKE2b-256 in sequential mode, with an output digest length of 32 bytes, 16-byte personalization string - \(p\) + \(p\!\) , and input - \(x\) + \(x\!\) .
          13. @@ -107,7 +109,7 @@
          14. A fake Sapling note with a value of \(1\) zatoshi and - \(\mathsf{rcm} = 0\) + \(\mathsf{rcm} = 0\!\) .
          15. A Sapling commitment tree that is empty except for the commitment for the fake note.
          16. @@ -115,10 +117,10 @@

            The inputs to the signature algorithm are:

            • The payment address - \((\mathsf{d}, \mathsf{pk_d})\) + \((\mathsf{d}, \mathsf{pk_d})\!\) ,
            • Its corresponding expanded spending key - \((\mathsf{ask}, \mathsf{nsk}, \mathsf{ovk})\) + \((\mathsf{ask}, \mathsf{nsk}, \mathsf{ovk})\!\) ,
            • The SLIP-44 15 coin type, and
            • The message @@ -131,17 +133,17 @@ \((\mathsf{ak}, \mathsf{nk}, \mathsf{ovk})\) from the expanded spending key.
            • Let - \(\mathsf{g_d} = \mathsf{DiversifyHash}(\mathsf{d})\) + \(\mathsf{g_d} = \mathsf{DiversifyHash}(\mathsf{d})\!\) .
            • Let - \(\mathsf{cm} = \mathsf{NoteCommit}^\mathsf{Sapling}_0(\mathsf{repr}_\mathbb{J}(\mathsf{g_d}), \mathsf{repr}_\mathbb{J}(\mathsf{pk_d}), 1)\) + \(\mathsf{cm} = \mathsf{NoteCommit}^\mathsf{Sapling}_0(\mathsf{repr}_\mathbb{J}(\mathsf{g_d}), \mathsf{repr}_\mathbb{J}(\mathsf{pk_d}), 1)\!\) .
            • Let \(\mathsf{rt}\) be the root of a Merkle tree with depth \(\mathsf{MerkleDepth}^\mathsf{Sapling}\) and hashing function - \(\mathsf{MerkleCRH}^\mathsf{Sapling}\) + \(\mathsf{MerkleCRH}^\mathsf{Sapling}\!\) , containing \(\mathsf{cm}\) at position 0, and @@ -150,45 +152,45 @@
            • Let \(path\) be the Merkle path from position 0 to - \(\mathsf{rt}\) + \(\mathsf{rt}\!\) . 4
            • Let - \(\mathsf{cv} = \mathsf{ValueCommit}_0(1)\) + \(\mathsf{cv} = \mathsf{ValueCommit}_0(1)\!\) .
              • This is a constant and may be pre-computed.
            • Let - \(\mathsf{nf} = \mathsf{PRF}^\mathsf{nfSapling}_{\mathsf{repr}_\mathbb{J}(\mathsf{nk})}(\mathsf{repr}_\mathbb{J}(\mathsf{MixingPedersenHash}(\mathsf{cm}, 0)))\) + \(\mathsf{nf} = \mathsf{PRF}^\mathsf{nfSapling}_{\mathsf{repr}_\mathbb{J}(\mathsf{nk})}(\mathsf{repr}_\mathbb{J}(\mathsf{MixingPedersenHash}(\mathsf{cm}, 0)))\!\) .
            • Select a random - \(Îą\) + \(Îą\!\) .
            • Let - \(\mathsf{rk} = \mathsf{SpendAuthSig.RandomizePublic}(Îą, \mathsf{ak})\) + \(\mathsf{rk} = \mathsf{SpendAuthSig.RandomizePublic}(Îą, \mathsf{ak})\!\) .
            • Let \(zkproof\) be the byte sequence representation of a Sapling spend proof with primary input \((\mathsf{rt}, \mathsf{cv}, \mathsf{nf}, \mathsf{rk})\) and auxiliary input - \((path, 0, \mathsf{g_d}, \mathsf{pk_d}, 1, 0, \mathsf{cm}, 0, Îą, \mathsf{ak}, \mathsf{nsk})\) + \((path, 0, \mathsf{g_d}, \mathsf{pk_d}, 1, 0, \mathsf{cm}, 0, Îą, \mathsf{ak}, \mathsf{nsk})\!\) . 5
            • Let - \(\mathsf{rsk} = \mathsf{SpendAuthSig.RandomizePrivate}(Îą, \mathsf{ask})\) + \(\mathsf{rsk} = \mathsf{SpendAuthSig.RandomizePrivate}(Îą, \mathsf{ask})\!\) .
            • Let \(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 - \(digest = \mathsf{BLAKE2b}\text{-}\mathsf{256}(\texttt{"ZIP304Signed"}\,||\,coinType, zkproof\,||\,msg)\) + \(digest = \mathsf{BLAKE2b}\text{-}\mathsf{256}(\texttt{“ZIP304Signed”}\,||\,coinType, zkproof\,||\,msg)\!\) .
            • Let - \(spendAuthSig = \mathsf{SpendAuthSig.Sign}(\mathsf{rsk}, digest)\) + \(spendAuthSig = \mathsf{SpendAuthSig.Sign}(\mathsf{rsk}, digest)\!\) .
            • Return - \((\mathsf{nf}, \mathsf{rk}, zkproof, spendAuthSig)\) + \((\mathsf{nf}, \mathsf{rk}, zkproof, spendAuthSig)\!\) .
            @@ -196,14 +198,14 @@

            The inputs to the verification algorithm are:

            • The payment address - \((\mathsf{d}, \mathsf{pk_d})\) + \((\mathsf{d}, \mathsf{pk_d})\!\) ,
            • The SLIP-44 15 coin type,
            • The message \(msg\) that is claimed to be signed, and
            • The ZIP 304 signature - \((\mathsf{nf}, \mathsf{rk}, zkproof, spendAuthSig)\) + \((\mathsf{nf}, \mathsf{rk}, zkproof, spendAuthSig)\!\) .

            The signature MUST be verified as follows:

            @@ -212,20 +214,20 @@ \(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).
          17. Let - \(digest = \mathsf{BLAKE2b}\text{-}\mathsf{256}(\texttt{"ZIP304Signed"}\,||\,coinType, zkproof\,||\,msg)\) + \(digest = \mathsf{BLAKE2b}\text{-}\mathsf{256}(\texttt{“ZIP304Signed”}\,||\,coinType, zkproof\,||\,msg)\!\) .
          18. If - \(\mathsf{SpendAuthSig.Verify}(\mathsf{rk}, digest, spendAuthSig) = 0\) + \(\mathsf{SpendAuthSig.Verify}(\mathsf{rk}, digest, spendAuthSig) = 0\!\) , return false.
          19. Let - \(\mathsf{cm} = \mathsf{NoteCommit}^\mathsf{Sapling}_0(\mathsf{repr}_\mathbb{J}(\mathsf{DiversifyHash}(\mathsf{d})), \mathsf{repr}_\mathbb{J}(\mathsf{pk_d}), 1)\) + \(\mathsf{cm} = \mathsf{NoteCommit}^\mathsf{Sapling}_0(\mathsf{repr}_\mathbb{J}(\mathsf{DiversifyHash}(\mathsf{d})), \mathsf{repr}_\mathbb{J}(\mathsf{pk_d}), 1)\!\) .
          20. Let \(\mathsf{rt}\) be the root of a Merkle tree with depth \(\mathsf{MerkleDepth}^\mathsf{Sapling}\) and hashing function - \(\mathsf{MerkleCRH}^\mathsf{Sapling}\) + \(\mathsf{MerkleCRH}^\mathsf{Sapling}\!\) , containing \(\mathsf{cm}\) at position 0, and @@ -234,10 +236,10 @@
          21. Let \(path\) be the Merkle path from position 0 to - \(\mathsf{rt}\) + \(\mathsf{rt}\!\) . 4
          22. Let - \(\mathsf{cv} = \mathsf{ValueCommit}_0(1)\) + \(\mathsf{cv} = \mathsf{ValueCommit}_0(1)\!\) .
            • This is a constant and may be pre-computed.
            • @@ -246,17 +248,17 @@
            • Decode and verify \(zkproof\) as a Sapling spend proof with primary input - \((\mathsf{rt}, \mathsf{cv}, \mathsf{nf}, \mathsf{rk})\) + \((\mathsf{rt}, \mathsf{cv}, \mathsf{nf}, \mathsf{rk})\!\) . 5 If verification fails, return false.
            • Return true.

            Signature encoding

            The raw form of a ZIP 304 signature is - \(\mathsf{nf}\,||\,\mathsf{LEBS2OSP}_{256}(\mathsf{repr}_{\mathbb{J}}(\mathsf{rk}))\,||\,zkproof\,||\,spendAuthSig\) + \(\mathsf{nf}\,||\,\mathsf{LEBS2OSP}_{256}(\mathsf{repr}_{\mathbb{J}}(\mathsf{rk}))\,||\,zkproof\,||\,spendAuthSig\!\) , for a total size of 320 bytes.

            When encoding a ZIP 304 signature in a human-readable format, implementations SHOULD use standard Base64 for compatibility with the signmessage and verifymessage RPC methods in zcashd. ZIP 304 signatures in this form are 428 bytes. The encoded form is the string - \(\texttt{"zip304:"}\) + \(\texttt{“zip304:”}\) followed by the result of Base64-encoding 2 the raw form of the signature.

            @@ -265,7 +267,7 @@

            We use a note value of \(1\) zatoshi instead of zero to ensure that the payment address is fully bound to - \(zkproof\) + \(zkproof\!\) . Notes with zero value have certain constraints disabled inside the circuit.

            We set \(\mathsf{rcm}\) @@ -287,7 +289,7 @@

          23. \(\mathsf{nf}\) is a binary public input to - \(zkproof\) + \(zkproof\!\) .
          24. \(\mathsf{rk}\) @@ -297,11 +299,11 @@
          25. RedJubjub signatures are themselves non-malleable.
          26. The one component that is inherently malleable is - \(zkproof\) + \(zkproof\!\) . The zero-knowledge property of a Groth16 proof implies that anyone can take a valid proof, and re-randomize it to obtain another valid proof with a different encoding. We prevent this by binding the encoding of \(zkproof\) to - \(spendAuthSig\) + \(spendAuthSig\!\) , by including \(zkproof\) in the message digest.

            diff --git a/rendered/zip-0307.html b/rendered/zip-0307.html index 07a72407c..eaf3dcc7e 100644 --- a/rendered/zip-0307.html +++ b/rendered/zip-0307.html @@ -3,7 +3,9 @@ ZIP 307: Light Client Protocol for Payment Detection - + + +
            @@ -207,7 +209,7 @@ \(\mathsf{epk} = \mathsf{abst}_{\mathbb{J}}(\mathtt{ephemeralKey})\)
          27. if - \(\mathsf{epk} = \bot\) + \(\mathsf{epk} = \bot\!\) , return \(\bot\)
          28. @@ -226,7 +228,7 @@ \(P^{\mathsf{enc}}\)
          29. [Pre-Canopy] if - \(\mathsf{leadByte} \neq 0x01\) + \(\mathsf{leadByte} \neq 0x01\!\) , return \(\bot\)
          30. @@ -236,14 +238,14 @@
          31. [Canopy onward] if \(\mathsf{height} < \mathsf{CanopyActivationHeight} + \mathsf{ZIP212GracePeriod}\) and - \(\mathsf{leadByte} \not\in \{ \mathtt{0x01}, \mathtt{0x02} \}\) + \(\mathsf{leadByte} \not\in \{ \mathtt{0x01}, \mathtt{0x02} \}\!\) , return \(\bot\)
          32. [Canopy onward] if \(\mathsf{height} < \mathsf{CanopyActivationHeight} + \mathsf{ZIP212GracePeriod}\) and - \(\mathsf{leadByte} \neq \mathtt{0x02}\) + \(\mathsf{leadByte} \neq \mathtt{0x02}\!\) , return \(\bot\)
          33. @@ -258,19 +260,19 @@
          34. if \(\mathsf{rcm} \geq r_{\mathbb{J}}\) or - \(\mathsf{g_d} = \bot\) + \(\mathsf{g_d} = \bot\!\) , return \(\bot\)
          35. [Canopy onward] if - \(\mathsf{leadByte} \neq \mathtt{0x01}\) + \(\mathsf{leadByte} \neq \mathtt{0x01}\!\) :
            • \(\mathsf{esk} = \mathsf{ToScalar}(\mathsf{PRF^{expand}_{rseed}}([4]))\)
            • if - \(\mathsf{repr}_{\mathbb{J}}(\mathsf{KA^{Sapling}.DerivePublic}(\mathsf{esk}, \mathsf{g_d})) \neq \mathtt{ephemeralKey}\) + \(\mathsf{repr}_{\mathbb{J}}(\mathsf{KA^{Sapling}.DerivePublic}(\mathsf{esk}, \mathsf{g_d})) \neq \mathtt{ephemeralKey}\!\) , return \(\bot\)
            • @@ -280,15 +282,15 @@ \(\mathsf{pk_d} = \mathsf{KA^{Sapling}.DerivePublic}(\mathsf{ivk}, \mathsf{g_d})\)
            • let - \(\mathsf{cm}_u' = \mathsf{Extract}_{\mathbb{J}^{(r)}}(\mathsf{NoteCommit^{Sapling}_{rcm}}(\mathsf{repr}_{\mathbb{J}}(\mathsf{g_d}), \mathsf{repr}_{\mathbb{J}}(\mathsf{pk_d}), \mathsf{v}))\) + \(\mathsf{cm}_u' = \mathsf{Extract}_{\mathbb{J}^{(r)}}(\mathsf{NoteCommit^{Sapling}_{rcm}}(\mathsf{repr}_{\mathbb{J}}(\mathsf{g_d}), \mathsf{repr}_{\mathbb{J}}(\mathsf{pk_d}), \mathsf{v}))\!\) .
            • if - \(\mathsf{LEBS2OSP}_{256}(\mathsf{cm}_u') \neq \mathtt{cmu}\) + \(\mathsf{LEBS2OSP}_{256}(\mathsf{cm}_u') \neq \mathtt{cmu}\!\) , return \(\bot\)
            • return - \(\mathbf{np}\) + \(\mathbf{np}\!\) .
          36. diff --git a/rendered/zip-0311.html b/rendered/zip-0311.html index cfec0a94b..98bbd6107 100644 --- a/rendered/zip-0311.html +++ b/rendered/zip-0311.html @@ -3,7 +3,9 @@ ZIP 311: Zcash Payment Disclosures - + + +
            @@ -142,9 +144,9 @@ \(\mathsf{DiversifyHash}(\mathsf{d})\) 7
          37. - \(\mathsf{SpendAuthSig.RandomizePrivate}(ι, \mathsf{sk})\) + \(\mathsf{SpendAuthSig.RandomizePrivate}(ι, \mathsf{sk})\!\) , - \(\mathsf{SpendAuthSig.Sign}(\mathsf{sk}, m)\) + \(\mathsf{SpendAuthSig.Sign}(\mathsf{sk}, m)\!\) , and \(\mathsf{SpendAuthSig.Verify}(\mathsf{vk}, m, σ)\) 8
          38. @@ -156,14 +158,14 @@ means scalar multiplication of the elliptic curve point \(P\) by the scalar - \(k\) + \(k\!\) .
          39. \(\mathsf{BLAKE2b}\text{-}\mathsf{256}(p, x)\) refers to unkeyed BLAKE2b-256 in sequential mode, with an output digest length of 32 bytes, 16-byte personalization string - \(p\) + \(p\!\) , and input - \(x\) + \(x\!\) .
          40. We also define the following notation here:

            @@ -173,12 +175,12 @@ means the sequence of values inclusive of \(a\) and exclusive of - \(b\) + \(b\!\) .
          41. \(\mathsf{length}(a)\) means the length of the sequence - \(a\) + \(a\!\) .
          42. @@ -189,17 +191,17 @@
          43. txid: Transaction id for the transaction tx being disclosed.
          44. msg: A message field, which could contain a challenge value from the party to whom the payment disclosure is directed.
          45. - \(\mathsf{transparentInputs}\) + \(\mathsf{transparentInputs}\!\) : A sequence of the transparent inputs for which we are proving spend authority \([0..\mathsf{length}(\mathsf{tx.vin})]\)
            • - \(\mathsf{index}\) + \(\mathsf{index}\!\) : An index into - \(\mathsf{tx.vin}\) + \(\mathsf{tx.vin}\!\) .
            • - \(\mathsf{sig}\) + \(\mathsf{sig}\!\) : A BIP 322 signature. 9
              • TODO: zcashd currently only supports the legacy format defined in BIP 322. We may want to backport full BIP 322 support before having transparent input support in this ZIP, to ensure it does what we need.
              • @@ -209,23 +211,23 @@
            • - \(\mathsf{saplingSpends}\) + \(\mathsf{saplingSpends}\!\) : A sequence of the Sapling Spends for which we are proving spend authority \([0..\mathsf{length}(\mathsf{tx.shieldedSpends})]\)
              • - \(\mathsf{index}\) + \(\mathsf{index}\!\) : An index into - \(\mathsf{tx.shieldedSpends}\) + \(\mathsf{tx.shieldedSpends}\!\) .
              • - \(\mathsf{cv}\) + \(\mathsf{cv}\!\) : A value commitment to the spent note.
              • - \(\mathsf{rk}\) + \(\mathsf{rk}\!\) : A randomized public key linked to the spent note.
              • - \(\mathsf{zkproof_{spend}}\) + \(\mathsf{zkproof_{spend}}\!\) : A Sapling spend proof.
              • [Optional] A payment address proof addr_proof:
                  @@ -235,10 +237,10 @@ \(\mathsf{pk_d} = [\mathsf{ivk}] \mathsf{DiversifyHash}(\mathsf{d})\)
                • - \(\mathsf{nullifier_{addr}}\) + \(\mathsf{nullifier_{addr}}\!\) : A nullifier for a ZIP 304 fake note. 11
                • - \(\mathsf{zkproof_{addr}}\) + \(\mathsf{zkproof_{addr}}\!\) : A Sapling spend proof.
              • @@ -248,17 +250,17 @@
            • - \(\mathsf{saplingOutputs}\) + \(\mathsf{saplingOutputs}\!\) : A sequence of the Sapling Outputs that we are disclosing \([0..\mathsf{length}(\mathsf{tx.shieldedOutputs})]\)
              • - \(\mathsf{index}\) + \(\mathsf{index}\!\) : An index into - \(\mathsf{tx.shieldedOutputs}\) + \(\mathsf{tx.shieldedOutputs}\!\) .
              • - \(\mathsf{ock}\) + \(\mathsf{ock}\!\) : The outgoing cipher key that allows this output to be recovered. 5
            • @@ -282,19 +284,19 @@
              • A Sapling spend index.
              • Its corresponding expanded spending key - \((\mathsf{ask}, \mathsf{nsk}, \mathsf{ovk})\) + \((\mathsf{ask}, \mathsf{nsk}, \mathsf{ovk})\!\) .
              • [Optional] An associated payment address - \((\mathsf{d}, \mathsf{pk_d})\) + \((\mathsf{d}, \mathsf{pk_d})\!\) .
            • A sequence of transparent input tuples (which may be empty) containing:
              • - \(\mathsf{index}\) + \(\mathsf{index}\!\) : An index into - \(\mathsf{tx.vin}\) + \(\mathsf{tx.vin}\!\) .
              • The inputs to a BIP 322 signature (excluding message_data).
              @@ -306,7 +308,7 @@
            • For each Sapling spend index:
              • Create a Sapling spend proof for the note that was spent in - \(\mathsf{tx.shieldedSpends[index]}\) + \(\mathsf{tx.shieldedSpends[index]}\!\) , using the same anchor, to obtain \((\mathsf{cv}, \mathsf{rk}, \mathsf{zkproof_{spend}})\) as well as the random @@ -327,21 +329,21 @@
            • Construct an unsigned payment disclosure from the disclosed Sapling outputs, and the above data for the Sapling spends and transparent inputs. Define the encoding of this as - \(unsignedPaymentDisclosure\) + \(unsignedPaymentDisclosure\!\) .
            • For each Sapling spend index:
              • Let - \(\mathsf{rsk} = \mathsf{SpendAuthSig.RandomizePrivate}(\alpha, \mathsf{ask})\) + \(\mathsf{rsk} = \mathsf{SpendAuthSig.RandomizePrivate}(\alpha, \mathsf{ask})\!\) .
              • Let \(coinType\) be the 4-byte little-endian encoding of the SLIP 44 coin type in its index form, not its hardened form (i.e. 133 for mainnet Zcash).
              • Let - \(digest = \mathsf{BLAKE2b}\text{-}\mathsf{256}(\texttt{"ZIP311Signed"}\,||\,coinType, unsignedPaymentDisclosure)\) + \(digest = \mathsf{BLAKE2b}\text{-}\mathsf{256}(\texttt{“ZIP311Signed”}\,||\,coinType, unsignedPaymentDisclosure)\!\) .
              • Let - \(spendAuthSig = \mathsf{SpendAuthSig.Sign}(\mathsf{rsk}, digest)\) + \(spendAuthSig = \mathsf{SpendAuthSig.Sign}(\mathsf{rsk}, digest)\!\) .
            • @@ -355,9 +357,9 @@

              Verifying a payment disclosure

              Given a payment disclosure - \(\mathsf{pd}\) + \(\mathsf{pd}\!\) , a transaction - \(\mathsf{tx}\) + \(\mathsf{tx}\!\) , and the height of the block in which \(\mathsf{tx}\) was mined (which we assume was verified by the caller), the verifier proceeds as follows:

              @@ -385,21 +387,21 @@
            • For every \(\mathsf{output}\) in - \(\mathsf{pd.saplingOutputs}\) + \(\mathsf{pd.saplingOutputs}\!\) , \(\mathsf{output.index}\) only occurs once.
            • For every \(\mathsf{spend}\) in - \(\mathsf{pd.saplingSpends}\) + \(\mathsf{pd.saplingSpends}\!\) , \(\mathsf{spend.index}\) only occurs once.
            • For every \(\mathsf{input}\) in - \(\mathsf{pd.transparentInputs}\) + \(\mathsf{pd.transparentInputs}\!\) , \(\mathsf{input.index}\) only occurs once.
            • @@ -410,21 +412,21 @@
            • For every \(\mathsf{output}\) in - \(\mathsf{pd.saplingOutputs}\) + \(\mathsf{pd.saplingOutputs}\!\) , \(\mathsf{output.index} < \mathsf{length}(\mathsf{tx.shieldedOutputs})\)
            • For every \(\mathsf{spend}\) in - \(\mathsf{pd.saplingSpends}\) + \(\mathsf{pd.saplingSpends}\!\) , \(\mathsf{spend.index} < \mathsf{length}(\mathsf{tx.shieldedSpends})\)
            • For every \(\mathsf{input}\) in - \(\mathsf{pd.transparentInputs}\) + \(\mathsf{pd.transparentInputs}\!\) , \(\mathsf{input.index} < \mathsf{length}(\mathsf{tx.vin})\)
            • @@ -442,21 +444,21 @@ \(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 - \(digest = \mathsf{BLAKE2b}\text{-}\mathsf{256}(\texttt{"ZIP311Signed"}\,||\,coinType, unsignedPaymentDisclosure)\) + \(digest = \mathsf{BLAKE2b}\text{-}\mathsf{256}(\texttt{“ZIP311Signed”}\,||\,coinType, unsignedPaymentDisclosure)\!\) .
            • For every \(\mathsf{spend}\) in - \(\mathsf{pd.saplingSpends}\) + \(\mathsf{pd.saplingSpends}\!\) :
              • If - \(\mathsf{SpendAuthSig.Verify}(\mathsf{spend.rk}, digest, \mathsf{spend.spendAuthSig}) = 0\) + \(\mathsf{SpendAuthSig.Verify}(\mathsf{spend.rk}, digest, \mathsf{spend.spendAuthSig}) = 0\!\) , return false.
              • [Optional] If a payment address proof \(\mathsf{addrProof}\) is present in - \(\mathsf{spend}\) + \(\mathsf{spend}\!\) , verify \((\mathsf{addrProof.nullifier_{addr}}, \mathsf{spend.rk}, \mathsf{addrProof.zkproof_{addr}})\) as a ZIP 304 proof for @@ -486,7 +488,7 @@
              • For every \(\mathsf{input}\) in - \(\mathsf{pd.transparentInputs}\) + \(\mathsf{pd.transparentInputs}\!\) :
                • TODO: BIP 322 verification.
                • @@ -495,15 +497,15 @@
                • For every \(\mathsf{output}\) in - \(\mathsf{pd.saplingOutputs}\) + \(\mathsf{pd.saplingOutputs}\!\) :
                  • Recover the Sapling note in \(\mathsf{tx.shieldedOutputs}[\mathsf{output.index}]\) via the process specified in 6 with inputs - \((height, \mathsf{output.ock})\) + \((height, \mathsf{output.ock})\!\) . If recovery returns - \(\bot\) + \(\bot\!\) , return false.
                • @@ -526,7 +528,7 @@ of \(\bot\) for a specific Sapling output, then they are unable to subsequently create a payment disclosure that discloses that output. This maintains the semantics of - \(\mathsf{ovk}\) + \(\mathsf{ovk}\!\) , in that the sender explicitly chose to lose the capability to recover that output.

                  Payment disclosures that prove Sapling spend authority are not required to reveal a sender address. This is because it is impossible: we can "prove" the transaction came from any of the diversified addresses linked to the spending key. Fundamentally, the "sender" of a transaction is anyone who has access to the corresponding spend authority; in the case of Sapling, a spend authority corresponds to multiple diversified addresses. In situations where a sender address is already known to the verifier of the payment disclosure (or publically), it may still be useful to have the option of linking the payment disclosure to that address.

            • diff --git a/rendered/zip-0312.html b/rendered/zip-0312.html index f69ad06eb..6471e4b61 100644 --- a/rendered/zip-0312.html +++ b/rendered/zip-0312.html @@ -3,7 +3,9 @@ ZIP 312: FROST for Spend Authorization Multisignatures - + + +
              @@ -71,7 +73,7 @@

              The types Scalar, Element, and G are defined in 7, as well as the notation for elliptic-curve arithmetic, which uses the additive notation. Note that this notation differs from that used in the Zcash Protocol Specification. For example, G.ScalarMult(P, k) is used for scalar multiplication, where the protocol spec would use \([k] P\) with the group implied by - \(P\) + \(P\!\) .

              An additional per-ciphersuite hash function is used, denote HR(m), which receives an arbitrary-sized byte string and returns a Scalar. It is defined concretely in the Ciphersuites section.

              Key Generation

              @@ -80,7 +82,7 @@ 14 is the particular key that must be used in the context of this ZIP. Note that the \(\mathsf{ask}\) is usually derived from the spending key - \(\mathsf{sk}\) + \(\mathsf{sk}\!\) , though that is not required. Not doing so allows using distributed key generation, since the key it generates is unpredictable. Note however that not deriving \(\mathsf{ask}\) from @@ -170,7 +172,7 @@
              • H1(m): Implemented by computing BLAKE2b-512("FROST_RedJubjubR", m), interpreting the 64 bytes as a little-endian integer, and reducing the resulting integer modulo G.Order().
              • H2(m): Implemented by computing BLAKE2b-512("Zcash_RedJubjubH", m), interpreting the 64 bytes as a little-endian integer, and reducing the resulting integer modulo G.Order(). (This is equivalent to - \(\mathsf{H}^\circledast(m)\) + \(\mathsf{H}^\circledast(m)\!\) , as defined by the \(\mathsf{RedJubjub}\) scheme instantiated in 12.)
              • @@ -211,7 +213,7 @@
                • H1(m): Implemented by computing BLAKE2b-512("FROST_RedPallasR", m), interpreting the 64 bytes as a little-endian integer, and reducing the resulting integer modulo G.Order().
                • H2(m): Implemented by computing BLAKE2b-512("Zcash_RedPallasH", m), interpreting the 64 bytes as a little-endian integer, and reducing the resulting integer modulo G.Order(). (This is equivalent to - \(\mathsf{H}^\circledast(m)\) + \(\mathsf{H}^\circledast(m)\!\) , as defined by the \(\mathsf{RedPallas}\) scheme instantiated in 12.)
                • @@ -232,10 +234,10 @@ function specified in 12:

                  • The FROST signature, when split into R and S in the first step of - \(\mathsf{RedDSA.Validate}\) + \(\mathsf{RedDSA.Validate}\!\) , must yield the values expected by the function. This is ensured by defining SerializeElement and SerializeScalar in each ciphersuite to yield those values.
                  • The challenge c used during FROST signing must be equal to the challenge c computed during - \(\mathsf{RedDSA.Validate}\) + \(\mathsf{RedDSA.Validate}\!\) . This requires defining the ciphersuite H2 function as the \(\mathsf{H}^\circledast(m)\) Zcash function in the ciphersuites, and making sure its input will be the same. Fortunately FROST and Zcash use the same input order (R, public key, message) so we just need to make sure that SerializeElement (used to compute the encoded public key before passing to the hash function) matches what @@ -252,17 +254,17 @@
                  • The re-randomization must be done in each signature share generation, such that the aggregated signature must be valid under verification with the randomized public key. The R value from the signature is not influenced by the randomizer so we just need to focus on the z value (using FROST notation). Recall that z must equal to r + (c * sk), and that each signature share is z_i = (hiding_nonce + (binding_nonce * binding_factor)) + (lambda_i * c * sk_i). The first terms are not influenced by the randomizer so we can only look into the second term of each top-level addition, i.e. c * sk must be equal to sum(lambda_i * c * sk_i) for each participant i. Under re-randomization these become c * (sk + randomizer) (see - \(\mathsf{RedDSA.RandomizedPrivate}\) + \(\mathsf{RedDSA.RandomizedPrivate}\!\) , which refers to the randomizer as - \(\alpha\) + \(\alpha\!\) ) and sum(lambda_i * c * (sk_i + randomizer)). The latter can be rewritten as c * (sum(lambda_i * sk_i) + randomizer * sum(lambda_i). Since sum(lambda_i * sk_i) == sk per the Shamir secret sharing mechanism used by FROST, and since sum(lambda_i) == 1 18, we arrive at c * (sk + randomizer) as required.
                  • The re-randomization procedure must be exactly the same as in 12 to ensure that re-randomized keys are uniformly distributed and signatures are unlinkable. This is also true; observe that randomizer_generate generates randomizer uniformly at random as required by - \(\mathsf{RedDSA.GenRandom}\) + \(\mathsf{RedDSA.GenRandom}\!\) ; and signature generation is compatible with - \(\mathsf{RedDSA.RandomizedPrivate}\) + \(\mathsf{RedDSA.RandomizedPrivate}\!\) , - \(\mathsf{RedDSA.RandomizedPublic}\) + \(\mathsf{RedDSA.RandomizedPublic}\!\) , \(\mathsf{RedDSA.Sign}\) and diff --git a/rendered/zip-0316.html b/rendered/zip-0316.html index 03c97e750..594829c81 100644 --- a/rendered/zip-0316.html +++ b/rendered/zip-0316.html @@ -3,7 +3,9 @@ ZIP 316: Unified Addresses and Unified Viewing Keys - + + +
                    @@ -270,7 +272,7 @@ is the encoding of \((\mathsf{ak}, \mathsf{nk}, \mathsf{ovk}, \mathsf{dk})\) given by - \(\mathsf{EncodeExtFVKParts}(\mathsf{ak}, \mathsf{nk}, \mathsf{ovk}, \mathsf{dk})\) + \(\mathsf{EncodeExtFVKParts}(\mathsf{ak}, \mathsf{nk}, \mathsf{ovk}, \mathsf{dk})\!\) , where \(\mathsf{EncodeExtFVKParts}\) is defined in 15. This SHOULD be derived from the Extended Full Viewing Key at the Account level of the ZIP 32 hierarchy.
                  • @@ -289,11 +291,11 @@ Both of these are encodings of the chain code and public key \((\mathsf{c}, \mathsf{pk})\) given by - \(\mathsf{c}\,||\,\mathsf{ser_P}(\mathsf{pk})\) + \(\mathsf{c}\,||\,\mathsf{ser_P}(\mathsf{pk})\!\) . (This is the same as the last 65 bytes of the extended public key format defined in section “Serialization format” of BIP 32 31.) However, the FVK uses the key at the Account level, i.e. at path - \(m / 44' / coin\_type' / account'\) + \(m / 44' / coin\_type' / account'\!\) , while the IVK uses the external (non-change) child key at the Change level, i.e. at path - \(m / 44' / coin\_type' / account' / 0\) + \(m / 44' / coin\_type' / account' / 0\!\) .

                  The Human-Readable Part is as specified for a Unified Viewing Key in Revisions.

                  @@ -309,8 +311,8 @@
                • A Revision 0 Unified Address or Unified Viewing Key MUST contain at least one shielded Item (Typecodes \(\mathtt{0x02}\) and - \(\mathtt{0x03}\) - ). This requirement is dropped for Revision 1 UA/UVKs.
                • + \(\mathtt{0x03}\!\) + ). This requirement is dropped for Revision 1 UA/UVKs; however, a Revision 1 UA/UVK MUST contain at least one non-Metadata Item.
                • The \(\mathtt{typecode}\) and @@ -322,7 +324,7 @@
                • For Transparent Addresses, the Receiver Encoding does not include the first two bytes of a raw encoding.
                • 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 25) to send funds into the Sprout chain value pool, this would not be generally useful.
                • With the exception of MUST-understand Metadata Items, Consumers MUST ignore constituent Items with Typecodes they do not recognise.
                • -
                • 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.
                • +
                • 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 Metadata Items.
                • Consumers MUST reject Unified Addresses/Viewing Keys in which any constituent Item does not meet the validation requirements of its encoding, as specified in this ZIP and the Zcash Protocol Specification 2.
                • 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.
                • There MUST NOT be additional bytes at the end of the raw encoding that cannot be interpreted as specified above.
                • @@ -401,15 +403,15 @@

                  When deriving a UIVK from a UFVK containing Typecodes \(\mathtt{0xE0}\) and/or - \(\mathtt{0xE1}\) + \(\mathtt{0xE1}\!\) , these Metadata Items MUST be retained unmodified in the derived UIVK.

                  When deriving a Unified Address from a UFVK or UIVK containing a Metadata Item having Typecode - \(\mathtt{0xE0}\) + \(\mathtt{0xE0}\!\) , the derived Unified Address MUST contain a Metadata Item having Typecode \(\mathtt{0xE0}\) such that the Address Expiry Height of the resulting address is less than or equal to the Expiry Height of the viewing key.

                  When deriving a Unified Address from a UFVK or UIVK containing a Metadata Item having Typecode - \(\mathtt{0xE1}\) + \(\mathtt{0xE1}\!\) , the derived Unified Address MUST contain a Metadata Item having Typecode \(\mathtt{0xE1}\) such that the Address Expiry Time of the resulting address is less than or equal to the Expiry Time of the viewing key.

                  @@ -467,7 +469,7 @@ be the remaining \(32\) bytes of - \(I_\mathsf{ovk}\) + \(I_\mathsf{ovk}\!\) .

                Since an external P2PKH FVK encodes the chain code and public key at the Account level, we can derive both external and internal child keys from it, as described in BIP 44 34. 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.

                @@ -501,6 +503,9 @@ inclusive.
              • There are no additional constraints on an Orchard diversifier index.
              +

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

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

              • For a Sapling IVK, the corresponding Sapling Receiver is obtained as specified in 4.
              • @@ -539,7 +544,7 @@ and last \(m\) characters, up to some bound on - \(n+m\) + \(n+m\!\) );
              • is controlled by the adversary (for concreteness, the adversary knows at least one of the private keys of the constituent Addresses).
          @@ -594,7 +599,7 @@ of length \(\ell_M\) bytes such that - \(48 \leq \ell_M \leq \ell^\mathsf{MAX}_M,\) + \(38 \leq \ell_M \leq \ell^\mathsf{MAX}_M,\) define \(\mathsf{F4Jumble}(M)\) by:

          @@ -643,7 +648,7 @@

          We instantiate \(H_i(u)\) by - \(\mathsf{BLAKE2b‐}(8\ell_L)(\texttt{“UA_F4Jumble_H”} \,||\,\) + \(\mathsf{BLAKE2b‐}(8\ell_L)(\texttt{“UA\_F4Jumble\_H”} \,||\,\) \([i, 0, 0], u),\) with \(\ell_H = 64.\) @@ -653,7 +658,7 @@ as the first \(\ell_R\) bytes of the concatenation of - \([\mathsf{BLAKE2b‐}512(\texttt{“UA_F4Jumble_G”} \,||\, [i] \,||\,\) + \([\mathsf{BLAKE2b‐}512(\texttt{“UA\_F4Jumble\_G”} \,||\, [i] \,||\,\) \(\mathsf{I2LEOSP}_{16}(j), u) \text{ for } j \text{ from}\) \(0 \text{ up to } \mathsf{ceiling}(\ell_R/\ell_H)-1].\)

          @@ -731,7 +736,7 @@ is close to \(c.\) ( - \(b'\) + \(\!b'\) and \(d'\) will not be close to @@ -806,7 +811,7 @@ part of the jumbled encoding three times from a less memory-constrained device. It is essential that the streamed value of \(d\) is the same on each pass, which can be verified using a Message Authentication Code (with key held only by the Consumer) or collision-resistant hash function. After the first pass of - \(d\) + \(d\!\) , the implementation is able to compute \(y;\) after the second pass it is able to compute diff --git a/rendered/zip-0317.html b/rendered/zip-0317.html index bf2e70936..8dab6cbe0 100644 --- a/rendered/zip-0317.html +++ b/rendered/zip-0317.html @@ -3,7 +3,9 @@ ZIP 317: Proportional Transfer Fee Mechanism - + + +
          @@ -211,27 +213,27 @@

          Let \(min\_actions\) be the minimum number of logical actions that can be used to execute economically relevant transactions that produce change. Due to the aforementioned padding, - \(min\_actions = 2\) + \(min\_actions = 2\!\) .

          Having a grace window size greater than \(min\_actions\) would increase the cost to create such a minimal transaction. If the cost we believe that users will tolerate for a minimal transaction is - \(B\) + \(B\!\) , then possible choices of \(marginal\_fee\) are bounded above by - \(B / \max(min\_actions, grace\_actions)\) + \(B / \max(min\_actions, grace\_actions)\!\) . Therefore, the optimal choice of \(grace\_actions\) to maximize the per-logical-action cost of denial-of-service attacks for a given - \(B\) + \(B\!\) , is - \(grace\_actions = min\_actions = 2\) + \(grace\_actions = min\_actions = 2\!\) . This also ensures that a denial-of-service adversary does not gain a significant per-logical-action cost advantage by using transactions with a smaller or larger number of logical actions.

          Transparent Contribution

          The specified formula calculates the contribution of transparent inputs and outputs based on their total size relative to a typical input or output. Another considered approach was to calculate this contribution simply as - \(\mathsf{max}(transparent\_inputs, transparent\_outputs)\) + \(\mathsf{max}(transparent\_inputs, transparent\_outputs)\!\) . However, this would allow a denial-of-service adversary to create transactions with transparent components containing arbitrarily large scripts.

          The chosen values for \(p2pkh\_standard\_input\_size\) @@ -298,7 +300,7 @@ \(unpaid\_actions(tx) = \begin{cases}\mathsf{max}\!\left(0,\, \mathsf{max}(grace\_actions,\, tx.\!logical\_actions) - \mathsf{floor}\!\left(\frac{tx.fee}{marginal\_fee}\right)\right),&\textsf{if }tx\textsf{ is a non-coinbase transaction} \\ 0,&\textsf{if }tx\textsf{ is a coinbase transaction.}\end{cases}\)

          Let - \(block\_unpaid\_actions(block) = \sum_{tx \,\in\, block}\, unpaid\_actions(tx)\) + \(block\_unpaid\_actions(block) = \sum_{tx \,\in\, block}\, unpaid\_actions(tx)\!\) .

          The following algorithm is RECOMMENDED for constructing a block template from a set of transactions in a node's mempool:

            @@ -308,7 +310,7 @@
          1. For each transaction \(tx\) in the mempool, calculate - \(tx.\!weight\_ratio = \mathsf{min}\!\left(\frac{\mathsf{max}(1,\, tx.fee)}{conventional\_fee(tx)},\, weight\_ratio\_cap\right)\!\) + \(tx.\!weight\_ratio = \mathsf{min}\!\left(\frac{\mathsf{max}(1,\, tx.fee)}{conventional\_fee(tx)},\, weight\_ratio\_cap\right)\) and add the transaction to the set of candidate transactions.
          2. Repeat while there is any candidate transaction that pays at least the conventional fee:
              @@ -380,7 +382,7 @@ rather than just \(tx.\!fee\) avoids needing to define "with probability in direct proportion to its - \(weight\_ratio\!\) + \(weight\_ratio\) " for the case where all remaining candidate transactions would have \(weight\_ratio = 0\!\) .

              diff --git a/rendered/zip-0320.html b/rendered/zip-0320.html index 0094e0110..1932b0d0a 100644 --- a/rendered/zip-0320.html +++ b/rendered/zip-0320.html @@ -3,7 +3,9 @@ ZIP 320: Defining an Address Type to which funds can only be sent from Transparent Addresses - + + +
              @@ -58,12 +60,12 @@
              1. Decode the address to a byte sequence using the Base58Check decoding algorithm 13.
              2. If the length of the resulting byte sequence is not 22 bytes or if its two-byte address prefix is not - \([\mathtt{0x1C}, \mathtt{0xB8}]\) + \([\mathtt{0x1C}, \mathtt{0xB8}]\!\) , return an error. Otherwise, let the validating key hash be the remaining 20 bytes of the sequence after removing the two-byte address prefix.
              3. Reencode the 20-byte validating key hash using the Bech32m encoding defined in 15 with the human-readable prefix (HRP) "tex".

              For Testnet addresses, the required lead bytes of a P2PKH address in step 2 are - \([\mathtt{0x1D}, \mathtt{0x25}]\) + \([\mathtt{0x1D}, \mathtt{0x25}]\!\) , and the "textest" HRP is used when reencoding in step 3.

              A TEX address can be parsed by reversing this encoding, i.e.:

                diff --git a/rendered/zip-0324.html b/rendered/zip-0324.html index 2816bce7c..47003b631 100644 --- a/rendered/zip-0324.html +++ b/rendered/zip-0324.html @@ -3,7 +3,9 @@ ZIP 324: URI-Encapsulated Payments - + + +
                diff --git a/rendered/zip-0401.html b/rendered/zip-0401.html index aaec293e4..b35caa570 100644 --- a/rendered/zip-0401.html +++ b/rendered/zip-0401.html @@ -3,7 +3,9 @@ ZIP 401: Addressing Mempool Denial-of-Service - + + +
                @@ -64,7 +66,7 @@

                There is some ambiguity in the specification of a transaction's "memory size", allowing implementations to use different approximations. Currently, zcashd uses a size computed by the RecursiveDynamicUsage function, and zebrad uses the serialized size. This has been changed from a previous version of this ZIP that specified use of the serialized size, to reflect how the implementation in zcashd has worked since it was first deployed 7.

                The threshold 10000 for the cost function is chosen so that the size in bytes of a minimal fully shielded Orchard transaction with 2 shielded actions (having a serialized size of 9165 bytes) will fall below the threshold. This has the effect of ensuring that such transactions are not evicted preferentially to typical transparent or Sapling transactions because of their size. This constant has been updated 6 from 4000 to 10000 in parallel with the changes for deployment of ZIP 317 5; the previous value had been chosen based on the typical size of fully shielded Sapling transactions.

                The proposed eviction policy differs significantly from that of Bitcoin Core 8, which is primarily fee-based. This reflects differing philosophies about the motivation for fees and the level of fee that legitimate users can reasonably be expected to pay. The proposed eviction weight function does involve a penalty for transactions with a fee lower than the ZIP 317 5 conventional fee, but since there is no further benefit (as far as mempool limiting is concerned) to increasing the fee above the conventional fee value, it creates no pressure toward escalating fees. For transactions with a memory size up to 10000 bytes, this penalty makes a transaction that pays less than the conventional fee five times as likely to be chosen for eviction (because - \(10000 + 40000 = 50000 = 10000 \times 5\) + \(10000 + 40000 = 50000 = 10000 \times 5\!\) ).

                The fee penalty is not included in the cost that determines whether the mempool is considered full. This ensures that a DoS attacker does not have an incentive to pay less than the conventional fee in order to cause the mempool to be considered full sooner.

                The default value of 80000000 for mempooltxcostlimit represents no more than 40 blocks’ worth of transactions in the worst case, which is the default expiration height after the Blossom network upgrade 2. It would serve no purpose to make it larger.

                diff --git a/rendered/zip-1011.html b/rendered/zip-1011.html index e62e1debf..2aac65bcd 100644 --- a/rendered/zip-1011.html +++ b/rendered/zip-1011.html @@ -3,7 +3,9 @@ ZIP 1011: Decentralize the Dev Fee - + + +
                diff --git a/rendered/zip-1015.html b/rendered/zip-1015.html index c5f3123b8..0b5c52872 100644 --- a/rendered/zip-1015.html +++ b/rendered/zip-1015.html @@ -1,13 +1,13 @@ - ZIP 1015: Block Reward Allocation for Non-Direct Development Funding + ZIP 1015: Block Subsidy Allocation for Non-Direct Development Funding
                ZIP: 1015
                -Title: Block Reward Allocation for Non-Direct Development Funding
                +Title: Block Subsidy Allocation for Non-Direct Development Funding
                 Owners: Jason McGee <aquietinvestor@gmail.com>
                         @Peacemonger (Zcash Forum)
                         Kris Nuttycombe <kris@nutty.land>
                @@ -32,7 +32,7 @@
                             

                The proposed lockbox addresses significant issues observed with ZIP 1014 3, such as regulatory risks, inefficiencies due to funding of organizations instead of projects, and centralization. While the exact disbursement mechanism for the lockbox funds is yet to be determined and will be addressed in a future ZIP, the goal is to employ a decentralized mechanism that ensures community involvement and efficient, project-specific funding. This approach is intended to potentially improve regulatory compliance, reduce inefficiencies, and enhance the decentralization of Zcash's funding structure.

                Motivation

                -

                Starting at Zcash's second halving in November 2024, under pre-existing consensus rules 100% of the block subsidies would be allocated to miners, and no further funds would be automatically allocated to any other entities. Consequently, unless the community takes action to approve new block-reward-based funding, existing teams dedicated to development or outreach or furthering charitable, educational, or scientific purposes would likely need to seek other sources of funding; failure to obtain such funding would likely impair their ability to continue serving the Zcash ecosystem. Setting aside a portion of the block subsidy to fund development will help ensure that both existing teams and new contributors can obtain funding in the future.

                +

                Starting at Zcash's second halving in November 2024, under pre-existing consensus rules 100% of the block subsidies would be allocated to miners, and no further funds would be automatically allocated to any other entities. Consequently, unless the community takes action to approve new block-subsidy-based funding, existing teams dedicated to development or outreach or furthering charitable, educational, or scientific purposes would likely need to seek other sources of funding; failure to obtain such funding would likely impair their ability to continue serving the Zcash ecosystem. Setting aside a portion of the block subsidy to fund development will help ensure that both existing teams and new contributors can obtain funding in the future.

                It is important to balance the incentives for securing the consensus protocol through mining with funding crucial charitable, educational, and scientific activities like research, development, and outreach. Additionally, there is a need to continue to promote decentralization and the growth of independent development teams.

                For these reasons, the Zcash Community wishes to establish a new Zcash Development Fund after the second halving in November 2024, with the intent to put in place a more decentralized mechanism for allocation of development funds. The alternatives presented here are intended to address the following:

                  diff --git a/rendered/zip-2001.html b/rendered/zip-2001.html index 6334e4e65..48717be1c 100644 --- a/rendered/zip-2001.html +++ b/rendered/zip-2001.html @@ -3,7 +3,9 @@ ZIP 2001: Lockbox Funding Streams - + + +
                  @@ -35,8 +37,8 @@

                  The funding stream mechanism defined in ZIP 207 11 is modified such that a funding stream may deposit funds into the deferred pool.

                  Specification

                  -
                  -

                  Modifications to ZIP 207 11

                  +
                  +

                  Changes to ZIP 207 11

                  The following paragraph is added to the section Motivation:

                  As of NU6, ZIP 1015 17 directs part of the block reward to a reserve, the distribution of which is to be determined via a future ZIP. ZIP 2001 18 modified the present ZIP to augment the funding stream mechanism with a common mechanism to implement this proposal.

                  @@ -50,7 +52,7 @@

                  Modifications to ZIP 207 \(\mathsf{fs.Recipients}\) MUST represent either a transparent P2SH address as specified in 6, or a Sapling shielded payment address as specified in 7, or the identifier - \(\mathsf{DEFERRED}\_\mathsf{POOL}\!\) + \(\mathsf{DEFERRED\_POOL}\!\) .

                  After the section Funding streams, a new section is added with the heading "Deferred Development Fund Chain Value Pool Balance" and the following contents:

                  @@ -63,14 +65,14 @@

                  Modifications to ZIP 207 \(\mathsf{DeferredFundingStreams}(\mathsf{height})\) is the set of funding streams with recipient identifier - \(\mathsf{DEFERRED}\_\mathsf{POOL}\) + \(\mathsf{DEFERRED\_POOL}\) in the block at height \(\mathsf{height}\!\) .

                  The \(\mathsf{ChainValuePoolBalance^{Deferred}}\) chain value pool balance for a given block chain is the sum of the values of payments to - \(\mathsf{DEFERRED}\_\mathsf{POOL}\) + \(\mathsf{DEFERRED\_POOL}\) for transactions in the block chain.

                  Equivalently, \(\mathsf{ChainValuePoolBalance^{Deferred}}\) @@ -97,11 +99,11 @@

                  Modifications to ZIP 207 \(\mathsf{cb}\) at block height - \(\mathsf{height}\) + \(\mathsf{height}\!\) , for each funding stream \(\mathsf{fs}\) active at that block height with a recipient identifier other than - \(\mathsf{DEFERRED}\_\mathsf{POOL}\) + \(\mathsf{DEFERRED\_POOL}\) given by \(\mathsf{fs.Recipient}(\mathsf{height})\!\) , @@ -118,29 +120,29 @@

                  Modifications to ZIP 207 10.

                  The effect of the definition of \(\mathsf{ChainValuePoolBalance^{Deferred}}\) above is that payments to the - \(\mathsf{DEFERRED}\_\mathsf{POOL}\) + \(\mathsf{DEFERRED\_POOL}\) cause \(\mathsf{FundingStream[FUND].Value}(\mathsf{height})\) to be added to \(\mathsf{ChainValuePoolBalance^{Deferred}}\) for the block chain including that block.

                  -

                  In the section Deployment 14, the following sentence is added:

                  +

                  In the section Deployment 14, the following sentence is added:

                  -

                  Changes to support deferred funding streams are to be deployed with NU6. 15

                  +

                  Changes to support deferred funding streams are to be deployed with NU6. 15

                  -

                  Modifications to the protocol specification

                  -

                  In section 4.17 Chain Value Pool Balances 5 (which is new in version 2024.5.1 of the protocol specification), include the following:

                  +

                  Changes to the Zcash Protocol Specification

                  +

                  In section 4.17 Chain Value Pool Balances 5 (which is new in version 2024.5.1 of the protocol specification), include the following:

                  Define \(\mathsf{totalDeferredOutput}\) - as in 9.

                  -

                  Then, consistent with 11, the deferred development fund chain value pool balance for a block chain up to and including height + as in 9.

                  +

                  Then, consistent with 11, the deferred development fund chain value pool balance for a block chain up to and including height \(\mathsf{height}\) is given by \(\mathsf{ChainValuePoolBalance^{Deferred}}(\mathsf{height}) := \sum_{\mathsf{h} = 0}^{\mathsf{height}} \mathsf{totalDeferredOutput}(\mathsf{h})\!\) @@ -165,7 +167,7 @@

                  Modifications to ZIP 207 8, instead of:

                  +

                  In section 7.1.2 Transaction Consensus Rules 8, instead of:

                  The total value in zatoshi of transparent outputs from a coinbase transaction, minus \(\mathsf{v^{balanceSapling}}\!\) @@ -176,7 +178,7 @@

                  Modifications to ZIP 207 \(\mathsf{height}\) + \(\mathsf{height}\!\) :

                  • define the "total output value" of its coinbase transaction to be the total value in zatoshi of its transparent outputs, minus @@ -198,8 +200,8 @@

                    Modifications to ZIP 207 10 contains language and definitions copied from ZIP 207; it should be updated to reflect the changes made above.

                    -

                    The second paragraph of section 1.2 High-level Overview 2 should be updated to take into account the deferred chain value pool. Since that section of the specification is entirely non-normative, we do not give the full wording change here.

                    +

                    Section 7.10 Payment of Funding Streams 10 contains language and definitions copied from ZIP 207; it should be updated to reflect the changes made above.

                    +

                    The second paragraph of section 1.2 High-level Overview 2 should be updated to take into account the deferred chain value pool. Since that section of the specification is entirely non-normative, we do not give the full wording change here.

                  References

                  diff --git a/rendered/zip-2002.html b/rendered/zip-2002.html index 38da825f7..735a2f679 100644 --- a/rendered/zip-2002.html +++ b/rendered/zip-2002.html @@ -3,7 +3,9 @@ ZIP 2002: Explicit Fees - + + +
                  @@ -21,8 +23,8 @@

                  Terminology

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

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

                  -

                  The terms "Testnet" and "Mainnet" are to be interpreted as described in section 3.12 of the Zcash Protocol Specification. 4

                  -

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

                  +

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

                  +

                  The terms "Mainnet" and "Testnet" are to be interpreted as described in § 3.12 ‘Mainnet and Testnet’. 4

                  Abstract

                  This proposal adds an explicit fee field to the v6 transaction format. Instead of fees being implicit in the difference between the input value and output value of the transaction, all value transfers, including fee transfers to miners, will be explicit and committed to via the txid.

                  @@ -33,11 +35,12 @@

                  Finally, this change will make it possible for light clients to determine the fee paid by a transaction without needing to download and inspect transparent inputs to the transaction.

                  Requirements

                  -

                  There must not be any potentially error-prone calculations needed to compute the fee for a given transaction. That is, the fee must be obvious from the encoding of the transaction.

                  +

                  Parties that see a transaction, even in isolation, reliably know its fee. That is, the fee must be explicit in the encoding of the transaction, and no potentially error-prone calculations or additional chain data are needed to compute it.

                  Specification

                  -

                  Transaction Format

                  -

                  The following field is added to the v6 transaction format 8.

                  +
                  +

                  Changes to ZIP 230 8

                  +

                  The following field is appended to the Common Transaction Fields of the v6 transaction format after nExpiryHeight 9:

                  @@ -56,10 +59,10 @@
                  +

                  Note: If both this ZIP and ZIP 233 are selected for inclusion in the same Network Upgrade, then the ambiguity in ordering of the fields added by these ZIPs would need to be resolved.

                  -

                  Consensus Rules

                  -

                  The following changes are to be made to the Zcash Protocol Specification 2.

                  -

                  In § 3.4 ‘Transactions and Treestates’ 3 (last modified by ZIP 236 9), add the following consensus rule and note:

                  +

                  Changes to the Zcash Protocol Specification

                  +

                  In § 3.4 ‘Transactions and Treestates’ 3 (last modified by ZIP 236 10), add the following consensus rule and note:

                  • [NU7 onward] For v6 and later transactions, the remaining value in the transparent transaction value pool, in zatoshis, MUST be equal to the value of the transaction’s fee field.
                  • @@ -69,31 +72,22 @@

                    In § 7.1 ‘Transaction Encoding and Consensus’ 5, add:

                    [NU7 onward] fee MUST be in the range - \(\{ 0 .. \mathsf{MAX\_MONEY} \}\) + \(\{ 0 .. \mathsf{MAX\_MONEY} \}\!\) .

                  -

                  Signature Hash

                  -

                  The transaction signature hashing algorithm defined in ZIP 244 is to be modified for v6 transactions as follows:

                  -

                  Section T.1: header_digest 10 is specified in draft-txv6-sighash 11 to read:

                  -
                  -

                  A BLAKE2b-256 hash of the following values

                  -
                  T.1a: version             (4-byte little-endian version identifier including ``fOverwintered`` flag)
                  -T.1b: version_group_id    (4-byte little-endian version group identifier)
                  -T.1c: consensus_branch_id (4-byte little-endian consensus branch id)
                  -T.1d: lock_time           (4-byte little-endian ``nLockTime`` value)
                  -T.1e: expiry_height       (4-byte little-endian block height)
                  -T.1f: fee                 (8-byte little-endian fee value)
                  -

                  The personalization field of this hash is set to:

                  -
                  "ZTxIdHeadersHash"
                  -
                  +
                  +

                  Modifications relative to ZIP 244 11

                  +

                  Relative to the sighash algorithm defined in ZIP 244, the sighash algorithm that applies to v6 transactions differs by appending the fee field to the Common Transaction Fields that are the input to the digest in T.1: header_digest 12:

                  +
                  T.1f: fee (8-byte little-endian fee amount)
                  +

                  Note: If both this ZIP and ZIP 233 are selected for inclusion in the same Network Upgrade, then the ambiguity in ordering of the fields added by these ZIPs would need to be resolved.

                  Applicability

                  All of these changes apply identically to Mainnet and Testnet.

                  Deployment

                  -

                  This ZIP is proposed to be deployed with the next transaction version change, which is assumed to be v6.

                  +

                  This ZIP is proposed to be deployed with the next transaction version change, which is assumed to be v6. 8

                  Reference implementation

                  TBD

                  @@ -155,7 +149,7 @@ - +
                  @@ -163,18 +157,34 @@
                  8
                  - +
                  + + + +
                  9ZIP 230: Version 6 Transaction Format. Specification: Transaction Format
                  + + + +
                  10 ZIP 236: Blocks should balance exactly
                  + + + + + + + +
                  11ZIP 244: Transaction Identifier Non-Malleability
                  - + @@ -182,7 +192,7 @@
                  1012 ZIP 244: Transaction Identifier Non-Malleability. Section T.1: Header Digest
                  - + diff --git a/rendered/zip-2003.html b/rendered/zip-2003.html index fbfcee6db..77b393a64 100644 --- a/rendered/zip-2003.html +++ b/rendered/zip-2003.html @@ -17,8 +17,8 @@

                  Terminology

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

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

                  -

                  The terms "Testnet" and "Mainnet" are to be interpreted as described in section 3.12 of the Zcash Protocol Specification. 3

                  -

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

                  +

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

                  +

                  The terms "Mainnet" and "Testnet" are to be interpreted as described in § 3.12 ‘Mainnet and Testnet’. 3

                  Abstract

                  This proposal disallows v4 transactions. The v5 transaction format introduced in the NU5 network upgrade 7 does not support Sprout, and so this will have the effect of disabling the ability to spend Sprout funds.

                  @@ -44,7 +44,7 @@

                  to be “[N​U​5 and NU6, pre-NU7]”, and ensure that the corresponding rule that applies from NU7 onward does not allow version 4.

                  These changes apply identically to Mainnet and Testnet.

                  Interaction with the proposed Network Sustainability Mechanism

                  -

                  For clarity, the Sprout chain value pool balance as of activation of this ZIP remains issued. If the Network Sustainability Mechanism ZIPs that affect issuance (8 and 9) are activated, then the Sprout chain value pool balance is, therefore, not considered part of the “Money Reserve” as a consequence of activating this ZIP.

                  +

                  For clarity, the Sprout chain value pool balance as of activation of this ZIP remains issued. If the Network Sustainability Mechanism ZIPs that affect issuance (8 and 9) are also activated, then this ZIP would not cause the Sprout chain value pool to be considered part of the “Money Reserve”.

                  Deployment

                  @@ -113,19 +113,19 @@
                  1113 ZIP draft: Version 6 Transaction Signature Validation
                  - +
                  - +
                  8Draft ZIP 233: Network Sustainability Mechanism: BurningZIP 233: Network Sustainability Mechanism: Burning
                  - +
                  - +
                  9Draft ZIP 234: Network Sustainability Mechanism: Issuance SmoothingZIP 234: Network Sustainability Mechanism: Issuance Smoothing
                  diff --git a/rendered/zip-2004.html b/rendered/zip-2004.html index c04ad9386..aa570297d 100644 --- a/rendered/zip-2004.html +++ b/rendered/zip-2004.html @@ -3,7 +3,9 @@ ZIP 2004: Remove the dependency of consensus on note encryption - + + +
                  @@ -19,8 +21,8 @@

                  Terminology

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

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

                  -

                  The terms "Testnet" and "Mainnet" are to be interpreted as described in section 3.12 of the Zcash Protocol Specification. 3

                  -

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

                  +

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

                  +

                  The terms "Mainnet" and "Testnet" are to be interpreted as described in § 3.12 ‘Mainnet and Testnet’. 3

                  Abstract

                  ZIP 213 6 added the ability for coinbase outputs to be shielded. An unfortunate side effect of this was to make consensus dependent on the details of note encryption. This has unnecessarily complicated the specification and implementation of consensus rules.

                  @@ -36,25 +38,22 @@

                  The consensus rule change specified in this ZIP must, from transaction version 6 onward, make the implementation and specification of shielded coinbase outputs independent of note encryption.

                  Specification

                  -

                  Changes to the protocol specification

                  +

                  Changes to the Zcash Protocol Specification

                  In § 5.4.3 'Symmetric Encryption', rename \(Sym\) to \(NoteSym\) and add the following text:

                  -
                  -
                  Let - \(\mathsf{NullSym.}\mathbf{K} := \mathbb{B}^{[256]}\) - ,
                  -
                  - \(\mathsf{NullSym.}\mathbf{P} := \mathbb{B^Y}^{\mathbb{N}}\) - , and - \(\mathsf{NullSym.}\mathbf{C} := \mathbb{B^Y}^{\mathbb{N}}\) - .
                  -

                  Let - \(\mathsf{NullSym.Encrypt_K}(\mathsf{P}) := \mathsf{P} || [0x00]^{16}\) + \(\mathsf{NullSym.}\mathbf{K} := \mathbb{B}^{[256]}\!\) + , + \(\mathsf{NullSym.}\mathbf{P} := \mathbb{B^Y}^{\mathbb{N}}\!\) + , and + \(\mathsf{NullSym.}\mathbf{C} := \mathbb{B^Y}^{\mathbb{N}}\!\) + .

                  +

                  Let + \(\mathsf{NullSym.Encrypt_K}(\mathsf{P}) := \mathsf{P} \,||\, [0x00]^{16}\!\) .

                  Define \(\mathsf{NullSym.Decrypt_K}(\mathsf{C})\) @@ -63,11 +62,11 @@

                1. If the last 16 bytes of \(\mathsf{C}\) are not - \([0x00]^{16}\) + \([0x00]^{16}\!\) , return - \(\bot\) + \(\bot\!\) . Otherwise discard those 16 bytes and return the remaining prefix of - \(\mathsf{C}\) + \(\mathsf{C}\!\) .
                2. Note: These definitions intentionally ignore the key; @@ -90,14 +89,14 @@

                  [Pre-NU7] let \(\mathsf{Sym}\) be - \(\mathsf{NoteSym}\) + \(\mathsf{NoteSym}\!\) .

                  [NU7 onward] if the note to be decrypted is in an output of a version 6 or later coinbase transaction, let \(\mathsf{Sym}\) be - \(\mathsf{NullSym}\) + \(\mathsf{NullSym}\!\) , otherwise let it be - \(\mathsf{NoteSym}\) + \(\mathsf{NoteSym}\!\) .

                  These changes apply identically to Mainnet and Testnet.

                  @@ -105,7 +104,7 @@

                  Deployment

                  -

                  This ZIP is proposed to be deployed with the next transaction version change, which is assumed to be v6.

                  +

                  This ZIP is proposed to be deployed with the next transaction version change, which is assumed to be v6. 7

                  Reference implementation

                  TBD.

                  @@ -162,6 +161,14 @@ + + + + + + + +
                  7ZIP 230: Version 6 Transaction Format
                  diff --git a/rendered/zip-guide-markdown.html b/rendered/zip-guide-markdown.html index 19abb4347..ca7f527a2 100644 --- a/rendered/zip-guide-markdown.html +++ b/rendered/zip-guide-markdown.html @@ -3,7 +3,9 @@ ZIP guide-markdown: {Something Short and To the Point} - + + + @@ -17,242 +19,288 @@ Category: {Consensus | Standards Track | Network | RPC | Wallet | Informational | Process} Created: yyyy-mm-dd License: {usually MIT} -Pull-Request: <https://github.com/zcash/zips/pull/???> -

                  Don’t Panic

                  -

                  If this is your first time writing a ZIP, the structure and format -may look intimidating. But really, it’s just meant to reflect -common-sense practice and some technical conventions. Feel free to start -with a simple initial draft that gets ideas across, even if it doesn’t -quite follow this format. The community and ZIP editors will help you -figure things out and get it into shape later.

                  +Pull-Request: <https://github.com/zcash/zips/pull/???> + + +

                  Don’t Panic

                  + +

                  If this is your first time writing a ZIP, the structure and format may look +intimidating. But really, it’s just meant to reflect common-sense practice and +some technical conventions. Feel free to start with a simple initial draft that +gets ideas across, even if it doesn’t quite follow this format. The community +and ZIP editors will help you figure things out and get it into shape later.

                  +

                  {Delete this section.}

                  -

                  Terminology

                  -

                  {Edit this to reflect the key words that are actually used.} The key -words “MUST”, “REQUIRED”, “MUST NOT”, “SHOULD”, and “MAY” in this -document are to be interpreted as described in BCP 14 1 -when, and only when, they appear in all capitals.

                  -

                  {Avoid duplicating definitions from other ZIPs. Instead use wording -like this:}

                  -

                  The terms “Mainnet” and “Testnet” in this document are to be -interpreted as defined in the Zcash protocol specification 2.

                  -

                  The term “full validator” in this document is to be interpreted as -defined in the Zcash protocol specification 3.

                  + +

                  Terminology

                  + +

                  {Edit this to reflect the key words that are actually used.} +The key words “MUST”, “REQUIRED”, “MUST NOT”, “SHOULD”, and “MAY” in this +document are to be interpreted as described in BCP 14 1 when, and +only when, they appear in all capitals.

                  + +

                  {Avoid duplicating definitions from other ZIPs. Instead use wording like this:}

                  + +

                  The terms “Mainnet” and “Testnet” in this document are to be interpreted as +defined in the Zcash protocol specification 2.

                  + +

                  The term “full validator” in this document is to be interpreted as defined in +the Zcash protocol specification 3.

                  +

                  The terms below are to be interpreted as follows:

                  -
                  -
                  {Term to be defined}
                  -
                  -

                  {Definition.}

                  -
                  -
                  {Another term}
                  -
                  -

                  {Definition.}

                  -
                  -
                  -

                  Abstract

                  + +

                  {Term to be defined}

                  + +

                  :{Definition.} +

                  + +

                  {Another term}

                  + +

                  :{Definition.} +

                  + +

                  Abstract

                  +

                  {Describe what this proposal does, typically in a few paragraphs.

                  -

                  The Abstract should only provide a summary of the ZIP; the ZIP should -remain complete without the Abstract.

                  -

                  Use links where applicable, e.g. 4 5.}

                  -

                  Motivation

                  + +

                  The Abstract should only provide a summary of the ZIP; the ZIP should remain +complete without the Abstract.

                  + +

                  Use links where applicable, e.g. 4 5.}

                  + +

                  Motivation

                  +

                  {Why is this proposal needed?

                  -

                  This is one of the most important sections of the ZIP, and should be -detailed and comprehensive. It shouldn’t include any of the actual -specification – don’t put conformance requirements in this section.

                  + +

                  This is one of the most important sections of the ZIP, and should be detailed +and comprehensive. It shouldn’t include any of the actual specification – +don’t put conformance requirements in this section.

                  +

                  Explain the status quo, why the status quo is in need of improvement, -and if applicable, the history of how this area has changed. Then -describe at a high level why this proposed solution addresses -the perceived issues. It is ok if this is somewhat redundant with the -abstract, but here you can go into a lot more detail.}

                  -

                  Requirements

                  -

                  {Describe design constraints on, or goals for the solution – -typically one paragraph for each constraint or goal. Again, don’t -actually specify anything here; this section is primarily for use as a -consistency check that what is specified meets the requirements.}

                  -

                  Non-requirements

                  -

                  {This section is entirely optional. If it is present, it describes -issues that the proposal is not attempting to address, that -someone might otherwise think it does or should.}

                  -

                  Specification

                  +and if applicable, the history of how this area has changed. Then describe +at a high level why this proposed solution addresses the perceived issues. +It is ok if this is somewhat redundant with the abstract, but here you can +go into a lot more detail.}

                  + +

                  Requirements

                  + +

                  {Describe design constraints on, or goals for the solution – typically one +paragraph for each constraint or goal. Again, don’t actually specify anything +here; this section is primarily for use as a consistency check that what is +specified meets the requirements.}

                  + +

                  Non-requirements

                  + +

                  {This section is entirely optional. If it is present, it describes issues that +the proposal is not attempting to address, that someone might otherwise think +it does or should.}

                  + +

                  Specification

                  +

                  {Replace this entire section.}

                  -

                  The Specification section describes what should change, using precise -language and conformance key words. Anything that is required in -order to implement the ZIP (or follow its process, in the case of a -Process ZIP) should be in this section.

                  -

                  Avoid overspecification! Also avoid underspecification. Specification -is hard. Don’t be afraid to ask for help.

                  -

                  Feel free to copy from other ZIPs doing similar things, e.g. defining -RPC calls, consensus rules, etc.

                  -

                  ZIPs MUST take into account differences between the Zcash Mainnet and -Testnet 6 where applicable. A consensus ZIP -MUST be able to be deployed on both Mainnet and Testnet.

                  -

                  Unless the specification is particularly simple, you will need to -organise it under subheadings.

                  -

                  Example subheading

                  -

                  At least while the ZIP is in Draft, we encourage writing open -questions and TODOs.

                  -

                  Open questions

                  + +

                  The Specification section describes what should change, using precise language and +conformance key words. Anything that is required in order to implement the ZIP +(or follow its process, in the case of a Process ZIP) should be in this section.

                  + +

                  Avoid overspecification! Also avoid underspecification. Specification is hard. +Don’t be afraid to ask for help.

                  + +

                  Feel free to copy from other ZIPs doing similar things, e.g. defining RPC calls, +consensus rules, etc.

                  + +

                  ZIPs MUST take into account differences between the Zcash Mainnet and Testnet +2 where applicable. A consensus ZIP MUST be able to be deployed +on both Mainnet and Testnet.

                  + +

                  Unless the specification is particularly simple, you will need to organise it under +subheadings.

                  + +

                  Example subheading

                  + +

                  At least while the ZIP is in Draft, we encourage writing open questions and TODOs.

                  + +

                  Open questions

                  +
                    -
                  • What happens if a full validator can’t parse the fandangle as a -doohicky?
                  • +
                  • What happens if a full validator can’t parse the fandangle as a doohicky?
                  +

                  TODO: define byte encoding for the Jabberwock.

                  -

                  Comparison of ZIPs to RFCs

                  -

                  Like RFCs, ZIPs are precise technical documents that SHOULD give -enough implementation information to implement part of a Zcash-related -protocol or follow a Zcash-related process 7.

                  + +

                  Comparison of ZIPs to RFCs

                  + +

                  Like RFCs, ZIPs are precise technical documents that SHOULD give enough +implementation information to implement part of a Zcash-related protocol or follow a +Zcash-related process 6.

                  +

                  ZIPs are different from RFCs in the following ways:

                  +
                    -
                  • Many (but not all) ZIPs are “living documents”; they are updated -in-place as the relevant areas of the protocol or process change. Unlike -in the RFC process, making a change in an area described by a published -ZIP does not necessarily require creating a new ZIP, although -that is an option if the change is extensive enough to warrant it.
                  • -
                  • The expected structure of a ZIP is more constrained than an RFC. For -example, the Specification section is REQUIRED, and all of the -conformance requirements MUST go in that section. The ZIP editors will -help you to ensure that things go in the right sections.
                  • -
                  • Security considerations SHOULD be spread throughout the text, in the -places where they are most relevant.
                  • +
                  • Many (but not all) ZIPs are “living documents”; they are updated in-place as +the relevant areas of the protocol or process change. Unlike in the RFC process, +making a change in an area described by a published ZIP does not necessarily +require creating a new ZIP, although that is an option if the change is extensive +enough to warrant it.
                  • +
                  • The expected structure of a ZIP is more constrained than an RFC. For example, +the Specification section is REQUIRED, and all of the conformance requirements +MUST go in that section. The ZIP editors will help you to ensure that things +go in the right sections.
                  • +
                  • Security considerations SHOULD be spread throughout the text, in the places +where they are most relevant.
                  -

                  Using mathematical notation

                  -

                  Embedded LaTeX x + y is allowed and -encouraged in ZIPs. The syntax for inline math is -“:math:latex -code`" in reStructuredText or "latexcode`” -in Markdown. The rendered HTML will use KaTeX 8, -which only supports a subset of LaTeX, so you will need to double-check -that the rendering is as intended.

                  -

                  In general the conventions in the Zcash protocol specification SHOULD -be followed. If you find this difficult, don’t worry too much about it -in initial drafts; the ZIP editors will catch any inconsistencies in -review.

                  -

                  Notes and warnings

                  -
                  -

                  “.. note::” in reStructuredText, or -“:::info” (terminated by “:::”) in Markdown, -can be used for an aside from the main text.

                  -

                  The rendering of notes is colourful and may be distracting, so they -should only be used for important points.

                  -
                  -
                  -

                  “.. warning::” in reStructuredText, or -“:::warning” (terminated by “:::”) in -Markdown, can be used for warnings.

                  -

                  Warnings should be used very sparingly — for example to signal that a -entire specification, or part of it, may be inapplicable or could cause -significant interoperability or security problems. In most cases, a -“MUST” or “SHOULD” conformance requirement is more appropriate.

                  -
                  -

                  Valid markup

                  -

                  This is optional before publishing a PR, but to check whether a -document is valid reStructuredText or Markdown, first install -rst2html5 and pandoc. E.g. on Debian-based -distros::

                  -
                  sudo apt install python3-pip pandoc perl sed
                  -pip3 install docutils==0.19 rst2html5
                  -

                  Then, with draft-myzip.rst or -draft-myzip.md in the root directory of a clone of this -repo, run::

                  -
                  make draft-myzip.html
                  -

                  (or just “make”) and view draft-myzip.html -in a web browser.

                  -

                  Citations and references

                  -

                  Each reference should be given a short name, e.g. “snark” 9. The syntax to cite that reference -is “[#snark]_” in reStructuredText, or -“[^snark]” in Markdown.

                  -

                  The corresponding entry in the References -section should look like this in reStructuredText:

                  -
                  .. [#snark] `The Hunting of the Snark <https://www.gutenberg.org/files/29888/29888-h/29888-h.htm>_. Lewis Carroll, with illustrations by Henry Holiday. MacMillan and Co. London. March 29, 1876.
                  + +

                  Using mathematical notation

                  + +

                  Embedded \(\LaTeX\), e.g. \(x + y\), is allowed and encouraged in ZIPs. The syntax for +inline math is “$latex code$” in either Markdown or (as a +non-standard extension) reStructuredText. This syntax does not work in tables for +reStructuredText; in that case use “:math:`latex code`” instead.

                  + +

                  The rendered HTML will use KaTeX 7, which only supports a subset of \(\LaTeX\), +so you will need to double-check that the rendering is as intended.

                  + +

                  In general the conventions in the Zcash protocol specification SHOULD be followed. +If you find this difficult, don’t worry too much about it in initial drafts; the +ZIP editors will catch any inconsistencies in review.

                  + +

                  Notes and warnings

                  + +

                  :::info +“.. note::” in reStructuredText, or “:::info” (terminated by +“:::”) in Markdown, can be used for an aside from the main text. +

                  + +
                  +
                  The rendering of notes is colourful and may be distracting, so they should
                  +
                  only be used for important points.
                  +
                  ::
                  + +
                  ::warning +“.. warning::” in reStructuredText, or “:::warning” (terminated by +“:::”) in Markdown, can be used for warnings.
                  + +
                  Warnings should be used very sparingly — for example to signal that a
                  +
                  entire specification, or part of it, may be inapplicable or could cause
                  +
                  significant interoperability or security problems. In most cases, a “MUST”
                  +
                  or “SHOULD” conformance requirement is more appropriate.
                  +
                  ::
                  +
                  + +

                  Valid markup

                  + +

                  This is optional before publishing a PR, but to check whether a document is valid +reStructuredText or Markdown, first install docutils and rst2html5, and +build MultiMarkdown-6. E.g. on Debian-based distros::

                  + +
                  sudo apt install python3-pip perl sed cmake
                  +pip3 install 'docutils==0.21.2' 'rst2html5==2.0.1'
                  +git clone -b develop https://github.com/Electric-Coin-Company/MultiMarkdown-6
                  +cd MultiMarkdown-6
                  +make release
                  +cd build
                  +make
                  +sudo make install
                  +
                  + +

                  Then, with draft-myzip.rst or draft-myzip.md in the root directory of a clone +of this repo, run::

                  + +
                  make draft-myzip.html
                  +
                  + +

                  (or just “make”) and view draft-myzip.html in a web browser.

                  + +

                  Citations and references

                  + +

                  Each reference should be given a short name, e.g. “snark” 8. The syntax to cite +that reference is “[#snark]_” in reStructuredText, or “[^snark]” in Markdown.

                  + +

                  The corresponding entry in the References section should look like this in +reStructuredText:

                  + +
                  .. [#snark] `The Hunting of the Snark <https://www.gutenberg.org/files/29888/29888-h/29888-h.htm>_. Lewis Carroll, with illustrations by Henry Holiday. MacMillan and Co. London. March 29, 1876.
                  +
                  +

                  or like this in Markdown::

                  -
                  [^snark] [The Hunting of the Snark](https://www.gutenberg.org/files/29888/29888-h/29888-h.htm). Lewis Carroll, with illustrations by Henry Holiday. MacMillan and Co. London. March 29, 1876.
                  -

                  Note that each entry must be on a single line regardless of how long -that makes the line. In Markdown there must be a blank line between -entries.

                  -

                  The current rendering of a Markdown ZIP reorders the references -according to their first use; the rendering of a reStructuredText ZIP -keeps them in the same order as in the References section.

                  + +
                  [^snark] [The Hunting of the Snark](https://www.gutenberg.org/files/29888/29888-h/29888-h.htm). Lewis Carroll, with illustrations by Henry Holiday. MacMillan and Co. London. March 29, 1876.
                  +
                  + +

                  Note that each entry must be on a single line regardless of how long that makes the +line. In Markdown there must be a blank line between entries.

                  + +

                  The current rendering of a Markdown ZIP reorders the references according to +their first use; the rendering of a reStructuredText ZIP keeps them in the same +order as in the References section.

                  +

                  To link to another section of the same ZIP, use

                  -
                  `Section title`_
                  + +
                  `Section title`_
                  +
                  +

                  in reStructuredText, or

                  -
                  [Section title]
                  + +
                  [Section title]
                  +
                  +

                  in Markdown.

                  -

                  Citing the Zcash -protocol specification

                  -

                  For references to the Zcash protocol specification, prefer to link to -a section anchor, and name the reference as -[^protocol-<anchor>]. This makes it more likely that -the link will remain valid if sections are renumbered or if content is -moved. The anchors in the protocol specification can be displayed by -clicking on a section heading in most PDF viewers. References to -particular sections should be versioned, even though the link will point -to the most recent stable version.

                  -

                  Do not include the “https://zips.z.cash/” part of URLs -to ZIPs or the protocol spec.

                  -

                  Reference implementation

                  -

                  {This section is entirely optional; if present, it usually gives -links to zcashd or zebrad PRs.}

                  -

                  References

                  -
                  + +

                  Citing the Zcash protocol specification

                  + +

                  For references to the Zcash protocol specification, prefer to link to a section +anchor, and name the reference as [^protocol-<anchor>]. This makes it more likely +that the link will remain valid if sections are renumbered or if content is moved. +The anchors in the protocol specification can be displayed by clicking on a section +heading in most PDF viewers. References to particular sections should be versioned, +even though the link will point to the most recent stable version.

                  + +

                  Do not include the “https://zips.z.cash/” part of URLs to ZIPs or the protocol spec.

                  + +

                  Reference implementation

                  + +

                  {This section is entirely optional; if present, it usually gives links to zcashd or +zebrad PRs.}

                  + +

                  References

                  + +

                    -
                  1. Information on BCP 14 — -“RFC 2119: Key words for use in RFCs to Indicate Requirement Levels” and -“RFC 8174: Ambiguity of Uppercase vs Lowercase in RFC 2119 Key -Words”↩︎

                  2. -
                  3. Zcash Protocol Specification, -Version 2022.3.8. Section 3.12: Mainnet and Testnet↩︎

                  4. -
                  5. Zcash Protocol Specification, -Version 2022.3.8. Section 3.3: The Block Chain↩︎

                  6. -
                  7. Zcash -Protocol Specification, Version 2022.3.8 or later↩︎

                  8. -
                  9. Zcash Protocol Specification, -Version 2022.3.8. Section 1: Introduction↩︎

                  10. -
                  11. Zcash Protocol Specification, -Version 2022.3.8. Section 3.12: Mainnet and Testnet↩︎

                  12. -
                  13. ZIP 0: ZIP -Process↩︎

                  14. -
                  15. KaTeX - -The fastest math typesetting library for the web↩︎

                  16. -
                  17. The -Hunting of the Snark. Lewis Carroll, with illustrations by Henry -Holiday. MacMillan and Co. London. March 29, 1876.↩︎

                  18. + +
                  19. +

                    Information on BCP 14 — “RFC 2119: Key words for use in RFCs to Indicate Requirement Levels” and “RFC 8174: Ambiguity of Uppercase vs Lowercase in RFC 2119 Key Words”  ↩︎

                    +
                  20. + +
                  21. +

                    Zcash Protocol Specification, Version 2022.3.8. Section 3.12: Mainnet and Testnet  ↩︎

                    +
                  22. + +
                  23. +

                    Zcash Protocol Specification, Version 2022.3.8. Section 3.3: The Block Chain  ↩︎

                    +
                  24. + +
                  25. +

                    Zcash Protocol Specification, Version 2022.3.8 or later  ↩︎

                    +
                  26. + +
                  27. +

                    Zcash Protocol Specification, Version 2022.3.8. Section 1: Introduction  ↩︎

                    +
                  28. + +
                  29. +

                    ZIP 0: ZIP Process  ↩︎

                    +
                  30. + +
                  31. +

                    KaTeX - The fastest math typesetting library for the web  ↩︎

                    +
                  32. + +
                  33. +

                    The Hunting of the Snark. Lewis Carroll, with illustrations by Henry Holiday. MacMillan and Co. London. March 29, 1876.  ↩︎

                    +
                  34. +
                  -
                  + diff --git a/rendered/zip-guide.html b/rendered/zip-guide.html index ccc02ec80..cd6a14055 100644 --- a/rendered/zip-guide.html +++ b/rendered/zip-guide.html @@ -3,7 +3,9 @@ ZIP guide: {Something Short and To the Point} - + + +
                  @@ -78,8 +80,11 @@

                  Using mathematical notation

                  Embedded - \(\LaTeX\) - is allowed and encouraged in ZIPs. The syntax for inline math is ":math:`latex code`" in reStructuredText or "$latex code$" in Markdown. The rendered HTML will use KaTeX 6, which only supports a subset of + \(\LaTeX\!\) + , e.g. + \(x + y\!\) + , is allowed and encouraged in ZIPs. The syntax for inline math is "$latex code$" in either Markdown or (as a non-standard extension) reStructuredText. This syntax does not work in tables for reStructuredText; in that case use ":math:`latex code`" instead.

                  +

                  The rendered HTML will use KaTeX 6, which only supports a subset of \(\LaTeX\!\) , so you will need to double-check that the rendering is as intended.

                  In general the conventions in the Zcash protocol specification SHOULD be followed. If you find this difficult, don't worry too much about it in initial drafts; the ZIP editors will catch any inconsistencies in review.

                  @@ -95,9 +100,15 @@

                  Valid markup

                  -

                  This is optional before publishing a PR, but to check whether a document is valid reStructuredText or Markdown, first install rst2html5 and pandoc. E.g. on Debian-based distros:

                  -
                  sudo apt install python3-pip pandoc perl sed
                  -pip3 install docutils==0.19 rst2html5
                  +

                  This is optional before publishing a PR, but to check whether a document is valid reStructuredText or Markdown, first install docutils and rst2html5, and build MultiMarkdown-6. E.g. on Debian-based distros:

                  +
                  sudo apt install python3-pip perl sed cmake
                  +pip3 install 'docutils==0.21.2' 'rst2html5==2.0.1'
                  +git clone -b develop https://github.com/Electric-Coin-Company/MultiMarkdown-6
                  +cd MultiMarkdown-6
                  +make release
                  +cd build
                  +make
                  +sudo make install

                  Then, with draft-myzip.rst or draft-myzip.md in the root directory of a clone of this repo, run:

                  make draft-myzip.html

                  (or just "make") and view draft-myzip.html in a web browser.

                  diff --git a/zips/zip-0032.rst b/zips/zip-0032.rst index 69817e5a3..ebf2b6f0c 100644 --- a/zips/zip-0032.rst +++ b/zips/zip-0032.rst @@ -15,7 +15,7 @@ Created: 2018-05-22 License: MIT -:math:`% This ZIP makes heavy use of mathematical markup. If you can see this, you may want to instead view the rendered version at https://zips.z.cash/zip-0032 .` +$% This ZIP makes heavy use of mathematical markup. If you can see this, you may want to instead view the rendered version at https://zips.z.cash/zip-0032 .$ Terminology =========== @@ -83,64 +83,64 @@ Conventions Most of the notation and functions used in this ZIP are defined in the Zcash protocol specification [#protocol]_. They are reproduced here for convenience: -- :math:`\mathsf{truncate}_k(S)` means the sequence formed from the first :math:`k` elements of :math:`S`. +- $\mathsf{truncate}_k(S)$ means the sequence formed from the first $k$ elements of $S$. -- :math:`a\,||\,b` means the concatenation of sequences :math:`a` then :math:`b`. +- $a\,||\,b$ means the concatenation of sequences $a$ then $b$. -- :math:`[k] P` means scalar multiplication of the elliptic curve point :math:`P` by the scalar :math:`k`. +- $[k] P$ means scalar multiplication of the elliptic curve point $P$ by the scalar $k$. -- :math:`\mathsf{LEOS2IP}_\ell(S)` is the integer in range :math:`\{ 0\,.\!. 2^\ell - 1 \}` represented in - little-endian order by the byte sequence :math:`S` of length :math:`\ell/8`. +- $\mathsf{LEOS2IP}_\ell(S)$ is the integer in range $\{ 0\,..\, 2^\ell - 1 \}$ represented in + little-endian order by the byte sequence $S$ of length $\ell/8$. -- :math:`\mathsf{I2LEBSP}_\ell(k)` is the sequence of :math:`\ell` bits representing :math:`k` in +- $\mathsf{I2LEBSP}_\ell(k)$ is the sequence of $\ell$ bits representing $k$ in little-endian order. -- :math:`\mathsf{LEBS2OSP}_\ell(B)` is defined as follows when :math:`\ell` is a multiple of :math:`8`: - convert each group of 8 bits in :math:`B` to a byte value with the least significant bit first, and +- $\mathsf{LEBS2OSP}_\ell(B)$ is defined as follows when $\ell$ is a multiple of $8$: + convert each group of 8 bits in $B$ to a byte value with the least significant bit first, and concatenate the resulting bytes in the same order as the groups. -- :math:`\mathsf{repr}_\mathbb{J}(P)` is the representation of the Jubjub elliptic curve point :math:`P` +- $\mathsf{repr}_\mathbb{J}(P)$ is the representation of the Jubjub elliptic curve point $P$ as a bit sequence, defined in [#protocol-jubjub]_. -- :math:`\mathsf{BLAKE2b}\text{-}\mathsf{256}(p, x)` refers to unkeyed BLAKE2b-256 in sequential mode, - with an output digest length of 32 bytes, 16-byte personalization string :math:`p`, and input :math:`x`. +- $\mathsf{BLAKE2b}\text{-}\mathsf{256}(p, x)$ refers to unkeyed BLAKE2b-256 in sequential mode, + with an output digest length of 32 bytes, 16-byte personalization string $p$, and input $x$. -- :math:`\mathsf{BLAKE2b}\text{-}\mathsf{512}(p, x)` refers to unkeyed BLAKE2b-512 in sequential mode, - with an output digest length of 64 bytes, 16-byte personalization string :math:`p`, and input :math:`x`. +- $\mathsf{BLAKE2b}\text{-}\mathsf{512}(p, x)$ refers to unkeyed BLAKE2b-512 in sequential mode, + with an output digest length of 64 bytes, 16-byte personalization string $p$, and input $x$. -- :math:`\mathsf{PRF^{expand}}(\mathsf{sk}, t) :=`:math:`\mathsf{BLAKE2b}\text{-}\mathsf{512}(\texttt{“Zcash_ExpandSeed”},`:math:`\mathsf{sk}\,||\,t)` +- $\mathsf{PRF^{expand}}(\mathsf{sk}, t) :=$ $\mathsf{BLAKE2b}\text{-}\mathsf{512}(\texttt{“Zcash\_ExpandSeed”},$ $\mathsf{sk}\,||\,t)$. -- :math:`r_\mathbb{J}` is the order of the Jubjub large prime subgroup. +- $r_\mathbb{J}$ is the order of the Jubjub large prime subgroup. -- :math:`r_\mathbb{P}` is the order of the Pallas curve. +- $r_\mathbb{P}$ is the order of the Pallas curve. -- :math:`\mathsf{ToScalar^{Sapling}}(x) :=`:math:`\mathsf{LEOS2IP}_{512}(x) \pmod{r_\mathbb{J}}`. +- $\mathsf{ToScalar^{Sapling}}(x) :=$ $\mathsf{LEOS2IP}_{512}(x) \pmod{r_\mathbb{J}}$. -- :math:`\mathsf{ToScalar^{Orchard}}(x) :=`:math:`\mathsf{LEOS2IP}_{512}(x) \pmod{r_\mathbb{P}}`. +- $\mathsf{ToScalar^{Orchard}}(x) :=$ $\mathsf{LEOS2IP}_{512}(x) \pmod{r_\mathbb{P}}$. -- :math:`\mathsf{DiversifyHash^{Sapling}}(d)` maps a diversifier :math:`d` to a base point on the Jubjub elliptic - curve, or to :math:`\bot` if the diversifier is invalid. It is instantiated in [#protocol-concretediversifyhash]_. +- $\mathsf{DiversifyHash^{Sapling}}(d)$ maps a diversifier $d$ to a base point on the Jubjub elliptic + curve, or to $\bot$ if the diversifier is invalid. It is instantiated in [#protocol-concretediversifyhash]_. The following algorithm standardized in [#NIST-SP-800-38G]_ is used: -- :math:`\mathsf{FF1}\text{-}\mathsf{AES256.Encrypt}(key, tweak, x)` refers to the FF1 encryption algorithm - using AES with a 256-bit :math:`key`, and parameters :math:`radix = 2,`:math:`minlen = 88,`:math:`maxlen = 88`. - It will be used only with the empty string :math:`\texttt{“”}` as the :math:`tweak`. :math:`x` is a +- $\mathsf{FF1}\text{-}\mathsf{AES256.Encrypt}(key, tweak, x)$ refers to the FF1 encryption algorithm + using AES with a 256-bit $key$, and parameters $radix = 2,$ $minlen = 88,$ $maxlen = 88$. + It will be used only with the empty string $\texttt{“”}$ as the $tweak$. $x$ is a sequence of 88 bits, as is the output. We also define the following conversion function: -- :math:`\mathsf{I2LEOSP}_\ell(k)` is the byte sequence :math:`S` of length :math:`\ell/8` representing in - little-endian order the integer :math:`k` in range :math:`\{ 0\,.\!. 2^\ell - 1 \}`. It is the reverse - operation of :math:`\mathsf{LEOS2IP}_\ell(S)`. +- $\mathsf{I2LEOSP}_\ell(k)$ is the byte sequence $S$ of length $\ell/8$ representing in + little-endian order the integer $k$ in range $\{ 0\,..\, 2^\ell - 1 \}$. It is the reverse + operation of $\mathsf{LEOS2IP}_\ell(S)$. Implementors should note that this ZIP is consistently little-endian (in keeping with the Sapling and Orchard specifications), which is the opposite of BIP 32. -We adapt the path notation of BIP 32 [#bip-0032]_ to describe shielded HD paths, using prime marks (:math:`'`) to -indicate hardened derivation (:math:`i' = i + 2^{31}`) as in BIP 44 [#bip-0044]_: +We adapt the path notation of BIP 32 [#bip-0032]_ to describe shielded HD paths, using prime marks ($\kern-0.1em{}'$) to +indicate hardened derivation ($\!i' = i + 2^{31}$) as in BIP 44 [#bip-0044]_: -- :math:`\mathsf{CKDfvk}(\mathsf{CKDfvk}(\mathsf{CKDfvk}(m_\mathsf{Sapling}, a), b), c)` is written as :math:`m_\mathsf{Sapling} / a / b / c`. +- $\mathsf{CKDfvk}(\mathsf{CKDfvk}(\mathsf{CKDfvk}(m_\mathsf{Sapling}, a), b), c)$ is written as $m_\mathsf{Sapling} / a / b / c$. Specification: Sapling key derivation @@ -163,110 +163,110 @@ keys in BIP 32 do not map cleanly to Sapling's key components. We take the follo the trust semantics of BIP 32: someone with access to a BIP 32 extended public key is able to view all transactions involving that address, which a Sapling full viewing key also enables. -We represent a Sapling extended spending key as :math:`(\mathsf{ask, nsk, ovk, dk, c})`, where -:math:`(\mathsf{ask, nsk, ovk})` is the normal Sapling expanded spending key, :math:`\mathsf{dk}` is a -diversifier key, and :math:`\mathsf{c}` is the chain code. +We represent a Sapling extended spending key as $(\mathsf{ask, nsk, ovk, dk, c})$, where +$(\mathsf{ask, nsk, ovk})$ is the normal Sapling expanded spending key, $\mathsf{dk}$ is a +diversifier key, and $\mathsf{c}$ is the chain code. -We represent a Sapling extended full viewing key as :math:`(\mathsf{ak, nk, ovk, dk, c})`, where -:math:`(\mathsf{ak, nk, ovk})` is the normal Sapling full viewing key, :math:`\mathsf{dk}` is the same -diversifier key as above, and :math:`\mathsf{c}` is the chain code. +We represent a Sapling extended full viewing key as $(\mathsf{ak, nk, ovk, dk, c})$, where +$(\mathsf{ak, nk, ovk})$ is the normal Sapling full viewing key, $\mathsf{dk}$ is the same +diversifier key as above, and $\mathsf{c}$ is the chain code. Sapling helper functions ------------------------ Define -* :math:`\mathsf{EncodeExtSKParts}(\mathsf{ask, nsk, ovk, dk}) :=`:math:`\mathsf{I2LEOSP}_{256}(\mathsf{ask})`:math:`||\,\mathsf{I2LEOSP}_{256}(\mathsf{nsk})`:math:`||\,\mathsf{ovk}`:math:`||\,\mathsf{dk}` -* :math:`\mathsf{EncodeExtFVKParts}(\mathsf{ak, nk, ovk, dk}) :=`:math:`\mathsf{LEBS2OSP}_{256}(\mathsf{repr}_\mathbb{J}(\mathsf{ak}))`:math:`||\,\mathsf{LEBS2OSP}_{256}(\mathsf{repr}_\mathbb{J}(\mathsf{nk}))`:math:`||\,\mathsf{ovk}`:math:`||\,\mathsf{dk}` +* $\mathsf{EncodeExtSKParts}(\mathsf{ask, nsk, ovk, dk}) :=$ $\mathsf{I2LEOSP}_{256}(\mathsf{ask})$ $||\,\mathsf{I2LEOSP}_{256}(\mathsf{nsk})$ $||\,\mathsf{ovk}$ $||\,\mathsf{dk}$ +* $\mathsf{EncodeExtFVKParts}(\mathsf{ak, nk, ovk, dk}) :=$ $\mathsf{LEBS2OSP}_{256}(\mathsf{repr}_\mathbb{J}(\mathsf{ak}))$ $||\,\mathsf{LEBS2OSP}_{256}(\mathsf{repr}_\mathbb{J}(\mathsf{nk}))$ $||\,\mathsf{ovk}$ $||\,\mathsf{dk}$ Sapling master key generation ----------------------------- -Let :math:`S` be a seed byte sequence of a chosen length, which MUST be at least 32 and at most 252 bytes. +Let $S$ be a seed byte sequence of a chosen length, which MUST be at least 32 and at most 252 bytes. -- Calculate :math:`I = \mathsf{BLAKE2b}\text{-}\mathsf{512}(\texttt{“ZcashIP32Sapling”}, S)`. -- Split :math:`I` into two 32-byte sequences, :math:`I_L` and :math:`I_R`. -- Use :math:`I_L` as the master spending key :math:`\mathsf{sk}_m`, and :math:`I_R` as the master chain code - :math:`\mathsf{c}_m`. -- Calculate :math:`\mathsf{ask}_m`, :math:`\mathsf{nsk}_m`, and :math:`\mathsf{ovk}_m` via the standard +- Calculate $I = \mathsf{BLAKE2b}\text{-}\mathsf{512}(\texttt{“ZcashIP32Sapling”}, S)$. +- Split $I$ into two 32-byte sequences, $I_L$ and $I_R$. +- Use $I_L$ as the master spending key $\mathsf{sk}_m$, and $I_R$ as the master chain code + $\mathsf{c}_m$. +- Calculate $\mathsf{ask}_m$, $\mathsf{nsk}_m$, and $\mathsf{ovk}_m$ via the standard Sapling derivation [#protocol-saplingkeycomponents]_: - - :math:`\mathsf{ask}_m = \mathsf{ToScalar^{Sapling}}(\mathsf{PRF^{expand}}(\mathsf{sk}_m, [\texttt{0x00}]))` - - :math:`\mathsf{nsk}_m = \mathsf{ToScalar^{Sapling}}(\mathsf{PRF^{expand}}(\mathsf{sk}_m, [\texttt{0x01}]))` - - :math:`\mathsf{ovk}_m = \mathsf{truncate}_{32}(\mathsf{PRF^{expand}}(\mathsf{sk}_m, [\texttt{0x02}]))`. + - $\mathsf{ask}_m = \mathsf{ToScalar^{Sapling}}(\mathsf{PRF^{expand}}(\mathsf{sk}_m, [\mathtt{0x00}]))$ + - $\mathsf{nsk}_m = \mathsf{ToScalar^{Sapling}}(\mathsf{PRF^{expand}}(\mathsf{sk}_m, [\mathtt{0x01}]))$ + - $\mathsf{ovk}_m = \mathsf{truncate}_{32}(\mathsf{PRF^{expand}}(\mathsf{sk}_m, [\mathtt{0x02}]))$. -- Calculate :math:`\mathsf{dk}_m` similarly: +- Calculate $\mathsf{dk}_m$ similarly: - - :math:`\mathsf{dk}_m = \mathsf{truncate}_{32}(\mathsf{PRF^{expand}}(\mathsf{sk}_m, [\texttt{0x10}]))`. + - $\mathsf{dk}_m = \mathsf{truncate}_{32}(\mathsf{PRF^{expand}}(\mathsf{sk}_m, [\mathtt{0x10}]))$. -- Return :math:`(\mathsf{ask}_m, \mathsf{nsk}_m, \mathsf{ovk}_m, \mathsf{dk}_m, \mathsf{c}_m)` as the - master extended spending key :math:`m_\mathsf{Sapling}`. +- Return $(\mathsf{ask}_m, \mathsf{nsk}_m, \mathsf{ovk}_m, \mathsf{dk}_m, \mathsf{c}_m)$ as the + master extended spending key $m_\mathsf{Sapling}$. -Note that the master extended key is invalid if :math:`\mathsf{ask}_m` is :math:`0`, or if the corresponding -:math:`\mathsf{ivk}` derived as specified in [#protocol-saplingkeycomponents]_ is :math:`0`. +Note that the master extended key is invalid if $\mathsf{ask}_m$ is $0$, or if the corresponding +$\mathsf{ivk}$ derived as specified in [#protocol-saplingkeycomponents]_ is $0$. Sapling child key derivation ---------------------------- -As in BIP 32, the method for deriving a child extended key, given a parent extended key and an index :math:`i`, +As in BIP 32, the method for deriving a child extended key, given a parent extended key and an index $i$, depends on the type of key being derived, and whether this is a hardened or non-hardened derivation. Deriving a child extended spending key `````````````````````````````````````` -:math:`\mathsf{CKDsk}((\mathsf{ask}_{par}, \mathsf{nsk}_{par}, \mathsf{ovk}_{par}, \mathsf{dk}_{par}, \mathsf{c}_{par}), i)`:math:`\rightarrow (\mathsf{ask}_i, \mathsf{nsk}_i, \mathsf{ovk}_i, \mathsf{dk}_i, \mathsf{c}_i)` +$\mathsf{CKDsk}((\mathsf{ask}_{par}, \mathsf{nsk}_{par}, \mathsf{ovk}_{par}, \mathsf{dk}_{par}, \mathsf{c}_{par}), i)$ $\rightarrow (\mathsf{ask}_i, \mathsf{nsk}_i, \mathsf{ovk}_i, \mathsf{dk}_i, \mathsf{c}_i)$ : -- Check whether :math:`i \geq 2^{31}` (whether the child is a hardened key). +- Check whether $i \geq 2^{31}$ (whether the child is a hardened key). - If so (hardened child): - let :math:`I = \mathsf{PRF^{expand}}(\mathsf{c}_{par}, [\texttt{0x11}]`:math:`||\,\mathsf{EncodeExtSKParts}(\mathsf{ask}_{par}, \mathsf{nsk}_{par}, \mathsf{ovk}_{par}, \mathsf{dk}_{par})`:math:`||\,\mathsf{I2LEOSP}_{32}(i))`. + let $I = \mathsf{PRF^{expand}}(\mathsf{c}_{par}, [\mathtt{0x11}]$ $||\,\mathsf{EncodeExtSKParts}(\mathsf{ask}_{par}, \mathsf{nsk}_{par}, \mathsf{ovk}_{par}, \mathsf{dk}_{par})$ $||\,\mathsf{I2LEOSP}_{32}(i))$. - If not (normal child): - let :math:`I = \mathsf{PRF^{expand}}(\mathsf{c}_{par}, [\texttt{0x12}]`:math:`||\,\mathsf{EncodeExtFVKParts}(\mathsf{ak}_{par}, \mathsf{nk}_{par}, \mathsf{ovk}_{par}, \mathsf{dk}_{par})`:math:`||\,\mathsf{I2LEOSP}_{32}(i))` - where :math:`(\mathsf{nk}_{par}, \mathsf{ak}_{par}, \mathsf{ovk}_{par})` is the full viewing key derived from - :math:`(\mathsf{ask}_{par}, \mathsf{nsk}_{par}, \mathsf{ovk}_{par})` as described in [#protocol-saplingkeycomponents]_. + let $I = \mathsf{PRF^{expand}}(\mathsf{c}_{par}, [\mathtt{0x12}]$ $||\,\mathsf{EncodeExtFVKParts}(\mathsf{ak}_{par}, \mathsf{nk}_{par}, \mathsf{ovk}_{par}, \mathsf{dk}_{par})$ $||\,\mathsf{I2LEOSP}_{32}(i))$ + where $(\mathsf{nk}_{par}, \mathsf{ak}_{par}, \mathsf{ovk}_{par})$ is the full viewing key derived from + $(\mathsf{ask}_{par}, \mathsf{nsk}_{par}, \mathsf{ovk}_{par})$ as described in [#protocol-saplingkeycomponents]_. -- Split :math:`I` into two 32-byte sequences, :math:`I_L` and :math:`I_R`. -- Let :math:`I_\mathsf{ask} = \mathsf{ToScalar^{Sapling}}(\mathsf{PRF^{expand}}(I_L, [\texttt{0x13}]))`. -- Let :math:`I_\mathsf{nsk} = \mathsf{ToScalar^{Sapling}}(\mathsf{PRF^{expand}}(I_L, [\texttt{0x14}]))`. +- Split $I$ into two 32-byte sequences, $I_L$ and $I_R$. +- Let $I_\mathsf{ask} = \mathsf{ToScalar^{Sapling}}(\mathsf{PRF^{expand}}(I_L, [\mathtt{0x13}]))$. +- Let $I_\mathsf{nsk} = \mathsf{ToScalar^{Sapling}}(\mathsf{PRF^{expand}}(I_L, [\mathtt{0x14}]))$. - Return: - - :math:`\mathsf{ask}_i = (I_\mathsf{ask} + \mathsf{ask}_{par}) \pmod{r_\mathbb{J}}` - - :math:`\mathsf{nsk}_i = (I_\mathsf{nsk} + \mathsf{nsk}_{par}) \pmod{r_\mathbb{J}}` - - :math:`\mathsf{ovk}_i = \mathsf{truncate}_{32}(\mathsf{PRF^{expand}}(I_L, [\texttt{0x15}]`:math:`||\,\mathsf{ovk}_{par}))` - - :math:`\mathsf{dk}_i = \mathsf{truncate}_{32}(\mathsf{PRF^{expand}}(I_L, [\texttt{0x16}]`:math:`||\,\mathsf{dk}_{par}))` - - :math:`\mathsf{c}_i = I_R`. + - $\mathsf{ask}_i = (I_\mathsf{ask} + \mathsf{ask}_{par}) \pmod{r_\mathbb{J}}$ + - $\mathsf{nsk}_i = (I_\mathsf{nsk} + \mathsf{nsk}_{par}) \pmod{r_\mathbb{J}}$ + - $\mathsf{ovk}_i = \mathsf{truncate}_{32}(\mathsf{PRF^{expand}}(I_L, [\mathtt{0x15}]$ $||\,\mathsf{ovk}_{par}))$ + - $\mathsf{dk}_i = \mathsf{truncate}_{32}(\mathsf{PRF^{expand}}(I_L, [\mathtt{0x16}]$ $||\,\mathsf{dk}_{par}))$ + - $\mathsf{c}_i = I_R$. -Note that the child extended key is invalid if :math:`\mathsf{ask}_i` is :math:`0`, or if the corresponding -:math:`\mathsf{ivk}` derived as specified in [#protocol-saplingkeycomponents]_ is :math:`0`. +Note that the child extended key is invalid if $\mathsf{ask}_i$ is $0$, or if the corresponding +$\mathsf{ivk}$ derived as specified in [#protocol-saplingkeycomponents]_ is $0$. Deriving a child extended full viewing key `````````````````````````````````````````` -Let :math:`\mathcal{G}^\mathsf{Sapling}` be as defined in [#protocol-concretespendauthsig]_ and -let :math:`\mathcal{H}^\mathsf{Sapling}` be as defined in [#protocol-saplingkeycomponents]_. +Let $\mathcal{G}^\mathsf{Sapling}$ be as defined in [#protocol-concretespendauthsig]_ and +let $\mathcal{H}^\mathsf{Sapling}$ be as defined in [#protocol-saplingkeycomponents]_. -:math:`\mathsf{CKDfvk}((\mathsf{ak}_{par}, \mathsf{nk}_{par}, \mathsf{ovk}_{par}, \mathsf{dk}_{par}, \mathsf{c}_{par}), i)`:math:`\rightarrow (\mathsf{ak}_{i}, \mathsf{nk}_{i}, \mathsf{ovk}_{i}, \mathsf{dk}_{i}, \mathsf{c}_{i})` +$\mathsf{CKDfvk}((\mathsf{ak}_{par}, \mathsf{nk}_{par}, \mathsf{ovk}_{par}, \mathsf{dk}_{par}, \mathsf{c}_{par}), i)$ $\rightarrow (\mathsf{ak}_{i}, \mathsf{nk}_{i}, \mathsf{ovk}_{i}, \mathsf{dk}_{i}, \mathsf{c}_{i})$ : -- Check whether :math:`i \geq 2^{31}` (whether the child is a hardened key). +- Check whether $i \geq 2^{31}$ (whether the child is a hardened key). - If so (hardened child): return failure. - If not (normal child): let - :math:`I = \mathsf{PRF^{expand}}(\mathsf{c}_{par}, [\texttt{0x12}]`:math:`||\,\mathsf{EncodeExtFVKParts}(\mathsf{ak}_{par}, \mathsf{nk}_{par}, \mathsf{ovk}_{par}, \mathsf{dk}_{par})`:math:`||\,\mathsf{I2LEOSP}_{32}(i))`. + $I = \mathsf{PRF^{expand}}(\mathsf{c}_{par}, [\mathtt{0x12}]$ $||\,\mathsf{EncodeExtFVKParts}(\mathsf{ak}_{par}, \mathsf{nk}_{par}, \mathsf{ovk}_{par}, \mathsf{dk}_{par})$ $||\,\mathsf{I2LEOSP}_{32}(i))$. -- Split :math:`I` into two 32-byte sequences, :math:`I_L` and :math:`I_R`. -- Let :math:`I_\mathsf{ask} = \mathsf{ToScalar^{Sapling}}(\mathsf{PRF^{expand}}(I_L, [\texttt{0x13}]))`. -- Let :math:`I_\mathsf{nsk} = \mathsf{ToScalar^{Sapling}}(\mathsf{PRF^{expand}}(I_L, [\texttt{0x14}]))`. +- Split $I$ into two 32-byte sequences, $I_L$ and $I_R$. +- Let $I_\mathsf{ask} = \mathsf{ToScalar^{Sapling}}(\mathsf{PRF^{expand}}(I_L, [\mathtt{0x13}]))$. +- Let $I_\mathsf{nsk} = \mathsf{ToScalar^{Sapling}}(\mathsf{PRF^{expand}}(I_L, [\mathtt{0x14}]))$. - Return: - - :math:`\mathsf{ak}_i = [I_\mathsf{ask}]\,\mathcal{G}^\mathsf{Sapling} + \mathsf{ak}_{par}` - - :math:`\mathsf{nk}_i = [I_\mathsf{nsk}]\,\mathcal{H}^\mathsf{Sapling} + \mathsf{nk}_{par}` - - :math:`\mathsf{ovk}_i = \mathsf{truncate}_{32}(\mathsf{PRF^{expand}}(I_L, [\texttt{0x15}]`:math:`||\,\mathsf{ovk}_{par}))` - - :math:`\mathsf{dk}_i = \mathsf{truncate}_{32}(\mathsf{PRF^{expand}}(I_L, [\texttt{0x16}]`:math:`||\,\mathsf{dk}_{par}))` - - :math:`\mathsf{c}_i = I_R`. + - $\mathsf{ak}_i = [I_\mathsf{ask}]\,\mathcal{G}^\mathsf{Sapling} + \mathsf{ak}_{par}$ + - $\mathsf{nk}_i = [I_\mathsf{nsk}]\,\mathcal{H}^\mathsf{Sapling} + \mathsf{nk}_{par}$ + - $\mathsf{ovk}_i = \mathsf{truncate}_{32}(\mathsf{PRF^{expand}}(I_L, [\mathtt{0x15}]$ $||\,\mathsf{ovk}_{par}))$ + - $\mathsf{dk}_i = \mathsf{truncate}_{32}(\mathsf{PRF^{expand}}(I_L, [\mathtt{0x16}]$ $||\,\mathsf{dk}_{par}))$ + - $\mathsf{c}_i = I_R$. -Note that the child extended key is invalid if :math:`\mathsf{ak}_i` is the zero point of Jubjub, -or if the corresponding :math:`\mathsf{ivk}` derived as specified in [#protocol-saplingkeycomponents]_ -is :math:`0`. +Note that the child extended key is invalid if $\mathsf{ak}_i$ is the zero point of Jubjub, +or if the corresponding $\mathsf{ivk}$ derived as specified in [#protocol-saplingkeycomponents]_ +is $0$. Sapling internal key derivation ------------------------------- @@ -283,39 +283,39 @@ key. Deriving a Sapling internal spending key ```````````````````````````````````````` -Let :math:`(\mathsf{ask}, \mathsf{nsk}, \mathsf{ovk}, \mathsf{dk})` be the external spending key. +Let $(\mathsf{ask}, \mathsf{nsk}, \mathsf{ovk}, \mathsf{dk})$ be the external spending key. -- Derive the corresponding :math:`\mathsf{ak}` and :math:`\mathsf{nk}` as specified in [#protocol-saplingkeycomponents]_. -- Let :math:`I = \textsf{BLAKE2b-256}(\texttt{"Zcash_SaplingInt"}, \mathsf{EncodeExtFVKParts}(\mathsf{ak}, \mathsf{nk}, \mathsf{ovk}, \mathsf{dk}))`. -- Let :math:`I_\mathsf{nsk} = \mathsf{ToScalar^{Sapling}}(\mathsf{PRF^{expand}}(I, [\mathtt{0x17}]))`. -- Let :math:`R = \mathsf{PRF^{expand}}(I, [\mathtt{0x18}])`. -- Let :math:`\mathsf{nsk_{internal}} = (I_\mathsf{nsk} + \mathsf{nsk}) \pmod{r_\mathbb{J}}`. -- Split :math:`R` into two 32-byte sequences, :math:`\mathsf{dk_{internal}}` and :math:`\mathsf{ovk_{internal}}`. -- Return the internal spending key as :math:`(\mathsf{ask}, \mathsf{nsk_{internal}}, \mathsf{ovk_{internal}}, \mathsf{dk_{internal}})`. +- Derive the corresponding $\mathsf{ak}$ and $\mathsf{nk}$ as specified in [#protocol-saplingkeycomponents]_. +- Let $I = \textsf{BLAKE2b-256}(\texttt{“Zcash\_SaplingInt”}, \mathsf{EncodeExtFVKParts}(\mathsf{ak}, \mathsf{nk}, \mathsf{ovk}, \mathsf{dk}))$. +- Let $I_\mathsf{nsk} = \mathsf{ToScalar^{Sapling}}(\mathsf{PRF^{expand}}(I, [\mathtt{0x17}]))$. +- Let $R = \mathsf{PRF^{expand}}(I, [\mathtt{0x18}])$. +- Let $\mathsf{nsk_{internal}} = (I_\mathsf{nsk} + \mathsf{nsk}) \pmod{r_\mathbb{J}}$. +- Split $R$ into two 32-byte sequences, $\mathsf{dk_{internal}}$ and $\mathsf{ovk_{internal}}$. +- Return the internal spending key as $(\mathsf{ask}, \mathsf{nsk_{internal}}, \mathsf{ovk_{internal}}, \mathsf{dk_{internal}})$. -Note that the child extended key is invalid if :math:`\mathsf{ak}` is the zero point of Jubjub, -or if the corresponding :math:`\mathsf{ivk}` derived as specified in [#protocol-saplingkeycomponents]_ -is :math:`0`. +Note that the child extended key is invalid if $\mathsf{ak}$ is the zero point of Jubjub, +or if the corresponding $\mathsf{ivk}$ derived as specified in [#protocol-saplingkeycomponents]_ +is $0$. Deriving a Sapling internal full viewing key ```````````````````````````````````````````` -Let :math:`\mathcal{H}^\mathsf{Sapling}` be as defined in [#protocol-saplingkeycomponents]_. +Let $\mathcal{H}^\mathsf{Sapling}$ be as defined in [#protocol-saplingkeycomponents]_. -Let :math:`(\mathsf{ak}, \mathsf{nk}, \mathsf{ovk}, \mathsf{dk})` be the external full viewing key. +Let $(\mathsf{ak}, \mathsf{nk}, \mathsf{ovk}, \mathsf{dk})$ be the external full viewing key. -- Let :math:`I = \textsf{BLAKE2b-256}(\texttt{"Zcash_SaplingInt"}, \mathsf{EncodeExtFVKParts}(\mathsf{ak}, \mathsf{nk}, \mathsf{ovk}, \mathsf{dk}))`. -- Let :math:`I_\mathsf{nsk} = \mathsf{ToScalar^{Sapling}}(\mathsf{PRF^{expand}}(I, [\mathtt{0x17}]))`. -- Let :math:`R = \mathsf{PRF^{expand}}(I, [\mathtt{0x18}])`. -- Let :math:`\mathsf{nk_{internal}} = [I_\mathsf{nsk}] \mathcal{H}^\mathsf{Sapling} + \mathsf{nk}`. -- Split :math:`R` into two 32-byte sequences, :math:`\mathsf{dk_{internal}}` and :math:`\mathsf{ovk_{internal}}`. -- Return the internal full viewing key as :math:`(\mathsf{ak}, \mathsf{nk_{internal}}, \mathsf{ovk_{internal}}, \mathsf{dk_{internal}})`. +- Let $I = \textsf{BLAKE2b-256}(\texttt{“Zcash\_SaplingInt”}, \mathsf{EncodeExtFVKParts}(\mathsf{ak}, \mathsf{nk}, \mathsf{ovk}, \mathsf{dk}))$. +- Let $I_\mathsf{nsk} = \mathsf{ToScalar^{Sapling}}(\mathsf{PRF^{expand}}(I, [\mathtt{0x17}]))$. +- Let $R = \mathsf{PRF^{expand}}(I, [\mathtt{0x18}])$. +- Let $\mathsf{nk_{internal}} = [I_\mathsf{nsk}] \mathcal{H}^\mathsf{Sapling} + \mathsf{nk}$. +- Split $R$ into two 32-byte sequences, $\mathsf{dk_{internal}}$ and $\mathsf{ovk_{internal}}$. +- Return the internal full viewing key as $(\mathsf{ak}, \mathsf{nk_{internal}}, \mathsf{ovk_{internal}}, \mathsf{dk_{internal}})$. This design uses the same technique as non-hardened derivation to obtain a full viewing key -with the same spend authority (the private key corresponding to :math:`\mathsf{ak}`) as the +with the same spend authority (the private key corresponding to $\mathsf{ak}$) as the original, but viewing authority only for internal transfers. -The values of :math:`I`, :math:`I_\mathsf{nsk}`, and :math:`R` are the same between deriving +The values of $I$, $I_\mathsf{nsk}$, and $R$ are the same between deriving a full viewing key, and deriving the corresponding spending key. Both of these derivations are shown in the following diagram: @@ -331,28 +331,28 @@ are shown in the following diagram: This method of deriving internal keys is applied to external keys that are children of the Account level. It was implemented in `zcashd` as part of support for ZIP 316 [#zip-0316]_. -Note that the internal extended key is invalid if :math:`\mathsf{ak}` is the zero point of Jubjub, -or if the corresponding :math:`\mathsf{ivk_{internal}}` derived from the internal full viewing key -as specified in [#protocol-saplingkeycomponents]_ is :math:`0`. +Note that the internal extended key is invalid if $\mathsf{ak}$ is the zero point of Jubjub, +or if the corresponding $\mathsf{ivk_{internal}}$ derived from the internal full viewing key +as specified in [#protocol-saplingkeycomponents]_ is $0$. Sapling diversifier derivation ------------------------------ -The 88-bit diversifiers for a Sapling extended key are derived from its diversifier key :math:`\mathsf{dk}`. +The 88-bit diversifiers for a Sapling extended key are derived from its diversifier key $\mathsf{dk}$. To prevent the diversifier leaking how many diversified addresses have already been generated for an account, we make the sequence of diversifiers pseudorandom and uncorrelated to that of any other account. In order to reach the maximum possible diversifier range without running into repetitions due to the birthday bound, we use FF1-AES256 as a Pseudo-Random Permutation as follows: -- Let :math:`j` be the index of the desired diversifier, in the range :math:`0\,.\!. 2^{88} - 1`. -- :math:`d_j = \mathsf{FF1}\text{-}\mathsf{AES256.Encrypt}(\mathsf{dk}, \texttt{“”}, \mathsf{I2LEBSP}_{88}(j))`. +- Let $j$ be the index of the desired diversifier, in the range $0\,..\, 2^{88} - 1$. +- $d_j = \mathsf{FF1}\text{-}\mathsf{AES256.Encrypt}(\mathsf{dk}, \texttt{“”}, \mathsf{I2LEBSP}_{88}(j))$. -A valid diversifier :math:`d_j` is one for which :math:`\mathsf{DiversifyHash^{Sapling}}(d_j) \neq \bot`. -For a given :math:`\mathsf{dk}`, approximately half of the possible values of :math:`j` yield valid +A valid diversifier $d_j$ is one for which $\mathsf{DiversifyHash^{Sapling}}(d_j) \neq \bot$. +For a given $\mathsf{dk}$, approximately half of the possible values of $j$ yield valid diversifiers. -The default diversifier for a Sapling extended key is defined to be :math:`d_j`, where :math:`j` is the +The default diversifier for a Sapling extended key is defined to be $d_j$, where $j$ is the least nonnegative integer yielding a valid diversifier. @@ -368,47 +368,47 @@ path across multiple contexts). Instantiation ------------- -Let :math:`\mathsf{Context}` be the context in which the hardened-only key derivation process is +Let $\mathsf{Context}$ be the context in which the hardened-only key derivation process is instantiated (e.g. a shielded protocol). We define two context-specific constants: -- :math:`\mathsf{Context.MKGDomain}` is a sequence of 16 bytes, used as a domain separator during +- $\mathsf{Context.MKGDomain}$ is a sequence of 16 bytes, used as a domain separator during master key generation. It SHOULD be disjoint from other domain separators used with BLAKE2b in Zcash protocols. -- :math:`\mathsf{Context.CKDDomain}` is a byte value, used as a domain separator during child key +- $\mathsf{Context.CKDDomain}$ is a byte value, used as a domain separator during child key derivation. This should be tracked as part of the global set of domains defined for - :math:`\mathsf{PRF^{expand}}`. + $\mathsf{PRF^{expand}}$. Hardened-only master key generation ----------------------------------- -Let :math:`\mathsf{IKM}` be an input key material byte sequence, which MUST use an unambiguous encoding +Let $\mathsf{IKM}$ be an input key material byte sequence, which MUST use an unambiguous encoding within the given context, and SHOULD contain at least 256 bits of entropy. It is RECOMMENDED to use a prefix-free encoding, which may require the use of length fields if multiple fields need to be encoded. -:math:`\mathsf{MKGh}^\mathsf{Context}(\mathsf{IKM}) \rightarrow (\mathsf{sk}_m, \mathsf{c}_m)` +$\mathsf{MKGh}^\mathsf{Context}(\mathsf{IKM}) \rightarrow (\mathsf{sk}_m, \mathsf{c}_m)$ : -- Calculate :math:`I = \mathsf{BLAKE2b}\text{-}\mathsf{512}(\mathsf{Context.MKGDomain}, \mathsf{IKM})`. -- Split :math:`I` into two 32-byte sequences, :math:`I_L` and :math:`I_R`. -- Use :math:`I_L` as the master secret key :math:`\mathsf{sk}_m`. -- Use :math:`I_R` as the master chain code :math:`\mathsf{c}_m`. -- Return :math:`(\mathsf{sk}_m, \mathsf{c}_m)`. +- Calculate $I = \mathsf{BLAKE2b}\text{-}\mathsf{512}(\mathsf{Context.MKGDomain}, \mathsf{IKM})$. +- Split $I$ into two 32-byte sequences, $I_L$ and $I_R$. +- Use $I_L$ as the master secret key $\mathsf{sk}_m$. +- Use $I_R$ as the master chain code $\mathsf{c}_m$. +- Return $(\mathsf{sk}_m, \mathsf{c}_m)$. Hardened-only child key derivation ---------------------------------- -:math:`\mathsf{CKDh}^\mathsf{Context}((\mathsf{sk}_{par}, \mathsf{c}_{par}), i)`:math:`\rightarrow (\mathsf{sk}_i, \mathsf{c}_i)` +$\mathsf{CKDh}^\mathsf{Context}((\mathsf{sk}_{par}, \mathsf{c}_{par}), i)$ $\rightarrow (\mathsf{sk}_i, \mathsf{c}_i)$ : -- Check whether :math:`i \geq 2^{31}` (whether the child is a hardened key). +- Check whether $i \geq 2^{31}$ (whether the child is a hardened key). - If so (hardened child): let - :math:`I = \mathsf{PRF^{expand}}(\mathsf{c}_{par}, [\mathsf{Context.CKDDomain}]\,||\,\mathsf{sk}_{par}\,||\,\mathsf{I2LEOSP}_{32}(i))`. + $I = \mathsf{PRF^{expand}}(\mathsf{c}_{par}, [\mathsf{Context.CKDDomain}]\,||\,\mathsf{sk}_{par}\,||\,\mathsf{I2LEOSP}_{32}(i))$. - If not (normal child): return failure. -- Split :math:`I` into two 32-byte sequences, :math:`I_L` and :math:`I_R`. -- Use :math:`I_L` as the child secret key :math:`\mathsf{sk}_i`. -- Use :math:`I_R` as the child chain code :math:`\mathsf{c}_i`. -- Return :math:`(\mathsf{sk}_i, \mathsf{c}_i)`. +- Split $I$ into two 32-byte sequences, $I_L$ and $I_R$. +- Use $I_L$ as the child secret key $\mathsf{sk}_i$. +- Use $I_R$ as the child chain code $\mathsf{c}_i$. +- Return $(\mathsf{sk}_i, \mathsf{c}_i)$. Specification: Orchard key derivation @@ -417,29 +417,29 @@ Specification: Orchard key derivation We only support hardened key derivation for Orchard. We instantiate the hardened key generation process with the following constants: -- :math:`\mathsf{Orchard.MKGDomain} = \texttt{“ZcashIP32Orchard”}` -- :math:`\mathsf{Orchard.CKDDomain} = \texttt{0x81}` +- $\mathsf{Orchard.MKGDomain} = \texttt{“ZcashIP32Orchard”}$ +- $\mathsf{Orchard.CKDDomain} = \mathtt{0x81}$ Orchard extended keys --------------------- -We represent an Orchard extended spending key as :math:`(\mathsf{sk, c}),` where :math:`\mathsf{sk}` -is the normal Orchard spending key (opaque 32 bytes), and :math:`\mathsf{c}` is the chain code. +We represent an Orchard extended spending key as $(\mathsf{sk, c}),$ where $\mathsf{sk}$ +is the normal Orchard spending key (opaque 32 bytes), and $\mathsf{c}$ is the chain code. Orchard master key generation ----------------------------- -Let :math:`S` be a seed byte sequence of a chosen length, which MUST be at least 32 and at most 252 bytes. +Let $S$ be a seed byte sequence of a chosen length, which MUST be at least 32 and at most 252 bytes. -- Return :math:`\mathsf{MKGh}^\mathsf{Orchard}(S)` as the master extended spending key - :math:`m_\mathsf{Orchard}`. +- Return $\mathsf{MKGh}^\mathsf{Orchard}(S)$ as the master extended spending key + $m_\mathsf{Orchard}$. Orchard child key derivation ---------------------------- -:math:`\mathsf{CKDsk}((\mathsf{sk}_{par}, \mathsf{c}_{par}), i)`:math:`\rightarrow (\mathsf{sk}_{i}, \mathsf{c}_i)` +$\mathsf{CKDsk}((\mathsf{sk}_{par}, \mathsf{c}_{par}), i)$ $\rightarrow (\mathsf{sk}_{i}, \mathsf{c}_i)$ : -- Return :math:`\mathsf{CKDh}^\mathsf{Orchard}((\mathsf{sk}_{par}, \mathsf{c}_{par}), i)` +- Return $\mathsf{CKDh}^\mathsf{Orchard}((\mathsf{sk}_{par}, \mathsf{c}_{par}), i)$ Note that the resulting child spending key may produce an invalid external FVK, as specified in [#protocol-orchardkeycomponents]_, with small probability. The corresponding internal FVK @@ -454,26 +454,26 @@ any external full viewing key we need to be able to derive a single internal ful key that has viewing authority for just internal transfers. We also need to be able to derive the corresponding internal spending key if we have the external spending key. -Let :math:`\mathsf{ask}` be the spend authorizing key if available, and -let :math:`(\mathsf{ak}, \mathsf{nk}, \mathsf{rivk})` be the corresponding external full +Let $\mathsf{ask}$ be the spend authorizing key if available, and +let $(\mathsf{ak}, \mathsf{nk}, \mathsf{rivk})$ be the corresponding external full viewing key, obtained as specified in [#protocol-orchardkeycomponents]_. -Define :math:`\mathsf{DeriveInternalFVK^{Orchard}}(\mathsf{ak}, \mathsf{nk}, \mathsf{rivk})` +Define $\mathsf{DeriveInternalFVK^{Orchard}}(\mathsf{ak}, \mathsf{nk}, \mathsf{rivk})$ as follows: -- Let :math:`K = \mathsf{I2LEBSP}_{256}(\mathsf{rivk})`. -- Let :math:`\mathsf{rivk_{internal}} = \mathsf{ToScalar^{Orchard}}(\mathsf{PRF^{expand}}(K, [\mathtt{0x83}] \,||\, \mathsf{I2LEOSP_{256}}(\mathsf{ak}) \,||\, \mathsf{I2LEOSP_{256}}(\mathsf{nk}))`. -- Return :math:`(\mathsf{ak}, \mathsf{nk}, \mathsf{rivk_{internal}})`. +- Let $K = \mathsf{I2LEBSP}_{256}(\mathsf{rivk})$. +- Let $\mathsf{rivk_{internal}} = \mathsf{ToScalar^{Orchard}}(\mathsf{PRF^{expand}}(K, [\mathtt{0x83}] \,||\, \mathsf{I2LEOSP_{256}}(\mathsf{ak}) \,||\, \mathsf{I2LEOSP_{256}}(\mathsf{nk}))$. +- Return $(\mathsf{ak}, \mathsf{nk}, \mathsf{rivk_{internal}})$. -The result of applying :math:`\mathsf{DeriveInternalFVK^{Orchard}}` to the external full viewing +The result of applying $\mathsf{DeriveInternalFVK^{Orchard}}$ to the external full viewing key is the internal full viewing key. The corresponding expanded internal spending key is -:math:`(\mathsf{ask}, \mathsf{nk}, \mathsf{rivk_{internal}})`, +$(\mathsf{ask}, \mathsf{nk}, \mathsf{rivk_{internal}})$. Unlike `Sapling internal key derivation`_, we do not base this internal key derivation procedure on non-hardened derivation, which is not defined for Orchard. We can obtain the -desired separation of viewing authority by modifying only the :math:`\mathsf{rivk_{internal}}` +desired separation of viewing authority by modifying only the $\mathsf{rivk_{internal}}$ field relative to the external full viewing key, which results in different -:math:`\mathsf{dk_{internal}}`, :math:`\mathsf{ivk_{internal}}` and :math:`\mathsf{ovk_{internal}}` +$\mathsf{dk_{internal}}$, $\mathsf{ivk_{internal}}$ and $\mathsf{ovk_{internal}}$ fields being derived, as specified in [#protocol-orchardkeycomponents]_ and shown in the following diagram: @@ -499,18 +499,18 @@ key. This means that the full viewing key provides the capability to determine t within the sequence, which matches the capabilities of a Sapling extended full viewing key but simplifies the key structure. -Given an Orchard extended spending key :math:`(\mathsf{sk}_i, \mathsf{c}_i)`: +Given an Orchard extended spending key $(\mathsf{sk}_i, \mathsf{c}_i)$: -- Let :math:`(\mathsf{ak}, \mathsf{nk}, \mathsf{rivk})` be the Orchard full viewing key for :math:`\mathsf{sk}_i`. -- Let :math:`K = \mathsf{I2LEBSP}_{256}(\mathsf{rivk})`. -- :math:`\mathsf{dk}_i = \mathsf{truncate}_{32}(\mathsf{PRF^{expand}}(K, [\texttt{0x82}] \,||\, \mathsf{I2LEOSP}_{256}(\mathsf{ak}) \,||\, \mathsf{I2LEOSP}_{256}(\mathsf{nk})))`. -- Let :math:`j` be the index of the desired diversifier, in the range :math:`0\,.\!. 2^{88} - 1`. -- :math:`d_{i,j} = \mathsf{FF1}\text{-}\mathsf{AES256.Encrypt}(\mathsf{dk}_i, \texttt{“”}, \mathsf{I2LEBSP}_{88}(j))`. +- Let $(\mathsf{ak}, \mathsf{nk}, \mathsf{rivk})$ be the Orchard full viewing key for $\mathsf{sk}_i$. +- Let $K = \mathsf{I2LEBSP}_{256}(\mathsf{rivk})$. +- $\mathsf{dk}_i = \mathsf{truncate}_{32}(\mathsf{PRF^{expand}}(K, [\mathtt{0x82}] \,||\, \mathsf{I2LEOSP}_{256}(\mathsf{ak}) \,||\, \mathsf{I2LEOSP}_{256}(\mathsf{nk})))$. +- Let $j$ be the index of the desired diversifier, in the range $0\,..\, 2^{88} - 1$. +- $d_{i,j} = \mathsf{FF1}\text{-}\mathsf{AES256.Encrypt}(\mathsf{dk}_i, \texttt{“”}, \mathsf{I2LEBSP}_{88}(j))$. -Note that unlike Sapling, all Orchard diversifiers are valid, and thus all possible values of :math:`j` yield +Note that unlike Sapling, all Orchard diversifiers are valid, and thus all possible values of $j$ yield valid diversifiers. -The default diversifier for :math:`(\mathsf{sk}_i, \mathsf{c}_i)` is defined to be :math:`d_{i,0}.` +The default diversifier for $(\mathsf{sk}_i, \mathsf{c}_i)$ is defined to be $d_{i,0}.$ Specification: Arbitrary key derivation @@ -521,35 +521,35 @@ existing key material (for example, deriving an arbitrary account-level key), wi ecosystem-wide coordination. The following instantiation of the hardened key generation process may be used for this purpose. -Let :math:`\mathsf{ContextString}` be a globally-unique non-empty sequence of at most 252 bytes +Let $\mathsf{ContextString}$ be a globally-unique non-empty sequence of at most 252 bytes that identifies the desired context. We instantiate the hardened key generation process with the following constants: -- :math:`\mathsf{Arbitrary.MKGDomain} = \texttt{“ZcashArbitraryKD”}` -- :math:`\mathsf{Arbitrary.CKDDomain} = \texttt{0xAB}` +- $\mathsf{Arbitrary.MKGDomain} = \texttt{“ZcashArbitraryKD”}$ +- $\mathsf{Arbitrary.CKDDomain} = \mathtt{0xAB}$ Arbitrary master key generation ------------------------------- -Let :math:`S` be a seed byte sequence of a chosen length, which MUST be at least 32 and at most 252 bytes. +Let $S$ be a seed byte sequence of a chosen length, which MUST be at least 32 and at most 252 bytes. The master extended arbitrary key is: -:math:`m_\mathsf{Arbitrary} = \mathsf{MKGh}^\mathsf{Arbitrary}([\mathsf{length}(\mathsf{ContextString})]\,||\,\mathsf{ContextString}\,||\,[\mathsf{length}(S)]\,||\,S)\!`. +$m_\mathsf{Arbitrary} = \mathsf{MKGh}^\mathsf{Arbitrary}([\mathsf{length}(\mathsf{ContextString})]\,||\,\mathsf{ContextString}\,||\,[\mathsf{length}(S)]\,||\,S)$. Arbitrary child key derivation ------------------------------ -:math:`\mathsf{CKDarb}((\mathsf{sk}_{par}, \mathsf{c}_{par}), i)`:math:`\rightarrow (\mathsf{sk}_i, \mathsf{c}_i)` +$\mathsf{CKDarb}((\mathsf{sk}_{par}, \mathsf{c}_{par}), i)$ $\rightarrow (\mathsf{sk}_i, \mathsf{c}_i)$ : -- Return :math:`\mathsf{CKDh}^\mathsf{Arbitrary}((\mathsf{sk}_{par}, \mathsf{c}_{par}), i)\!`. +- Return $\mathsf{CKDh}^\mathsf{Arbitrary}((\mathsf{sk}_{par}, \mathsf{c}_{par}), i)$. If the context requires a 64-byte key (for example, to avoid an entropy bottleneck in its particular -subsequent operations), and :math:`i` is the last element of an HD path, the concatenation -:math:`\mathsf{sk}_i\,||\,\mathsf{c}_i` MAY be used as a key. In this case, -:math:`(\mathsf{sk}_i, \mathsf{c}_i)` MUST NOT be given as input to :math:`\mathsf{CKDarb}` (this -is a restatement of the requirement that :math:`i` is the last element of an HD path). +subsequent operations), and $i$ is the last element of an HD path, the concatenation +$\mathsf{sk}_i\,||\,\mathsf{c}_i$ MAY be used as a key. In this case, +$(\mathsf{sk}_i, \mathsf{c}_i)$ MUST NOT be given as input to $\mathsf{CKDarb}$ (this +is a restatement of the requirement that $i$ is the last element of an HD path). Specification: Wallet usage @@ -565,18 +565,18 @@ Key path levels Sapling and Orchard key paths have the following three path levels at the top, all of which use hardened derivation: -- :math:`purpose`: a constant set to :math:`32'` (or :math:`\texttt{0x80000020}`) following the BIP 43 +- $purpose$: a constant set to $32'$ (or $\mathtt{0x80000020}$) following the BIP 43 recommendation. It indicates that the subtree of this node is used according to this specification. -- :math:`coin\_type`: a constant identifying the cryptocurrency that this subtree's keys are used with. For +- $coin\_type$: a constant identifying the cryptocurrency that this subtree's keys are used with. For compatibility with existing BIP 44 implementations, we use the same constants as defined in SLIP 44 - [#slip-0044]_. Note that in keeping with that document, all cryptocurrency testnets share :math:`coin\_type` - index :math:`1`. + [#slip-0044]_. Note that in keeping with that document, all cryptocurrency testnets share $coin\_type$ + index $1$. -- :math:`account`: numbered from index :math:`0` in sequentially increasing manner. Defined as in +- $account$: numbered from index $0$ in sequentially increasing manner. Defined as in BIP 44 [#bip-0044]_. -Unlike BIP 44, none of the shielded key paths have a :math:`change` path level. The use of change addresses +Unlike BIP 44, none of the shielded key paths have a $change$ path level. The use of change addresses in Bitcoin is a (failed) attempt to increase the difficulty of tracking users on the transaction graph, by segregating external and internal address usage. Shielded addresses are never publicly visible in transactions, which means that sending change back to the originating address is indistinguishable from @@ -592,25 +592,25 @@ relevant transactions. The above key path levels include an account identifier, which in all user interfaces is represented as a "bucket of funds" under the control of a single spending authority. Therefore, wallets implementing Sapling -ZIP 32 derivation MUST support the following path for any account in range :math:`\{ 0\,.\!. 2^{31} - 1 \}`: +ZIP 32 derivation MUST support the following path for any account in range $\{ 0\,..\, 2^{31} - 1 \}$: -* :math:`m_\mathsf{Sapling} / purpose' / coin\_type' / account'`. +* $m_\mathsf{Sapling} / purpose' / coin\_type' / account'$. Furthermore, wallets MUST support generating the default payment address (corresponding to the default diversifier as defined above) for any account they support. They MAY also support generating a stream of payment addresses for a given account, if they wish to maintain the user experience of giving a unique address to each recipient. -Note that a given account can have a maximum of approximately :math:`2^{87}` payment addresses, because each +Note that a given account can have a maximum of approximately $2^{87}$ payment addresses, because each diversifier has around a 50% chance of being invalid. If in certain circumstances a wallet needs to derive independent spend authorities within a single account, -they MAY additionally support a non-hardened :math:`address\_index` path level as in [#bip-0044]_: +they MAY additionally support a non-hardened $address\_index$ path level as in [#bip-0044]_: -* :math:`m_\mathsf{Sapling} / purpose' / coin\_type' / account' / address\_index`. +* $m_\mathsf{Sapling} / purpose' / coin\_type' / account' / address\_index$. `zcashd` version 4.6.0 and later uses this to derive "legacy" Sapling addresses from a mnemonic seed phrase -under account :math:`\mathtt{0x7FFFFFFF}`, using hardened derivation for :math:`address\_index`. +under account $\mathtt{0x7FFFFFFF}$, using hardened derivation for $address\_index$. Orchard key path ---------------- @@ -621,16 +621,16 @@ addresses as needed does not increase the cost of scanning the block chain for r The above key path levels include an account identifier, which in all user interfaces is represented as a "bucket of funds" under the control of a single spending authority. Therefore, wallets implementing Orchard -ZIP 32 derivation MUST support the following path for any account in range :math:`\{ 0\,.\!. 2^{31} - 1 \}`: +ZIP 32 derivation MUST support the following path for any account in range $\{ 0\,..\, 2^{31} - 1 \}$: -* :math:`m_\mathsf{Orchard} / purpose' / coin\_type' / account'`. +* $m_\mathsf{Orchard} / purpose' / coin\_type' / account'$. Furthermore, wallets MUST support generating the default payment address (corresponding to the default diversifier for Orchard) for any account they support. They MAY also support generating a stream of diversified payment addresses for a given account, if they wish to enable users to give a unique address to each recipient. -Note that a given account can have a maximum of :math:`2^{88}` payment addresses (unlike Sapling, all Orchard +Note that a given account can have a maximum of $2^{88}$ payment addresses (unlike Sapling, all Orchard diversifiers are valid). @@ -640,10 +640,10 @@ Specification: Fingerprints and Tags Sapling Full Viewing Key Fingerprints and Tags ---------------------------------------------- -A "Sapling full viewing key fingerprint" of a full viewing key with raw encoding :math:`\mathit{FVK}` (as specified +A "Sapling full viewing key fingerprint" of a full viewing key with raw encoding $\mathit{FVK}$ (as specified in [#protocol-saplingfullviewingkeyencoding]_) is given by: -* :math:`\mathsf{BLAKE2b}\text{-}\mathsf{256}(\texttt{“ZcashSaplingFVFP”}, \mathit{FVK})`. +* $\mathsf{BLAKE2b}\text{-}\mathsf{256}(\texttt{“ZcashSaplingFVFP”}, \mathit{FVK})$. It MAY be used to uniquely identify a particular Sapling full viewing key. @@ -654,10 +654,10 @@ uniquely identify a particular key. Orchard Full Viewing Key Fingerprints and Tags ---------------------------------------------- -An "Orchard full viewing key fingerprint" of a full viewing key with raw encoding :math:`\mathit{FVK}` (as +An "Orchard full viewing key fingerprint" of a full viewing key with raw encoding $\mathit{FVK}$ (as specified in [#protocol-orchardfullviewingkeyencoding]_) is given by: -* :math:`\mathsf{BLAKE2b}\text{-}\mathsf{256}(\texttt{“ZcashOrchardFVFP”}, \mathit{FVK})`. +* $\mathsf{BLAKE2b}\text{-}\mathsf{256}(\texttt{“ZcashOrchardFVFP”}, \mathit{FVK})$. It MAY be used to uniquely identify a particular Orchard full viewing key. @@ -668,9 +668,9 @@ uniquely identify a particular key. Seed Fingerprints ----------------- -A "seed fingerprint" for the master seed :math:`S` of a hierarchical deterministic wallet is given by: +A "seed fingerprint" for the master seed $S$ of a hierarchical deterministic wallet is given by: -* :math:`\mathsf{BLAKE2b}\text{-}\mathsf{256}(\texttt{“Zcash_HD_Seed_FP”},`:math:`[\mathsf{length}(S)]\,||\,S)`. +* $\mathsf{BLAKE2b}\text{-}\mathsf{256}(\texttt{“Zcash\_HD\_Seed\_FP”},$ $[\mathsf{length}(S)]\,||\,S)$. It MAY be used to uniquely identify a particular hierarchical deterministic wallet. @@ -691,14 +691,14 @@ and a Bech32 [#bip-0173]_ encoding. Sapling extended spending keys ------------------------------ -A Sapling extended spending key :math:`(\mathsf{ask, nsk, ovk, dk, c})`, at depth :math:`depth`, -with parent full viewing key tag :math:`parent\_fvk\_tag` and child number :math:`i`, is +A Sapling extended spending key $(\mathsf{ask, nsk, ovk, dk, c})$, at depth $depth$, +with parent full viewing key tag $parent\_fvk\_tag$ and child number $i$, is represented as a byte sequence: -* :math:`\mathsf{I2LEOSP}_{8}(depth)`:math:`||\,parent\_fvk\_tag`:math:`||\,\mathsf{I2LEOSP}_{32}(i)`:math:`||\,\mathsf{c}`:math:`||\,\mathsf{EncodeExtSKParts}(\mathsf{ask, nsk, ovk, dk})`. +* $\mathsf{I2LEOSP}_{8}(depth)$ $||\,parent\_fvk\_tag$ $||\,\mathsf{I2LEOSP}_{32}(i)$ $||\,\mathsf{c}$ $||\,\mathsf{EncodeExtSKParts}(\mathsf{ask, nsk, ovk, dk})$. -For the master extended spending key, :math:`depth` is :math:`0`, :math:`parent\_fvk\_tag` is -4 zero bytes, and :math:`i` is :math:`0`. +For the master extended spending key, $depth$ is $0$, $parent\_fvk\_tag$ is +4 zero bytes, and $i$ is $0$. When encoded as Bech32, the Human-Readable Part is ``secret-extended-key-main`` for the production network, or ``secret-extended-key-test`` for the test network. @@ -706,14 +706,14 @@ for the production network, or ``secret-extended-key-test`` for the test network Sapling extended full viewing keys ---------------------------------- -A Sapling extended full viewing key :math:`(\mathsf{ak, nk, ovk, dk, c})`, at depth :math:`depth`, -with parent full viewing key tag :math:`parent\_fvk\_tag` and child number :math:`i`, is +A Sapling extended full viewing key $(\mathsf{ak, nk, ovk, dk, c})$, at depth $depth$, +with parent full viewing key tag $parent\_fvk\_tag$ and child number $i$, is represented as a byte sequence: -* :math:`\mathsf{I2LEOSP}_{8}(depth)`:math:`||\,parent\_fvk\_tag`:math:`||\,\mathsf{I2LEOSP}_{32}(i)`:math:`||\,\mathsf{c}`:math:`||\,\mathsf{EncodeExtFVKParts}(\mathsf{ak, nk, ovk, dk})`. +* $\mathsf{I2LEOSP}_{8}(depth)$ $||\,parent\_fvk\_tag$ $||\,\mathsf{I2LEOSP}_{32}(i)$ $||\,\mathsf{c}$ $||\,\mathsf{EncodeExtFVKParts}(\mathsf{ak, nk, ovk, dk})$. -For the master extended full viewing key, :math:`depth` is :math:`0`, :math:`parent\_fvk\_tag` -is 4 zero bytes, and :math:`i` is :math:`0`. +For the master extended full viewing key, $depth$ is $0$, $parent\_fvk\_tag$ +is 4 zero bytes, and $i$ is $0$. When encoded as Bech32, the Human-Readable Part is ``zxviews`` for the production network, or ``zxviewtestsapling`` for the test network. @@ -721,13 +721,13 @@ network, or ``zxviewtestsapling`` for the test network. Orchard extended spending keys ------------------------------ -An Orchard extended spending key :math:`(\mathsf{sk, c})`, at depth :math:`depth`, with parent full viewing -key tag :math:`parent\_fvk\_tag` and child number :math:`i`, is represented as a byte sequence: +An Orchard extended spending key $(\mathsf{sk, c})$, at depth $depth$, with parent full viewing +key tag $parent\_fvk\_tag$ and child number $i$, is represented as a byte sequence: -* :math:`\mathsf{I2LEOSP}_{8}(depth)\,||\,parent\_fvk\_tag\,||\,\mathsf{I2LEOSP}_{32}(i)\,||\,\mathsf{c}\,||\,\mathsf{sk}`. +* $\mathsf{I2LEOSP}_{8}(depth)\,||\,parent\_fvk\_tag\,||\,\mathsf{I2LEOSP}_{32}(i)\,||\,\mathsf{c}\,||\,\mathsf{sk}$. -For the master extended spending key, :math:`depth` is :math:`0`, :math:`parent\_fvk\_tag` is -4 zero bytes, and :math:`i` is :math:`0`. +For the master extended spending key, $depth$ is $0$, $parent\_fvk\_tag$ is +4 zero bytes, and $i$ is $0$. When encoded as Bech32, the Human-Readable Part is ``secret-orchard-extsk-main`` for Mainnet, or ``secret-orchard-extsk-test`` for Testnet. @@ -743,11 +743,11 @@ Values reserved due to previous specification for Sprout The following values were previously used in the specification of hierarchical derivation for Sprout, and therefore SHOULD NOT be used in future Zcash-related specifications: -* the :math:`\mathsf{BLAKE2b}\text{-}\mathsf{512}` personalization :math:`\texttt{“ZcashIP32_Sprout”}`, +* the $\mathsf{BLAKE2b}\text{-}\mathsf{512}$ personalization $\texttt{“ZcashIP32\_Sprout”}$, formerly specified for derivation of the master key of the Sprout tree; -* the :math:`\mathsf{BLAKE2b}\text{-}\mathsf{256}` personalization :math:`\texttt{“Zcash_Sprout_AFP”}`, +* the $\mathsf{BLAKE2b}\text{-}\mathsf{256}$ personalization $\texttt{“Zcash\_Sprout\_AFP”}$, formerly specified for generation of Sprout address fingerprints; -* the :math:`\mathsf{PRF^{expand}}` prefix :math:`\texttt{0x80}`, formerly specified for +* the $\mathsf{PRF^{expand}}$ prefix $\mathtt{0x80}$, formerly specified for Sprout child key derivation; * the Bech32 Human-Readable Parts ``zxsprout`` and ``zxtestsprout``, formerly specified for Sprout extended spending keys on Mainnet and Testnet respectively. diff --git a/zips/zip-0203.rst b/zips/zip-0203.rst index 3d2dbd036..a49f0b349 100644 --- a/zips/zip-0203.rst +++ b/zips/zip-0203.rst @@ -31,12 +31,12 @@ be mined, and potentially simplifying bidirectional payment channels by reducing to store and compress revocations for past states, since transactions not committed to the chain could expire and become invalid after a period of time. -If the expiry is at block height :math:`N`, then the transaction must be included in block -:math:`N` or earlier. Block :math:`N+1` will be too late, and the transaction will be +If the expiry is at block height $N\!$, then the transaction must be included in block +$N$ or earlier. Block $N+1$ will be too late, and the transaction will be removed from the mempool. The new consensus rule will enforce that the transaction will not be considered valid if -included in block of height greater than :math:`N`, and blocks that include expired +included in block of height greater than $N\!$, and blocks that include expired transactions will not be considered valid. diff --git a/zips/zip-0207.rst b/zips/zip-0207.rst index 9d566b0e3..291da0a09 100644 --- a/zips/zip-0207.rst +++ b/zips/zip-0207.rst @@ -59,7 +59,7 @@ requirements for the Zcash Development Fund, the ZIP was reintroduced for that purpose in the Canopy upgrade in order to reuse specification, analysis, and implementation effort. -As of NU6, ZIP 1015 [#zip-1015]_ directs part of the block reward to a reserve, +As of NU6, ZIP 1015 [#zip-1015]_ directs part of the block subsidy to a reserve, the distribution of which is to be determined via a future ZIP. ZIP 2001 [#zip-2001]_ modified this ZIP to augment the funding stream mechanism with a common mechanism to implement this proposal. @@ -89,16 +89,16 @@ Definitions We use the following constants and functions defined in [#protocol-constants]_, [#protocol-diffadjustment]_, [#protocol-subsidies]_, and [#protocol-foundersreward]_: -- :math:`\mathsf{BlossomActivationHeight}` -- :math:`\mathsf{PostBlossomHalvingInterval}` -- :math:`\mathsf{Halving}(\mathsf{height})` -- :math:`\mathsf{BlockSubsidy}(\mathsf{height})` -- :math:`\mathsf{RedeemScriptHash}(\mathsf{height})`. +- $\mathsf{BlossomActivationHeight}$ +- $\mathsf{PostBlossomHalvingInterval}$ +- $\mathsf{Halving}(\mathsf{height})$ +- $\mathsf{BlockSubsidy}(\mathsf{height})$ +- $\mathsf{RedeemScriptHash}(\mathsf{height})$. We also define the following function: -- :math:`\mathsf{HeightForHalving}(\mathsf{halving})`: Smallest :math:`\mathsf{height}` such that - :math:`\mathsf{Halving}(\mathsf{height}) = \mathsf{halving}` +- $\mathsf{HeightForHalving}(\mathsf{halving})$: Smallest $\mathsf{height}$ such that + $\mathsf{Halving}(\mathsf{height}) = \mathsf{halving}$ Funding streams @@ -129,10 +129,10 @@ than its start height. The funding streams are paid to one of a pre-defined set of recipients, depending on the block height. Each recipient identifier MUST be either the string encoding of a transparent P2SH address or Sapling address (as specified in -[#protocol-transparentaddrencoding]_ or [#protocol-saplingpaymentaddrencoding]) +[#protocol-transparentaddrencoding]_ or [#protocol-saplingpaymentaddrencoding]_) to be paid by an output in the coinbase transaction, or the identifier -:math:`\mathsf{DEFERRED}\_\mathsf{POOL}`. The latter, added in the NU6 network -upgrade [#zip-0253]_, indicates that the value is to be paid to a reserve to be +$\mathsf{DEFERRED\_POOL}$. The latter, added in the NU6 network upgrade +[#zip-0253]_, indicates that the value is to be paid to a reserve to be used for development funding, the distribution of which is to be determined via a future ZIP. @@ -142,7 +142,7 @@ given block height is defined as follows: .. math:: - \begin{eqnarray*} + \begin{array}{rcl} \mathsf{AddressChangeInterval} &=& \mathsf{PostBlossomHalvingInterval} / 48 \\ \mathsf{AddressPeriod}(\mathsf{height}) &=& \mathsf{floor}\left( @@ -151,7 +151,7 @@ given block height is defined as follows: \mathsf{FundingStream[FUND].AddressIndex}(\mathsf{height}) &=& \mathsf{AddressPeriod}(\mathsf{height}) - \\&&\hspace{2em} \mathsf{AddressPeriod}(\mathsf{FundingStream[FUND].StartHeight}) \\ \mathsf{FundingStream[FUND].Address}(\mathsf{height}) &=& \mathsf{FundingStream[FUND].Addresses[} \\&&\hspace{2em} \mathsf{FundingStream[FUND].AddressIndex}(\mathsf{height})\mathsf{]} - \end{eqnarray*} + \end{array} This has the property that all active funding streams change the address they are using on the same block height schedule, aligned to the height of the @@ -190,24 +190,24 @@ Deferred Development Fund Chain Value Pool Balance -------------------------------------------------- Full node implementations MUST track an additional -:math:`\mathsf{ChainValuePoolBalance^{Deferred}}` chain value pool balance, +$\mathsf{ChainValuePoolBalance^{Deferred}}$ chain value pool balance, in addition to the Sprout, Sapling, and Orchard chain value pool balances. -Define :math:`\mathsf{totalDeferredOutput}(\mathsf{height}) := \sum_{\mathsf{fs} \in \mathsf{DeferredFundingStreams}(\mathsf{height})} \mathsf{fs.Value}(\mathsf{height})` -where :math:`\mathsf{DeferredFundingStreams}(\mathsf{height})` is the set of -funding streams with recipient identifier :math:`\mathsf{DEFERRED}\_\mathsf{POOL}` -in the block at height :math:`\mathsf{height}`. +Define $\mathsf{totalDeferredOutput}(\mathsf{height}) := \sum_{\mathsf{fs} \in \mathsf{DeferredFundingStreams}(\mathsf{height})} \mathsf{fs.Value}(\mathsf{height})$ +where $\mathsf{DeferredFundingStreams}(\mathsf{height})$ is the set of +funding streams with recipient identifier $\mathsf{DEFERRED\_POOL}$ +in the block at height $\mathsf{height}$. -The :math:`\mathsf{ChainValuePoolBalance^{Deferred}}` chain value pool balance +The $\mathsf{ChainValuePoolBalance^{Deferred}}$ chain value pool balance for a given block chain is the sum of the values of payments to -:math:`\mathsf{DEFERRED}\_\mathsf{POOL}` for transactions in the block chain. +$\mathsf{DEFERRED\_POOL}$ for transactions in the block chain. -Equivalently, :math:`\mathsf{ChainValuePoolBalance^{Deferred}}` for a block -chain up to and including height :math:`\mathsf{height}` is given by -:math:`\sum_{\mathsf{h} = 0}^{\mathsf{height}} \mathsf{totalDeferredOutput}(\mathsf{h})`. +Equivalently, $\mathsf{ChainValuePoolBalance^{Deferred}}$ for a block +chain up to and including height $\mathsf{height}$ is given by +$\sum_{\mathsf{h} = 0}^{\mathsf{height}} \mathsf{totalDeferredOutput}(\mathsf{h})$. -Note: :math:`\mathsf{totalDeferredOutput}(\mathsf{h})` is necessarily -zero for heights :math:`\mathsf{h}` prior to NU6 activation. +Note: $\mathsf{totalDeferredOutput}(\mathsf{h})$ is necessarily +zero for heights $\mathsf{h}$ prior to NU6 activation. Consensus rules @@ -223,17 +223,17 @@ Once the Canopy network upgrade activates: (This would be the case under the preexisting consensus rules for Mainnet, but not for Testnet.) -- In each block with coinbase transaction :math:`\mathsf{cb}` at block height - :math:`\mathsf{height}`, for each funding stream :math:`\mathsf{fs}` +- In each block with coinbase transaction $\mathsf{cb}$ at block height + $\mathsf{height}$, for each funding stream $\mathsf{fs}$ active at that block height with a recipient identifier other than - :math:`\mathsf{DEFERRED}\_\mathsf{POOL}` given by - :math:`\mathsf{fs.Recipient}(\mathsf{height})\!`, - :math:`\mathsf{cb}` \MUST contain at least one output that pays - :math:`\mathsf{fs.Value}(\mathsf{height})` \zatoshi in the prescribed way to + $\mathsf{DEFERRED\_POOL}$ given by + $\mathsf{fs.Recipient}(\mathsf{height})$, + $\mathsf{cb}$ \MUST contain at least one output that pays + $\mathsf{fs.Value}(\mathsf{height})$ zatoshi in the prescribed way to the address represented by that recipient identifier. -- :math:`\mathsf{fs.Recipient}(\mathsf{height})` is defined as - :math:`\mathsf{fs.Recipients_{\,\fs.RecipientIndex}}(\mathsf{height})\!`. +- $\mathsf{fs.Recipient}(\mathsf{height})$ is defined as + $\mathsf{fs.Recipients_{\,fs.RecipientIndex}}(\mathsf{height})$. - The "prescribed way" to pay a transparent P2SH address is to use a standard P2SH script of the form ``OP_HASH160 RedeemScriptHash(height) OP_EQUAL`` as @@ -243,15 +243,15 @@ Once the Canopy network upgrade activates: That is, all Sapling outputs in coinbase transactions (including, but not limited to, outputs for funding streams) MUST have valid note commitments when recovered using a 32-byte array of zeroes as the outgoing viewing key. - In this case the note plaintext lead byte MUST be :math:`\mathbf{0x02}\!`, as + In this case the note plaintext lead byte MUST be $\mathbf{0x02}$, as specified in [#zip-0212]_. -These rules are reproduced in [#protocol-fundingstreams]. +These rules are reproduced in [#protocol-fundingstreams]_. -The effect of the definition of :math:`\mathsf{ChainValuePoolBalance^{Deferred}}` -above is that payments to the :math:`\mathsf{DEFERRED}\_\mathsf{POOL}` cause -:math:`\mathsf{FundingStream[FUND].Value}(\mathsf{height})` to be added to -:math:`\mathsf{ChainValuePoolBalance^{Deferred}}` for the block chain including +The effect of the definition of $\mathsf{ChainValuePoolBalance^{Deferred}}$ +above is that payments to the $\mathsf{DEFERRED\_POOL}$ cause +$\mathsf{FundingStream[FUND].Value}(\mathsf{height})$ to be added to +$\mathsf{ChainValuePoolBalance^{Deferred}}$ for the block chain including that block. For the funding stream definitions to be activated at Canopy and at NU6, see @@ -289,25 +289,25 @@ Reference Implementation References ========== -.. [#BCP14] `Information on BCP 14 — "RFC 2119: Key words for use in RFCs to Indicate Requirement Levels" and "RFC 8174: Ambiguity of Uppercase vs Lowercase in RFC 2119 Key Words" ` -.. [#protocol] `Zcash Protocol Specification, Version 2024.5.1 or later ` -.. [#protocol-subsidyconcepts] `Zcash Protocol Specification, Version 2024.5.1 [NU6]. Section 3.10: Block Subsidy and Founders' Reward ` -.. [#protocol-networks] `Zcash Protocol Specification, Version 2024.5.1 [NU6]. Section 3.12: Mainnet and Testnet ` -.. [#protocol-constants] `Zcash Protocol Specification, Version 2024.5.1 [NU6]. Section 5.3: Constants ` -.. [#protocol-transparentaddrencoding] `Zcash Protocol Specification, Version 2024.5.1 [NU6]. Section 5.6.1.1: Transparent Addresses ` -.. [#protocol-saplingpaymentaddrencoding] `Zcash Protocol Specification, Version 2024.5.1 [NU6]. Section 5.6.3.1: Sapling Payment Addresses ` -.. [#protocol-diffadjustment] `Zcash Protocol Specification, Version 2024.5.1 [NU6]. Section 7.7.3: Difficulty adjustment ` -.. [#protocol-subsidies] `Zcash Protocol Specification, Version 2024.5.1 [NU6]. Section 7.8: Calculation of Block Subsidy, Funding Streams, and Founders' Reward ` -.. [#protocol-foundersreward] `Zcash Protocol Specification, Version 2024.5.1 [NU6]. Section 7.9: Payment of Founders' Reward ` -.. [#protocol-fundingstreams] `Zcash Protocol Specification, Version 2024.5.1 [NU6]. Section 7.10: Payment of Funding Streams ` -.. [#zip-0000] `ZIP 0: ZIP Process ` -.. [#zip-0200] `ZIP 200: Network Upgrade Mechanism ` -.. [#zip-0208] `ZIP 208: Shorter Block Target Spacing ` -.. [#zip-0212] `ZIP 212: Allow Recipient to Derive Sapling Ephemeral Secret from Note Plaintext ` -.. [#zip-0213] `ZIP 213: Shielded Coinbase ` -.. [#zip-0214] `ZIP 214: Consensus rules for a Zcash Development Fund ` -.. [#zip-0251] `ZIP 251: Deployment of the Canopy Network Upgrade ` -.. [#zip-0253] `ZIP 253: Deployment of the NU6 Network Upgrade ` -.. [#zip-1014] `ZIP 1014: Establishing a Dev Fund for ECC, ZF, and Major Grants ` -.. [#zip-1015] `ZIP 1015: Block Reward Allocation for Non-Direct Development Funding ` -.. [#zip-2001] `ZIP 2001: Lockbox Funding Streams ` +.. [#BCP14] `Information on BCP 14 — "RFC 2119: Key words for use in RFCs to Indicate Requirement Levels" and "RFC 8174: Ambiguity of Uppercase vs Lowercase in RFC 2119 Key Words" `_ +.. [#protocol] `Zcash Protocol Specification, Version 2024.5.1 or later `_ +.. [#protocol-subsidyconcepts] `Zcash Protocol Specification, Version 2024.5.1 [NU6]. Section 3.10: Block Subsidy and Founders' Reward `_ +.. [#protocol-networks] `Zcash Protocol Specification, Version 2024.5.1 [NU6]. Section 3.12: Mainnet and Testnet `_ +.. [#protocol-constants] `Zcash Protocol Specification, Version 2024.5.1 [NU6]. Section 5.3: Constants `_ +.. [#protocol-transparentaddrencoding] `Zcash Protocol Specification, Version 2024.5.1 [NU6]. Section 5.6.1.1: Transparent Addresses `_ +.. [#protocol-saplingpaymentaddrencoding] `Zcash Protocol Specification, Version 2024.5.1 [NU6]. Section 5.6.3.1: Sapling Payment Addresses `_ +.. [#protocol-diffadjustment] `Zcash Protocol Specification, Version 2024.5.1 [NU6]. Section 7.7.3: Difficulty adjustment `_ +.. [#protocol-subsidies] `Zcash Protocol Specification, Version 2024.5.1 [NU6]. Section 7.8: Calculation of Block Subsidy, Funding Streams, and Founders' Reward `_ +.. [#protocol-foundersreward] `Zcash Protocol Specification, Version 2024.5.1 [NU6]. Section 7.9: Payment of Founders' Reward `_ +.. [#protocol-fundingstreams] `Zcash Protocol Specification, Version 2024.5.1 [NU6]. Section 7.10: Payment of Funding Streams `_ +.. [#zip-0000] `ZIP 0: ZIP Process `_ +.. [#zip-0200] `ZIP 200: Network Upgrade Mechanism `_ +.. [#zip-0208] `ZIP 208: Shorter Block Target Spacing `_ +.. [#zip-0212] `ZIP 212: Allow Recipient to Derive Sapling Ephemeral Secret from Note Plaintext `_ +.. [#zip-0213] `ZIP 213: Shielded Coinbase `_ +.. [#zip-0214] `ZIP 214: Consensus rules for a Zcash Development Fund `_ +.. [#zip-0251] `ZIP 251: Deployment of the Canopy Network Upgrade `_ +.. [#zip-0253] `ZIP 253: Deployment of the NU6 Network Upgrade `_ +.. [#zip-1014] `ZIP 1014: Establishing a Dev Fund for ECC, ZF, and Major Grants `_ +.. [#zip-1015] `ZIP 1015: Block Subsidy Allocation for Non-Direct Development Funding `_ +.. [#zip-2001] `ZIP 2001: Lockbox Funding Streams `_ diff --git a/zips/zip-0208.rst b/zips/zip-0208.rst index cf9840f27..bfd02e4e9 100644 --- a/zips/zip-0208.rst +++ b/zips/zip-0208.rst @@ -71,112 +71,123 @@ The changes described in this section are to be made in the Zcash Protocol Speci Consensus changes ----------------- -Throughout the specification, rename HalvingInterval to PreBlossomHalvingInterval, -and rename PoWTargetSpacing to PreBlossomTargetSpacing. These constants retain -their values from [#preblossom-protocol]_ of 840000 (blocks) and 150 (seconds) -respectively. +Throughout the specification, rename $\mathsf{HalvingInterval}$ to $\mathsf{PreBlossomHalvingInterval}$, +and rename $\mathsf{PoWTargetSpacing}$ to $\mathsf{PreBlossomTargetSpacing}$. These constants retain +their values from [#preblossom-protocol]_ of $840000$ (blocks) and $150$ (seconds) respectively. -In section 2 (Notation), add BlossomActivationHeight and PostBlossomPoWTargetSpacing +In section 2 (Notation), add $\mathsf{BlossomActivationHeight}$ and $\mathsf{PostBlossomPoWTargetSpacing}$ to the list of integer constants. -In section 5.3 (Constants), define PostBlossomPoWTargetSpacing := 75 seconds. +In section 5.3 (Constants), define $\mathsf{PostBlossomPoWTargetSpacing} := 75$ seconds. -For a given network (production or test), define BlossomActivationHeight as the +For a given network (production or test), define $\mathsf{BlossomActivationHeight}$ as the height at which Blossom activates on that network, as specified in [#zip-0206]_. In section 7.6.3 (Difficulty adjustment) [later moved to section 7.7.3], make the following changes: -Define IsBlossomActivated(*height*) to return true if *height* ≥ BlossomActivationHeight, -otherwise false. +Define $\mathsf{IsBlossomActivated}(\mathsf{height})$ to return true if +$\mathsf{height} \geq \mathsf{BlossomActivationHeight}$, otherwise false. -This specification assumes that BlossomActivationHeight ≥ SlowStartInterval. +This specification assumes that $\mathsf{BlossomActivationHeight} \geq \mathsf{SlowStartInterval}$. Define: -- BlossomPoWTargetSpacingRatio := PreBlossomPoWTargetSpacing / PostBlossomPoWTargetSpacing -- PostBlossomHalvingInterval := floor(PreBlossomHalvingInterval · BlossomPoWTargetSpacingRatio). +- $\mathsf{BlossomPoWTargetSpacingRatio} := \mathsf{PreBlossomPoWTargetSpacing} / \mathsf{PostBlossomPoWTargetSpacing}$ +- $\mathsf{PostBlossomHalvingInterval} := \mathsf{floor}(\mathsf{PreBlossomHalvingInterval} \cdot \mathsf{BlossomPoWTargetSpacingRatio})$. -In the same section, redefine PoWTargetSpacing as a function taking a *height* -parameter, as follows: +In the same section, redefine $\mathsf{PoWTargetSpacing} as a function taking a +$\mathsf{height}$ parameter, as follows: -- PoWTargetSpacing(*height*) := +.. math:: + \mathsf{PoWTargetSpacing}(\mathsf{height}) := + \begin{cases} + \mathsf{PreBlossomPoWTargetSpacing}, &\!\!\text{if not } \mathsf{IsBlossomActivated}(\mathsf{height}) \\ + \mathsf{PostBlossomPoWTargetSpacing} &\!\!\text{otherwise} + \end{cases} - - PreBlossomPoWTargetSpacing, if not IsBlossomActivated(*height*) - - PostBlossomPoWTargetSpacing, otherwise. +Also redefine $\mathsf{AveragingWindowTimespan}$, $\mathsf{MinActualTimespan}$, $\mathsf{MaxActualTimespan}$, +$\mathsf{ActualTimespanDamped}$, $\mathsf{ActualTimespanBounded}$, and $\mathsf{Threshold}$ as follows: -Also redefine AveragingWindowTimespan, MinActualTimespan, MaxActualTimespan, -ActualTimespanDamped, ActualTimespanBounded, and Threshold as follows: - -- add a *height* parameter to each of these functions that does not already +- add a $\mathsf{height}$ parameter to each of these functions that does not already have one; -- ensure that each reference to any of these values, or to PoWTargetSpacing, - are replaced with a function call passing the *height* parameter. +- ensure that each reference to any of these values, or to $\mathsf{PoWTargetSpacing}$, + are replaced with a function call passing the $\mathsf{height}$ parameter. In section 7.7 (Calculation of Block Subsidy and Founders’ Reward) [later moved -to section 7.8], redefine the Halving and BlockSubsidy functions as follows: - -- Halving(*height*) := - - - floor((*height* - SlowStartShift) / PreBlossomHalvingInterval), if not IsBlossomActivated(*height*) - - floor((BlossomActivationHeight - SlowStartShift) / PreBlossomHalvingInterval + (*height* - BlossomActivationHeight) / PostBlossomHalvingInterval), otherwise - -- BlockSubsidy(*height*) := - - - SlowStartRate · *height*, if *height* < SlowStartInterval / 2 - - SlowStartRate · (*height* + 1), if SlowStartInterval / 2 ≤ *height* and *height* < SlowStartInterval - - floor(MaxBlockSubsidy / 2\ :sup:`Halving(*height*)`\ ), if SlowStartInterval ≤ *height* and not IsBlossomActivated(*height*) - - floor(MaxBlockSubsidy / (BlossomPoWTargetSpacingRatio · 2\ :sup:`Halving(*height*)`\ )), otherwise - -Note: BlossomActivationHeight, PostBlossomHalvingInterval, and PostBlossomTargetSpacing are chosen so that: - -- (BlossomActivationHeight - SlowStartShift) / PreBlossomHalvingInterval + (*height* - BlossomActivationHeight) / PostBlossomHalvingInterval) - is exactly 1 for some integer *height*. -- MaxBlockSubsidy / (BlossomPoWTargetSpacingRatio · 2\ :sup:`Halving(*height*)`\ ) +to section 7.8], redefine the $\mathsf{Halving}$ and $\mathsf{BlockSubsidy}$ functions as follows: + +.. math:: + \mathsf{Halving}(\mathsf{height}) := + \begin{cases} + \mathsf{floor}((\mathsf{height} - \mathsf{SlowStartShift}) / \mathsf{PreBlossomHalvingInterval}), &\!\!\text{if not } \mathsf{IsBlossomActivated}(\mathsf{height}) \\ + \mathsf{floor}((\mathsf{BlossomActivationHeight} - \mathsf{SlowStartShift}) / \mathsf{PreBlossomHalvingInterval} & \\ + \hspace{1em}+\; (\mathsf{height} - \mathsf{BlossomActivationHeight}) / \mathsf{PostBlossomHalvingInterval}) &\!\!\text{otherwise} + \end{cases} + +.. math:: + \mathsf{BlockSubsidy}(\mathsf{height}) := + \begin{cases} + \mathsf{SlowStartRate} \cdot \mathsf{height}, &\!\!\text{if } \mathsf{height} < \mathsf{SlowStartInterval} / 2 \\ + \mathsf{SlowStartRate} \cdot (\mathsf{height} + 1), &\!\!\text{if } \mathsf{SlowStartInterval} / 2 \leq \mathsf{height} \text{ and } \mathsf{height} < \mathsf{SlowStartInterval} \\ + \mathsf{floor}(\mathsf{MaxBlockSubsidy} / 2^{\mathsf{Halving}(\mathsf{height})}), &\!\!\text{if } \mathsf{SlowStartInterval} \leq \mathsf{height} \text{ and not } \mathsf{IsBlossomActivated}(\mathsf{height}) \\ + \mathsf{floor}(\mathsf{MaxBlockSubsidy} / & \\ + \hspace{1em}(\mathsf{BlossomPoWTargetSpacingRatio} \cdot 2^{\mathsf{Halving}(\mathsf{height})})) &\!\!\text{otherwise} + \end{cases} + +Note: $\mathsf{BlossomActivationHeight}$, $\mathsf{PostBlossomHalvingInterval}$, and $\mathsf{PostBlossomTargetSpacing}$ are chosen so that: + +- $(\mathsf{BlossomActivationHeight} - \mathsf{SlowStartShift}) / \mathsf{PreBlossomHalvingInterval}\hspace{-3em}$ + $\hspace{3em}+\; (\mathsf{height} - \mathsf{BlossomActivationHeight}) / \mathsf{PostBlossomHalvingInterval}$ + is exactly $1$ for some integer $\mathsf{height}$. +- $\mathsf{MaxBlockSubsidy} / (\mathsf{BlossomPoWTargetSpacingRatio} \cdot 2^{\mathsf{Halving}(\mathsf{height})})$ is an integer for the next few periods. In section 7.8 (Payment of Founders’ Reward) [later moved to section 7.9], define: -- FounderAddressAdjustedHeight(*height*) := - - - *height*, if not IsBlossomActivated(*height*) - - BlossomActivationHeight + floor((*height* - BlossomActivationHeight) / BlossomPoWTargetSpacingRatio), otherwise +.. math:: + \mathsf{FounderAddressAdjustedHeight}(\mathsf{height}) := + \begin{cases} + \mathsf{height}, &\!\!\text{if not } \mathsf{IsBlossomActivated}(\mathsf{height}) \\ + \mathsf{BlossomActivationHeight} + \mathsf{floor}((\mathsf{height} - \mathsf{BlossomActivationHeight}) / \\ + \hspace{1em}\mathsf{BlossomPoWTargetSpacingRatio}) &\!\!\text{otherwise} + \end{cases} -and in the definition of FounderAddressIndex, replace the use of *height* with FounderAddressAdjustedHeight(*height*). +and in the definition of $\mathsf{FounderAddressIndex}$, replace the use of $\mathsf{height}$ with $\mathsf{FounderAddressAdjustedHeight}(\mathsf{height})$. Also define: -- FoundersRewardLastBlockHeight := max({ *height* ⦂ N | Halving(*height*) < 1 }) +- $\mathsf{FoundersRewardLastBlockHeight} := \mathsf{max}(\{ \mathsf{height} \;{\small ⦂}\; \mathbb{N} | \mathsf{Halving}(\mathsf{height}) < 1 \})$ Replace the first note in that section with: -- No Founders’ Reward is required to be paid for *height* > FoundersRewardLastBlockHeight - (i.e. after the first halving), or for *height* = 0 (i.e. the genesis block). +- No Founders’ Reward is required to be paid for $\mathsf{height} > \mathsf{FoundersRewardLastBlockHeight}$ + (i.e. after the first halving), or for $\mathsf{height} = 0$ (i.e. the genesis block). -and in the second note, replace SlowStartShift + PreBlossomHalvingInterval - 1 with -FoundersRewardLastBlockHeight. +and in the second note, replace $\mathsf{SlowStartShift} + \mathsf{PreBlossomHalvingInterval} - 1$ with +$\mathsf{FoundersRewardLastBlockHeight}$. Effect on difficulty adjustment ------------------------------- -The difficulty adjustment parameters PoWAveragingWindow and PoWMedianBlockSpan +The difficulty adjustment parameters $\mathsf{PoWAveragingWindow}$ and $\mathsf{PoWMedianBlockSpan}$ refer to numbers of blocks, but do *not* change at Blossom activation. This is because the amount of damping/averaging required is expected to be roughly the same, in terms of the number of blocks, after the change in block target spacing. -The change in the effective value of PoWTargetSpacing will cause the block +The change in the effective value of $\mathsf{PoWTargetSpacing}$ will cause the block spacing to adjust to the new target, at the normal rate for a difficulty adjustment. The results of simulations are consistent with this expected behaviour. -Note that the change in AveragingWindowTimespan(height) takes effect +Note that the change in $\mathsf{AveragingWindowTimespan(\mathsf{height})$ takes effect immediately when calculating the target difficulty starting from the block at the Blossom activation height, even though the difficulty of the preceding -PoWAveragingWindow blocks will have been adjusted using the pre-Blossom target +$\mathsf{PoWAveragingWindow}$ blocks will have been adjusted using the pre-Blossom target spacing. Therefore it is likely that the difficulty adjustment for the first -few blocks after activation will be limited by PoWMaxAdjustDown. This is not +few blocks after activation will be limited by $\mathsf{PoWMaxAdjustDown}$. This is not anticipated to cause any problem. @@ -189,12 +200,13 @@ On Testnet from block height 299188 onward, the difficulty adjustment algorithm specification changes this threshold to be proportional to the block target spacing. -That is, if the block time of a block at height *height* ≥ 299188 is greater than -6 · PoWTargetSpacing(*height*) seconds after that of the preceding block, -then the block is a minimum-difficulty block. In that case its ``nBits`` field -MUST be set to ToCompact(PoWLimit), where PoWLimit is the value defined for Testnet -in section 5.3 of the Zcash Protocol Specification [#protocol-constants]_, and -ToCompact is as defined in section 7.7.4 of that specification [#protocol-nbits]_. +That is, if the block time of a block at height $\mathsf{height} \geq 299188$ is greater +than $6 \cdot \mathsf{PoWTargetSpacing}(\mathsf{height})$ seconds after that of the +preceding block, then the block is a minimum-difficulty block. In that case its ``nBits`` +field MUST be set to $\mathsf{ToCompact}(\mathsf{PoWLimit})$, where $\mathsf{PoWLimit}$ +is the value defined for Testnet in section 5.3 of the Zcash Protocol Specification +[#protocol-constants]_, and $\mathsf{ToCompact}$ is as defined in section 7.7.4 of that +specification [#protocol-nbits]_. Note: a previous revision of this ZIP (and [#zip-0205]_) incorrectly said that only the target threshold of minimum-difficulty blocks is affected. In fact @@ -324,7 +336,7 @@ an hour after responding to the message:: // for some reasonable time window (1 hour) that block relay might require. For each block, when estimating whether it will still be on disk after an hour, we -take MIN_BLOCKS_TO_KEEP = 288 blocks, minus approximately the number of blocks expected +take MIN_BLOCKS_TO_KEEP = $288$ blocks, minus approximately the number of blocks expected in one hour at the target block spacing as of that block. Around Blossom activation, this might underestimate the number of blocks in the next hour, but given the value of MIN_BLOCKS_TO_KEEP, this is not anticipated to cause any problem. @@ -388,7 +400,7 @@ pre-upgrade consensus branch that persists. Reference Implementation ======================== -https://github.com/zcash/zcash/pull/4025 +* https://github.com/zcash/zcash/pull/4025 References diff --git a/zips/zip-0212.rst b/zips/zip-0212.rst index 0669e8f60..93ce9dc67 100644 --- a/zips/zip-0212.rst +++ b/zips/zip-0212.rst @@ -19,17 +19,17 @@ in all capitals. The following functions are defined in the Zcash Protocol Specification [#protocol]_ according to the type (Sapling or Orchard) of note plaintext being processed: -* let :math:`\mathsf{ToScalar}` be - :math:`\mathsf{ToScalar^{Sapling}}` defined in section 4.2.2 [#protocol-saplingkeycomponents]_ or - :math:`\mathsf{ToScalar^{Orchard}}` defined in section 4.2.3 [#protocol-orchardkeycomponents]_; -* let :math:`\mathsf{DiversifyHash}` be - :math:`\mathsf{DiversifyHash^{Sapling}}` or :math:`\mathsf{DiversifyHash^{Orchard}}` +* let $\mathsf{ToScalar}$ be + $\mathsf{ToScalar^{Sapling}}$ defined in section 4.2.2 [#protocol-saplingkeycomponents]_ or + $\mathsf{ToScalar^{Orchard}}$ defined in section 4.2.3 [#protocol-orchardkeycomponents]_; +* let $\mathsf{DiversifyHash}$ be + $\mathsf{DiversifyHash^{Sapling}}$ or $\mathsf{DiversifyHash^{Orchard}}$ defined in section 5.4.1.6 [#protocol-concretediversifyhash]_; -* let :math:`\mathsf{KA}` be - :math:`\mathsf{KA^{Sapling}}` defined in section 5.4.5.3 [#protocol-concretesaplingkeyagreement]_ or - :math:`\mathsf{KA^{Orchard}}` defined in section 5.4.5.5 [#protocol-concreteorchardkeyagreement]_; -* let :math:`\mathsf{NoteCommit}` be - :math:`\mathsf{NoteCommit^{Sapling}}` or :math:`\mathsf{NoteCommit^{Orchard}}` +* let $\mathsf{KA}$ be + $\mathsf{KA^{Sapling}}$ defined in section 5.4.5.3 [#protocol-concretesaplingkeyagreement]_ or + $\mathsf{KA^{Orchard}}$ defined in section 5.4.5.5 [#protocol-concreteorchardkeyagreement]_; +* let $\mathsf{NoteCommit}$ be + $\mathsf{NoteCommit^{Sapling}}$ or $\mathsf{NoteCommit^{Orchard}}$ defined in section 4.1.8 [#protocol-abstractcommit]_. @@ -54,28 +54,28 @@ allows users to maintain many payment addresses without paying additional overhead during blockchain scanning. The feature works by allowing payment addresses to become a tuple -:math:`(\mathsf{pk_d}, \mathsf{d})` of a public key :math:`\mathsf{pk_d}` and -:math:`88\!`-bit diversifier :math:`\mathsf{d}` such that -:math:`\mathsf{pk_d} = [\mathsf{ivk}]\, \mathsf{DiversifyHash}(\mathsf{d})` for -some incoming viewing key :math:`\mathsf{ivk}\!`. The hash function -:math:`\mathsf{DiversifyHash}(\mathsf{d})` maps from a diversifier to prime-order +$(\mathsf{pk_d}, \mathsf{d})$ of a public key $\mathsf{pk_d}$ and +$88$-bit diversifier $\mathsf{d}$ such that +$\mathsf{pk_d} = [\mathsf{ivk}]\, \mathsf{DiversifyHash}(\mathsf{d})$ for +some incoming viewing key $\mathsf{ivk}$. The hash function +$\mathsf{DiversifyHash}(\mathsf{d})$ maps from a diversifier to prime-order elements of the Jubjub or Pallas elliptic curve. It is possible for a user -to choose many :math:`\mathsf{d}` to create several distinct and unlinkable +to choose many $\mathsf{d}$ to create several distinct and unlinkable payment addresses of this form. In order to make a payment to a Sapling or Orchard address, an ephemeral secret -:math:`\mathsf{esk}` is sampled by the sender and an ephemeral public key -:math:`\mathsf{epk} = [\mathsf{esk}]\, \mathsf{DiversifyHash}(\mathsf{d})` is +$\mathsf{esk}$ is sampled by the sender and an ephemeral public key +$\mathsf{epk} = [\mathsf{esk}]\, \mathsf{DiversifyHash}(\mathsf{d})$ is included in the Output or Action description. Then, a shared Diffie-Hellman secret is computed by the sender as -:math:`\mathsf{KA.Agree}(\mathsf{esk}, \mathsf{pk_d})\!`. The recipient can -recover this shared secret without knowledge of the particular :math:`\mathsf{d}` -by computing :math:`\mathsf{KA.Agree}(\mathsf{ivk}, \mathsf{epk})\!`. This shared +$\mathsf{KA.Agree}(\mathsf{esk}, \mathsf{pk_d})$. The recipient can +recover this shared secret without knowledge of the particular $\mathsf{d}$ +by computing $\mathsf{KA.Agree}(\mathsf{ivk}, \mathsf{epk})$. This shared secret is then used as part of note decryption. -Naïvely, the recipient cannot know which :math:`(\mathsf{pk_d}, \mathsf{d})` +Naïvely, the recipient cannot know which $(\mathsf{pk_d}, \mathsf{d})$ was used to compute the shared secret, but the sender is asked to include the -:math:`\mathsf{d}` within the note plaintext to reconstruct the note. However, +$\mathsf{d}$ within the note plaintext to reconstruct the note. However, if the recipient has more than one known address, an attacker could use a different payment address to perform secret exchange and, by observing the behavior of the recipient, link the two diversified addresses together. (This @@ -84,9 +84,9 @@ Sapling protocol.) In order to prevent this attack before activation of this ZIP, the protocol forced the sender to prove knowledge of the discrete logarithm of -:math:`\mathsf{epk}` with respect to the -:math:`\mathsf{g_d} = \mathsf{DiversifyHash}(\mathsf{d})` included within the -note commitment. This :math:`\mathsf{g_d}` is determined by :math:`\mathsf{d}` +$\mathsf{epk}$ with respect to the +$\mathsf{g_d} = \mathsf{DiversifyHash}(\mathsf{d})$ included within the +note commitment. This $\mathsf{g_d}$ is determined by $\mathsf{d}$ and recomputed during note decryption, and so either the note decryption will fail, or the sender will be unable to produce the proof that requires knowledge of the discrete logarithm. @@ -95,19 +95,19 @@ However, the latter proof was part of the Sapling Output statement, and so relied on the soundness of the underlying Groth16 zk-SNARK — hence on relatively strong cryptographic assumptions and a trusted setup. It is preferable to force the sender to transfer sufficient information in the note plaintext to allow -deriving :math:`\mathsf{esk}\!`, so that, during note decryption, the recipient -can check that :math:`\mathsf{epk} = [\mathsf{esk}]\, \mathsf{g_d}` for the -expected :math:`\mathsf{g_d}\!`, and ignore the payment as invalid otherwise. +deriving $\mathsf{esk}$, so that, during note decryption, the recipient +can check that $\mathsf{epk} = [\mathsf{esk}]\, \mathsf{g_d}$ for the +expected $\mathsf{g_d}$, and ignore the payment as invalid otherwise. For Sapling, this forms a line of defense in the case that soundness of the zk-SNARK does not hold. For Orchard, this check is essential because (for -efficiency and simplicity) :math:`\mathsf{epk} = [\mathsf{esk}]\, \mathsf{g_d}` +efficiency and simplicity) $\mathsf{epk} = [\mathsf{esk}]\, \mathsf{g_d}$ is *not* checked in the Action statement. -Merely sending :math:`\mathsf{esk}` to the recipient in the note plaintext would +Merely sending $\mathsf{esk}$ to the recipient in the note plaintext would require us to enlarge the note plaintext, but also would compromise the proof of IND-CCA2 security for in-band secret distribution. We avoid both of these -concerns by using a key derivation to obtain both :math:`\mathsf{esk}` and -:math:`\mathsf{rcm}\!`. +concerns by using a key derivation to obtain both $\mathsf{esk}$ and +$\mathsf{rcm}$. Specification @@ -121,17 +121,17 @@ Specification Please note that prior versions of the protocol specification (2022.3.8 and earlier) were inconsistent with this ZIP regarding the - domain separators for :math:`\mathsf{PRF^{expand}}` used to derive - :math:`\mathsf{rcm}` and :math:`\mathsf{esk}\!`. The protocol + domain separators for $\mathsf{PRF^{expand}}$ used to derive + $\mathsf{rcm}$ and $\mathsf{esk}$. The protocol specification diverged from the deployed implementations for Sapling, and this ZIP previously (before December 2023) diverged from the deployed implementations for Orchard. Pseudo random functions (PRFs) are defined in section 4.1.2 of the Zcash Protocol Specification [#protocol-abstractprfs]_. We will be adapting -:math:`\mathsf{PRF^{expand}}` for the purposes of this ZIP. This function is -keyed by a 256-bit key :math:`\mathsf{sk}` and takes an arbitrary length byte -sequence as input, returning a :math:`64\!`-byte sequence as output. +$\mathsf{PRF^{expand}}$ for the purposes of this ZIP. This function is +keyed by a 256-bit key $\mathsf{sk}$ and takes an arbitrary length byte +sequence as input, returning a $64$-byte sequence as output. Changes to Sapling and Orchard Note plaintexts ---------------------------------------------- @@ -139,22 +139,22 @@ Changes to Sapling and Orchard Note plaintexts Note plaintext encodings are specified in section 5.5 of the Zcash Protocol Specification [#protocol-notept]_. Before activation of this ZIP, the encoding of a Sapling note plaintext required that the first byte take the form -:math:`\mathtt{0x01}\!`, indicating the version of the note plaintext. In -addition, a :math:`256\!`-bit :math:`\mathsf{rcm}` field exists within the +$\mathtt{0x01}$, indicating the version of the note plaintext. In +addition, a $256$-bit $\mathsf{rcm}$ field exists within the note plaintext and encoding. Following the activation of this ZIP, senders of Sapling or Orchard notes MUST use the following note plaintext format: -* The first byte of the encoding MUST take the form :math:`\mathtt{0x02}` +* The first byte of the encoding MUST take the form $\mathtt{0x02}$ (representing the new note plaintext version). -* The field :math:`\mathsf{rcm}` of the encoding is renamed to - :math:`\mathsf{rseed}\!`. This field :math:`\mathsf{rseed}` of the Sapling +* The field $\mathsf{rcm}$ of the encoding is renamed to + $\mathsf{rseed}$. This field $\mathsf{rseed}$ of the Sapling or Orchard note plaintext no longer takes the type of - :math:`\mathsf{NoteCommit.Trapdoor}` (as it did for Sapling) but instead - is a :math:`32\!`-byte sequence. + $\mathsf{NoteCommit.Trapdoor}$ (as it did for Sapling) but instead + is a $32$-byte sequence. -The requirement that the former :math:`\mathsf{rcm}` field be a scalar of the +The requirement that the former $\mathsf{rcm}$ field be a scalar of the Jubjub elliptic curve, when interpreted as a little endian integer, is removed from descriptions of note plaintexts in the Zcash Protocol Specification. @@ -166,34 +166,34 @@ Protocol Specification for Sapling [#protocol-saplingsend]_ and section 4.7.3 for Orchard [#protocol-orchardsend]_. In addition, the process of encrypting a note is described in section 4.19.1 of the Zcash Protocol Specification [#protocol-saplingandorchardencrypt]_. Prior to activation of this ZIP, the -sender sampled :math:`\mathsf{rcm^{new}}` and the ephemeral private key -:math:`\mathsf{esk}` uniformly at random during this process. +sender sampled $\mathsf{rcm^{new}}$ and the ephemeral private key +$\mathsf{esk}$ uniformly at random during this process. After the activation of this ZIP, the sender MUST instead sample a uniformly -random :math:`32\!`-byte sequence :math:`\mathsf{rseed}\!`. The note plaintext takes -:math:`\mathsf{rseed}` in place of :math:`\mathsf{rcm^{new}}\!`. +random $32$-byte sequence $\mathsf{rseed}$. The note plaintext takes +$\mathsf{rseed}$ in place of $\mathsf{rcm^{new}}$. For Sapling: -* :math:`\mathsf{rcm^{new}}` MUST be derived as the output of - :math:`\mathsf{ToScalar}(\mathsf{PRF^{expand}_{rseed}}([4]))\!`. -* :math:`\mathsf{esk}` MUST be derived as the output of - :math:`\mathsf{ToScalar}(\mathsf{PRF^{expand}_{rseed}}([5]))\!`. +* $\mathsf{rcm^{new}}$ MUST be derived as the output of + $\mathsf{ToScalar}(\mathsf{PRF^{expand}_{rseed}}([4]))$. +* $\mathsf{esk}$ MUST be derived as the output of + $\mathsf{ToScalar}(\mathsf{PRF^{expand}_{rseed}}([5]))$. For Orchard: -* :math:`\mathsf{rcm^{new}}` MUST be derived as the output of - :math:`\mathsf{ToScalar}(\mathsf{PRF^{expand}_{rseed}}([5] \,||\, \underline{\text{ρ}}))\!`. -* :math:`\mathsf{esk}` MUST be derived as the output of - :math:`\mathsf{ToScalar}(\mathsf{PRF^{expand}_{rseed}}([4] \,||\, \underline{\text{ρ}}))\!`. -* :math:`\text{φ}` MUST be derived as the output of - :math:`\mathsf{ToScalar}(\mathsf{PRF^{expand}_{rseed}}([9] \,||\, \underline{\text{ρ}}))\!`. +* $\mathsf{rcm^{new}}$ MUST be derived as the output of + $\mathsf{ToScalar}(\mathsf{PRF^{expand}_{rseed}}([5] \,||\, \underline{\text{ρ}}))$. +* $\mathsf{esk}$ MUST be derived as the output of + $\mathsf{ToScalar}(\mathsf{PRF^{expand}_{rseed}}([4] \,||\, \underline{\text{ρ}}))$. +* $\text{φ}$ MUST be derived as the output of + $\mathsf{ToScalar}(\mathsf{PRF^{expand}_{rseed}}([9] \,||\, \underline{\text{ρ}}))$. -where :math:`\underline{\text{ρ}} = \mathsf{I2LEOSP}_{256}(\mathsf{nf^{old}}` from the same Action description :math:`\!)\!`. +where $\underline{\text{ρ}} = \mathsf{I2LEOSP}_{256}(\mathsf{nf^{old}}$ from the same Action description $\!)$. .. note:: - The domain separators :math:`[4]` and :math:`[5]` used in the input to - :math:`\mathsf{PRF^{expand}_{rseed}}` are swapped for Orchard relative to + The domain separators $[4]$ and $[5]$ used in the input to + $\mathsf{PRF^{expand}_{rseed}}$ are swapped for Orchard relative to Sapling. This was due to an oversight and there is no good reason for it. The specified domain separators were corrected to match the deployed @@ -209,7 +209,7 @@ The process of receiving notes in Sapling is described in sections 4.19.2 and [#protocol-decryptovk]_ There is a "grace period" of 32256 blocks starting from the block at which this -ZIP activates, during which note plaintexts with lead byte :math:`\mathtt{0x01}` +ZIP activates, during which note plaintexts with lead byte $\mathtt{0x01}$ MUST still be accepted. Let ActivationHeight be the activation height of this ZIP, and let @@ -226,12 +226,12 @@ viewing key) is able to decrypt a note plaintext, it performs the following check on the plaintext lead byte, based on the height of the containing transaction: -* If the height is less than ActivationHeight, then only :math:`\mathtt{0x01}` +* If the height is less than ActivationHeight, then only $\mathtt{0x01}$ is accepted as the plaintext lead byte. * If the height is at least ActivationHeight and less than GracePeriodEndHeight, - then either :math:`\mathtt{0x01}` or :math:`\mathtt{0x02}` is accepted as the + then either $\mathtt{0x01}$ or $\mathtt{0x02}$ is accepted as the plaintext lead byte. -* If the height is at least GracePeriodEndHeight, then only :math:`\mathtt{0x02}` +* If the height is at least GracePeriodEndHeight, then only $\mathtt{0x02}$ is accepted as the plaintext lead byte. If the plaintext lead byte is not accepted then the note MUST be discarded. @@ -239,13 +239,13 @@ However, if an implementation decrypted the note from a mempool transaction and it was accepted at that time, but it is later mined in a block after the end of the grace period, then it MAY be retained. -A note plaintext with lead byte :math:`\mathtt{0x02}` contains a field -:math:`\mathsf{rseed}` that is a :math:`32\!`-byte sequence rather than a scalar -value :math:`\mathsf{rcm}\!`. The recipient, during decryption and in any later -contexts, will derive :math:`\mathsf{rcm}` using :math:`\mathsf{PRF^{expand}_{rseed}}` +A note plaintext with lead byte $\mathtt{0x02}$ contains a field +$\mathsf{rseed}$ that is a $32$-byte sequence rather than a scalar +value $\mathsf{rcm}$. The recipient, during decryption and in any later +contexts, will derive $\mathsf{rcm}$ using $\mathsf{PRF^{expand}_{rseed}}$ in the same way as the sender, as described in `Changes to the process of sending Sapling or Orchard notes`_. -Further, the recipient MUST derive :math:`\mathsf{esk}` as described in that -section and check that :math:`\mathsf{epk} = [\mathsf{esk}]\, \mathsf{g_d}\!`, +Further, the recipient MUST derive $\mathsf{esk}$ as described in that +section and check that $\mathsf{epk} = [\mathsf{esk}]\, \mathsf{g_d}$, failing decryption if this check is not satisfied. Consensus rule change for coinbase transactions @@ -253,14 +253,14 @@ Consensus rule change for coinbase transactions After the activation of this ZIP, any Sapling output of a coinbase transaction that is decrypted to a note plaintext as specified in [#zip-0213]_, MUST have -note plaintext lead byte equal to :math:`\mathtt{0x02}\!`. +note plaintext lead byte equal to $\mathtt{0x02}$. This applies even during the “grace period”, and also applies to funding stream outputs [#zip-0207]_ sent to shielded payment addresses, if there are any. Since NU5 activates after the end of the grace period [#zip-0252]_, Orchard outputs will always require a note plaintext lead byte equal to -:math:`\mathtt{0x02}\!`. +$\mathtt{0x02}$. Rationale @@ -276,16 +276,16 @@ Acting differently here would be confusing for users that have previously been told that "privacy does not depend on zk-SNARK soundness" or similar claims. It would have been possible to infringe on the length of the ``memo`` field and -ask the sender to provide :math:`\mathsf{esk}` within the existing note plaintext +ask the sender to provide $\mathsf{esk}$ within the existing note plaintext without modifying the transaction format, but this would have harmed users who -have come to expect a :math:`512\!`-byte memo field to be available to them. +have come to expect a $512$-byte memo field to be available to them. Changes to the memo field length should be considered in a broader context than changes made for cryptographic purposes. It would be possible to transmit a signature of knowledge of a correct -:math:`\mathsf{esk}` rather than :math:`\mathsf{esk}` itself, but this appears +$\mathsf{esk}$ rather than $\mathsf{esk}$ itself, but this appears to be an unnecessary complication and is likely slower than just supplying -:math:`\mathsf{esk}\!`. +$\mathsf{esk}$. The grace period is intended to mitigate loss-of-funds risk due to non-conformant sending wallet implementations. The intention is that during the @@ -294,13 +294,13 @@ are still sending plaintexts according to the old specification, and cajole their developers to make the required updates. For the avoidance of doubt, such wallets are non-conformant because it is a "MUST" requirement to *immediately* switch to sending note plaintexts with lead byte -:math:`\mathtt{0x02}` (and the other changes in this specification) at the +$\mathtt{0x02}$ (and the other changes in this specification) at the upgrade. Note that nodes will clear their mempools when the upgrade activates, -which will clear all plaintexts with lead byte :math:`\mathtt{0x01}` that were +which will clear all plaintexts with lead byte $\mathtt{0x01}$ that were sent conformantly and not mined before the upgrade. Historical note: in practice some note plaintexts with lead byte -:math:`\mathtt{0x01}` were non-conformantly sent even after the end of the +$\mathtt{0x01}$ were non-conformantly sent even after the end of the specified grace period. ZecWallet extended its implementation of the grace period by a further 161280 blocks (approximately 20 weeks) in order to allow for recovery of these funds [#zecwallet-grace-extension]_. @@ -315,9 +315,9 @@ assumption of the zk-SNARK. It is already assumed that the adversary cannot defeat the EC-DDH assumption of the Jubjub (or Pallas) elliptic curve, for it could perform a linkability attack trivially in that case. -In the naïve case where the protocol is modified so that :math:`\mathsf{esk}` +In the naïve case where the protocol is modified so that $\mathsf{esk}$ is supplied directly to the recipient (rather than derived through -:math:`\mathsf{rseed}\!`) this would lead to an instance of key-dependent +$\mathsf{rseed}$) this would lead to an instance of key-dependent encryption, which is difficult or perhaps impossible to prove secure using existing security notions. Our approach of using a key derivation, which ultimately queries an oracle, allows a proof for IND-CCA2 security to be diff --git a/zips/zip-0213.rst b/zips/zip-0213.rst index 5914317a9..5a522430e 100644 --- a/zips/zip-0213.rst +++ b/zips/zip-0213.rst @@ -38,7 +38,7 @@ Motivation Zcash inherited the concept of "coinbase transactions" from Bitcoin: special transactions inside each block that are allowed to have no inputs. These transactions are created by -miners during block creation, and collect the block reward and transaction fees into new +miners during block creation, and collect the block subsidy and transaction fees into new transparent outputs that can then be spent. They are also leveraged in Zcash for the Founders' Reward (and potentially for funding streams [#zip-0207]_). diff --git a/zips/zip-0214.rst b/zips/zip-0214.rst index e9e47979f..974bdd7d9 100644 --- a/zips/zip-0214.rst +++ b/zips/zip-0214.rst @@ -61,8 +61,8 @@ proposed structure of the Zcash Development Fund, which is to be enacted in Network Upgrade 4 and last for 4 years. `Revision 1`_ of this ZIP describes consensus rule changes related to funding -of Zcash development via block rewards, to be enacted at Network Upgrade 6 and -lasting for 1 year. +of Zcash development via block subsidies, to be enacted at Network Upgrade 6 +and lasting for 1 year. Applicability @@ -413,4 +413,4 @@ References .. [#zip-0251] `ZIP 251: Deployment of the Canopy Network Upgrade `_ .. [#zip-0253] `ZIP 253: Deployment of the NU6 Network Upgrade `_ .. [#zip-1014] `ZIP 1014: Establishing a Dev Fund for ECC, ZF, and Major Grants `_ -.. [#zip-1015] `ZIP 1015: Block Reward Allocation for Non-Direct Development Funding `_ +.. [#zip-1015] `ZIP 1015: Block Subsidy Allocation for Non-Direct Development Funding `_ diff --git a/zips/zip-0215.rst b/zips/zip-0215.rst index 25b282269..f90cdbfd1 100644 --- a/zips/zip-0215.rst +++ b/zips/zip-0215.rst @@ -56,24 +56,24 @@ signatures, as is the case for RedJubjub. Specification ============= -After activation of this ZIP, the :math:`\mathsf{JoinSplitSig}` validation rules +After activation of this ZIP, the $\mathsf{JoinSplitSig}$ validation rules in [#protocol-concreteed25519]_ are changed to the following: -- :math:`\underline{A}` and :math:`\underline{R}` MUST be encodings of points - :math:`A` and :math:`R` respectively on the complete twisted Edwards curve Ed25519; -- :math:`\underline{S}` MUST represent an integer :math:`S` less than :math:`\ell`; -- The group equation :math:`[8][S]B = [8]R + [8][k]A` MUST be satisfied, where - :math:`k` and :math:`B` are defined as in RFC 8032 sections §5.1.7 and §5.1 +- $\underline{A}$ and $\underline{R}$ MUST be encodings of points + $A$ and $R$ respectively on the complete twisted Edwards curve Ed25519; +- $\underline{S}$ MUST represent an integer $S$ less than $\ell$; +- The group equation $[8][S]B = [8]R + [8][k]A$ MUST be satisfied, where + $k$ and $B$ are defined as in RFC 8032 sections §5.1.7 and §5.1 respectively. [#RFC8032]_ -The language about :math:`\mathsf{ExcludedPointEncodings}` in §5.4.5 of the Zcash +The language about $\mathsf{ExcludedPointEncodings}$ in §5.4.5 of the Zcash specification [#protocol-concreteed25519]_ no longer applies. -It is *not* required that :math:`\underline{A}` and :math:`\underline{R}` +It is *not* required that $\underline{A}$ and $\underline{R}$ are canonical encodings; in other words, the integer encoding the -:math:`y`-coordinate of the points may be unreduced modulo :math:`2^{255}-19`. +$y$-coordinate of the points may be unreduced modulo $2^{255}-19$. -Note: the alternate validation equation :math:`[S]B = R + [k]A`, allowed +Note: the alternate validation equation $[S]B = R + [k]A$, allowed by RFC 8032, MUST NOT be used. diff --git a/zips/zip-0216.rst b/zips/zip-0216.rst index c2aa86548..55d9b17b3 100644 --- a/zips/zip-0216.rst +++ b/zips/zip-0216.rst @@ -39,7 +39,7 @@ modelled with just the abstract types. The intention of the Jubjub implementation (both in the `jubjub` crate [#jubjub-crate]_ and its prior implementations) was to ensure that only canonical point encodings would be accepted by the decoding logic. However, an oversight in the implementation allowed an -edge case to slip through: for each point on the curve where the :math:`u\!`-coordinate is +edge case to slip through: for each point on the curve where the $u$-coordinate is zero, there are two encodings that will be accepted: .. code-block:: rust @@ -51,13 +51,13 @@ zero, there are two encodings that will be accepted: This code accepts either sign bit, because ``u_negated == u``. -There are two points on the Jubjub curve with :math:`u\!`-coordinate zero: +There are two points on the Jubjub curve with $u$-coordinate zero: -- :math:`(0, 1)`, which is the identity; -- :math:`(0, -1)`, which is a point of order two. +- $(0, 1)$, which is the identity; +- $(0, -1)$, which is a point of order two. Each of these has a single non-canonical encoding in which the value of the sign bit is -:math:`1`. +$1$. This creates a consensus issue because (unlike other non-canonical point encodings that are rejected) either of the above encodings can be decoded, and then re-encoded to a @@ -79,39 +79,39 @@ required 4 specification revisions to get right, conclusively demonstrates the p Specification ============= -Let :math:`\mathsf{abst}_{\mathbb{J}}`, :math:`\mathsf{repr}_{\mathbb{J}}`, and -:math:`q_{\mathbb{J}}` be as defined in [#protocol-jubjub]_. +Let $\mathsf{abst}_{\mathbb{J}}$, $\mathsf{repr}_{\mathbb{J}}$, and +$q_{\mathbb{J}}$ be as defined in [#protocol-jubjub]_. Define a non-canonical compressed encoding of a Jubjub point to be a sequence of -:math:`256` bits, :math:`b`, such that :math:`\mathsf{abst}_{\mathbb{J}}(b) \neq \bot` -and :math:`\mathsf{repr_{\mathbb{J}}}\big(\mathsf{abst}_{\mathbb{J}}(b)\big) \neq b`. +$256$ bits, $b$, such that $\mathsf{abst}_{\mathbb{J}}(b) \neq \bot$ +and $\mathsf{repr_{\mathbb{J}}}\big(\mathsf{abst}_{\mathbb{J}}(b)\big) \neq b$. Non-normative note: There are two such bit sequences, -:math:`\mathsf{I2LEOSP}_{\ell_{\mathbb{J}}}(2^{255} + 1)` and -:math:`\mathsf{I2LEOSP}_{\ell_{\mathbb{J}}}(2^{255} + q_{\mathbb{J}} - 1)`. +$\mathsf{I2LEOSP}_{\ell_{\mathbb{J}}}(2^{255} + 1)$ and +$\mathsf{I2LEOSP}_{\ell_{\mathbb{J}}}(2^{255} + q_{\mathbb{J}} - 1)$. The Sapling protocol uses little-endian ordering when converting between bit and -byte sequences, so the first of these sequences corresponds to a :math:`\mathtt{0x01}` -byte, followed by :math:`30` zero bytes, and then a :math:`\mathtt{0x80}` byte. +byte sequences, so the first of these sequences corresponds to a $\mathtt{0x01}$ +byte, followed by $30$ zero bytes, and then a $\mathtt{0x80}$ byte. Once this ZIP activates, the following places within the Sapling consensus protocol where Jubjub points occur MUST reject non-canonical Jubjub point encodings. In Sapling Spend descriptions [#protocol-spenddesc]_: - - the :math:`\underline{R}` component (i.e. the first :math:`32` bytes) of the - :math:`\mathtt{spendAuthSig}` RedDSA signature. + - the $\underline{R}$ component (i.e. the first $32$ bytes) of the + $\mathtt{spendAuthSig}$ RedDSA signature. In transactions [#protocol-txnencoding]_: - - the :math:`\underline{R}` component (i.e. the first :math:`32` bytes) of the - :math:`\mathtt{bindingSigSapling}` RedDSA signature. + - the $\underline{R}$ component (i.e. the first $32$ bytes) of the + $\mathtt{bindingSigSapling}$ RedDSA signature. -In the plaintext obtained by decrypting the :math:`\mathsf{C^{out}}` field of a +In the plaintext obtained by decrypting the $\mathsf{C^{out}}$ field of a Sapling transmitted note ciphertext [#protocol-decryptovk]_: - - :math:`\mathsf{pk}\star_{\mathsf{d}}`. + - $\mathsf{pk}\star_{\mathsf{d}}$. -(This affects decryption of :math:`\mathsf{C^{out}}` in all cases, but is +(This affects decryption of $\mathsf{C^{out}}$ in all cases, but is consensus-critical only in the case of a shielded coinbase output. [#protocol-txnencoding]_) @@ -121,13 +121,13 @@ existing consensus rules. In Sapling Spend descriptions: - - :math:`\mathtt{cv}` - - :math:`\mathtt{rk}` + - $\mathtt{cv}$ + - $\mathtt{rk}$ In Sapling Output descriptions [#protocol-outputdesc]_: - - :math:`\mathtt{cv}` - - :math:`\mathtt{ephemeralKey}`. + - $\mathtt{cv}$ + - $\mathtt{ephemeralKey}$. These fields cannot by consensus contain small-order points. All of the points with non-canonical encodings are small-order. @@ -140,19 +140,19 @@ transaction IDs. In addition, Sapling addresses and full viewing keys MUST be considered invalid when imported if they contain non-canonical Jubjub point encodings, or encodings of points -that are not in the prime-order subgroup :math:`\mathbb{J}^{(r)}`. These requirements +that are not in the prime-order subgroup $\mathbb{J}^{(r)}$. These requirements \MAY be enforced in advance of NU5 activation. In Sapling addresses [#protocol-saplingpaymentaddrencoding]_: - - the encoding of :math:`\mathsf{pk_d}`. + - the encoding of $\mathsf{pk_d}$. In Sapling full viewing keys [#protocol-saplingfullviewingkeyencoding]_ and extended full viewing keys [#zip-0032-extfvk]_: - - the encoding of :math:`\mathsf{ak}`. + - the encoding of $\mathsf{ak}$. -(:math:`\mathsf{ak}` also MUST NOT encode the zero point :math:`\mathcal{O}_{\mathbb{J}}`.) +($\mathsf{ak}$ also MUST NOT encode the zero point $\mathcal{O}_{\mathbb{J}}$.) The above is intended to be a complete list of the places where compressed encodings of Jubjub points occur in the Zcash consensus protocol and in plaintext, address, or @@ -180,16 +180,16 @@ In Sapling, we are motivated instead to reject these non-canonical points: The necessary checks are very simple and do not require cryptographic operations, therefore the performance impact will be negligible. -The public inputs of Jubjub points to the Spend circuit (:math:`\mathsf{rk}` and -:math:`\mathsf{cv^{old}}`) and Output circuit (:math:`\mathsf{cv^{new}}` and -:math:`\mathsf{epk}`) are not affected because they are represented in affine +The public inputs of Jubjub points to the Spend circuit ($\!\mathsf{rk}$ and +$\mathsf{cv^{old}}$) and Output circuit ($\!\mathsf{cv^{new}}$ and +$\mathsf{epk}$) are not affected because they are represented in affine coordinates as elements of the correct field -(:math:`\mathbb{F}_{r_\mathbb{S}} = \mathbb{F}_{q_\mathbb{J}}`), +($\!\mathbb{F}_{r_\mathbb{S}} = \mathbb{F}_{q_\mathbb{J}}$), and so no issue of encoding canonicity arises. -Encodings of elliptic curve points on Curve25519, BN-254 :math:`\mathbb{G}_1`, -BN-254 :math:`\mathbb{G}_2`, BLS12-381 :math:`\mathbb{G}_1`, and -BLS12-381 :math:`\mathbb{G}_2` are not affected. +Encodings of elliptic curve points on Curve25519, BN-254 $\mathbb{G}_1$, +BN-254 $\mathbb{G}_2$, BLS12-381 $\mathbb{G}_1$, and +BLS12-381 $\mathbb{G}_2$ are not affected. Encodings of elliptic curve points on the Pallas and Vesta curves in the NU5 proposal [#protocol-pallasandvesta]_ are also not affected. diff --git a/zips/zip-0221.rst b/zips/zip-0221.rst index 74b42e15e..ab8d61a38 100644 --- a/zips/zip-0221.rst +++ b/zips/zip-0221.rst @@ -26,12 +26,12 @@ interpreted as described in ZIP 200. [#zip-0200]_ receive payments, but does not store or validate a copy of the block chain. *High probability* - An event occurs with high probability if it occurs with probability :math:`1-O(1/2^\lambda)`, - where :math:`\lambda` is a security parameter. + An event occurs with high probability if it occurs with probability $1-O(1/2^\lambda)$, + where $\lambda$ is a security parameter. *Negligible probability* - An event occurs with negligible probability if it occurs with probability :math:`O(1/2^\lambda)`, - where :math:`\lambda` is the security parameter. + An event occurs with negligible probability if it occurs with probability $O(1/2^\lambda)$, + where $\lambda$ is the security parameter. *Merkle mountain range (MMR)* A Merkle mountain range (MMR) is a binary hash tree that allows for efficient appends of @@ -53,9 +53,9 @@ Background An MMR is a Merkle tree which allows for efficient appends, proofs, and verifications. Informally, appending data to an MMR consists of creating a new leaf and then iteratively -merging neighboring subtrees with the same size. This takes at most :math:`\log(n)` operations +merging neighboring subtrees with the same size. This takes at most $\log(n)$ operations and only requires knowledge of the previous subtree roots, of which there are fewer than -:math:`\log(n)`. +$\log(n)$. (example adapted from [#mimblewimble]_) To illustrate this, consider a list of 11 leaves. We first construct the biggest perfect @@ -96,9 +96,9 @@ and represent this numbering in a flat list: | Altitude | 0 | 0 | 1 | 0 | 0 | 1 | 2 | 0 | 0 | 1 | 0 | 0 | 1 | 2 | 3 | 0 | 0 | 1 | 0 | +----------+----+----+----+----+----+----+----+----+----+----+----+----+----+----+----+----+----+----+----+ -Let :math:`h` be the altitude of a given node. We can easily jump to the node's right -sibling (if it has one) by adding :math:`2^{h+1} - 1` to its position, and its left child -(if it has one) by subtracting :math:`2^h`. This allows us to efficiently find the subtree +Let $h$ be the altitude of a given node. We can easily jump to the node's right +sibling (if it has one) by adding $2^{h+1} - 1$ to its position, and its left child +(if it has one) by subtracting $2^h$. This allows us to efficiently find the subtree roots ("peaks") of the mountains. Once we have the positions of the mountain peaks, we "bag" them using the following @@ -144,14 +144,14 @@ MMR proofs are used in the FlyClient protocol [#FlyClient]_, to reduce the proof needed for light clients to verify: - the validity of a block chain received from a full node, and -- the inclusion of a block :math:`B` in that chain, and +- the inclusion of a block $B$ in that chain, and - certain metadata of any block or range of blocks in that chain. The protocol requires that an MMR that commits to the inclusion of all blocks since the -preceding network upgrade :math:`(B_x, \ldots, B_{n-1})` is formed for each block :math:`B_n`. -The root :math:`M_n` of the MMR MUST be included in the header of :math:`B_n`. +preceding network upgrade $(B_x, \ldots, B_{n-1})$ is formed for each block $B_n$. +The root $M_n$ of the MMR MUST be included in the header of $B_n$. -(:math:`x` is the activation height of the preceding network upgrade.) +($\!x$ is the activation height of the preceding network upgrade.) FlyClient reduces the number of block headers needed for light client verification of a valid chain, from linear (as in the current reference protocol) to logarithmic in @@ -169,14 +169,14 @@ devices. Specification ============= -For a block :math:`B_n` at height :math:`n > 0` in a given block chain, define the -"preceding network upgrade height" :math:`x` of :math:`B_n` to be the last network -upgrade activation height in the chain that is less than :math:`n`. (For this definition, -block height :math:`0` is considered to be the height of a network upgrade activation. +For a block $B_n$ at height $n > 0$ in a given block chain, define the +"preceding network upgrade height" $x$ of $B_n$ to be the last network +upgrade activation height in the chain that is less than $n$. (For this definition, +block height $0$ is considered to be the height of a network upgrade activation. The preceding network upgrade height of the genesis block is undefined.) -The leaves of the MMR at block :math:`B_n` are hash commitments to the header data -and metadata of each previous block :math:`B_x, \ldots, B_{n-1}`, where :math:`x` +The leaves of the MMR at block $B_n$ are hash commitments to the header data +and metadata of each previous block $B_x, \ldots, B_{n-1}$, where $x$ is defined as above. We extend the standard MMR to allow metadata to propagate upwards through the tree by either summing the metadata of both children, or inheriting the metadata of a specific child as necessary. This allows us to create efficient proofs @@ -202,8 +202,8 @@ Each MMR node is defined as follows: * This hash is encoded in internal byte order, and does NOT use the BLAKE2b-256 personalization string described above. * For clarity, in a given consensus branch, the ``hashSubtreeCommitment`` field - of leaf :math:`n-1` is *precisely equal* to the ``hashPrevBlock`` field in the - header of the block at height :math:`x+n`, where :math:`x` is the network + of leaf $n-1$ is *precisely equal* to the ``hashPrevBlock`` field in the + header of the block at height $x+n$, where $x$ is the network upgrade activation height of that consensus branch. Internal or root node @@ -285,16 +285,16 @@ Each MMR node is defined as follows: Leaf node The protocol-defined work of the block: - :math:`\mathsf{floor}(2^{256} / (\mathsf{ToTarget}(\mathsf{nBits}) + 1))`. [#protocol-workdef]_ + $\mathsf{floor}(2^{256} / (\mathsf{ToTarget}(\mathsf{nBits}) + 1))$. [#protocol-workdef]_ Internal or root node The sum of the ``nSubTreeTotalWork`` fields of both children. - Computations modulo :math:`2^{256}` are fine here; cumulative chain work is similarly - assumed elsewhere in the Zcash ecosystem to be at most :math:`2^{256}` (as inherited + Computations modulo $2^{256}$ are fine here; cumulative chain work is similarly + assumed elsewhere in the Zcash ecosystem to be at most $2^{256}$ (as inherited from Bitcoin). The computed work factors are, on average, equal to the computational efforts involved in the creation of the corresponding blocks, and an aggregate effort - of :math:`2^{256}` or more is infeasible in practice. + of $2^{256}$ or more is infeasible in practice. Serialized as ``uint256``. @@ -480,8 +480,8 @@ Tree nodes and hashing (pseudocode) Incremental push and pop (pseudocode) ------------------------------------- -With each new block :math:`B_n`, we append a new MMR leaf node corresponding to block -:math:`B_{n-1}`. The ``append`` operation is detailed below in pseudocode (adapted from +With each new block $B_n$, we append a new MMR leaf node corresponding to block +$B_{n-1}$. The ``append`` operation is detailed below in pseudocode (adapted from [#FlyClient]_): .. code-block:: python @@ -541,7 +541,7 @@ With each new block :math:`B_n`, we append a new MMR leaf node corresponding to return bag_peaks(merged[::-1]) In case of a block reorg, we have to delete the latest (i.e. rightmost) MMR leaf nodes, up -to the reorg length. This operation is :math:`O(\log(k))` where :math:`k` is the number of leaves +to the reorg length. This operation is $O(\log(k))$ where $k$ is the number of leaves in the right subtree of the MMR root. .. code-block:: python @@ -588,8 +588,8 @@ in [#zip-0244]_.) Prior to activation of the network upgrade that deploys this ZIP, this existing consensus rule on block headers (adjusted for the renamed field) is enforced: [#protocol-blockheader]_ - [Sapling onward] ``hashLightClientRoot`` MUST be :math:`\mathsf{LEBS2OSP}_{256}(\mathsf{rt})` - where :math:`\mathsf{rt}` is the root of the Sapling note commitment tree for the final + [Sapling onward] ``hashLightClientRoot`` MUST be $\mathsf{LEBS2OSP}_{256}(\mathsf{rt})$ + where $\mathsf{rt}$ is the root of the Sapling note commitment tree for the final Sapling tree state of this block. In the block that activates this ZIP, ``hashLightClientRoot`` MUST be set to all zero bytes. @@ -672,7 +672,7 @@ inclusion in a future upgrade. * This commitment serves the same purpose as ``hashFinalSaplingRoot`` in current Sapling semantics. - * However, because the MMR tree commits to blocks :math:`B_x \ldots B_{n-1}`, the latest + * However, because the MMR tree commits to blocks $B_x \ldots B_{n-1}$, the latest commitment will describe the final treestate of the previous block, rather than the current block. * Concretely: block 500 currently commits to the final treestate of block 500 in its @@ -744,7 +744,7 @@ implementation that would join these commitments, but it is clearly not appropri Zcash as it exists. The calculation of ``hashChainHistoryRoot`` is not well-defined for the genesis block, -since then :math:`n = 0` and there is no block :math:`B_{n-1}`. Also, in the case of +since then $n = 0$ and there is no block $B_{n-1}$. Also, in the case of chains that activate this ZIP after genesis (including Zcash Mainnet and Testnet), the ``hashChainHistoryRoot`` of the activation block would commit to the whole previous epoch if a special case were not made. It would be impractical to calculate this commitment all diff --git a/zips/zip-0224.rst b/zips/zip-0224.rst index b3b75fa32..450b8118a 100644 --- a/zips/zip-0224.rst +++ b/zips/zip-0224.rst @@ -92,7 +92,7 @@ embedded curve Jubjub: - Vesta is used as the "circuit curve"; its scalar field (being the base field of Pallas) is the "word" type over which the circuit is implemented (c/f BLS12-381). -We use the "simplified SWU" algorithm to define an infallible :math:`\mathsf{GroupHash}`, +We use the "simplified SWU" algorithm to define an infallible $\mathsf{GroupHash}$, instead of the fallible BLAKE2s-based mechanism used for Sapling. It is intended to follow (version 10 of) the IETF hash-to-curve Internet Draft [#ietf-hash-to-curve]_ (but the protocol specification takes precedence in the case of any discrepancy). @@ -102,7 +102,7 @@ of the cycle (Pallas being an embedded curve of Vesta); the full cycle is expect leveraged by future protocol updates. - Curve specifications: [#protocol-pallasandvesta]_ -- :math:`\mathsf{GroupHash}`: [#protocol-concretegrouphashpallasandvesta]_ +- $\mathsf{GroupHash}$: [#protocol-concretegrouphashpallasandvesta]_ - Supporting evidence: [#pasta-evidence]_ Proving system @@ -153,11 +153,11 @@ Keys and addresses Orchard keys and payment addresses are structurally similar to Sapling, with the following changes: -- The proof authorizing key is removed, and :math:`\mathsf{nk}` is now a field element. -- :math:`\mathsf{ivk}` is computed as a Sinsemilla commitment instead of a BLAKE2s output. - There is an additional :math:`\mathsf{rivk}` component of the full viewing key that acts +- The proof authorizing key is removed, and $\mathsf{nk}$ is now a field element. +- $\mathsf{ivk}$ is computed as a Sinsemilla commitment instead of a BLAKE2s output. + There is an additional $\mathsf{rivk}$ component of the full viewing key that acts as the randomizer for this commitment. -- :math:`\mathsf{ovk}` is derived from :math:`\mathsf{fvk}`, instead of being a component +- $\mathsf{ovk}$ is derived from $\mathsf{fvk}$, instead of being a component of the spending key. - All diversifiers now result in valid payment addresses. @@ -180,9 +180,9 @@ derivation mechanism (similar to Sprout). Notes ----- -Orchard notes have the structure :math:`(addr, v, \rho, \psi, \mathsf{rcm}).` :math:`\rho` +Orchard notes have the structure $(addr, v, \text{ρ}, \text{φ}, \mathsf{rcm}).$ $\text{ρ}$ is set to the nullifier of the spent note in the same action, which ensures it is unique. -:math:`\psi` and :math:`\mathsf{rcm}` are derived from a random seed (as with Sapling +$\text{φ}$ and $\mathsf{rcm}$ are derived from a random seed (as with Sapling after ZIP 212 [#zip-0212]_). - Orchard notes: [#protocol-notes]_ @@ -192,9 +192,9 @@ Nullifiers Nullifiers for Orchard notes are computed as: -:math:`\mathsf{nf} = [F_{\mathsf{nk}}(\rho) + \psi \pmod{p}] \mathcal{G} + \mathsf{cm}` +$\mathsf{nf} = [F_{\mathsf{nk}}(\text{ρ}) + \text{φ} \pmod{p}] \,\mathcal{G} + \mathsf{cm}$ -where :math:`F` is instantiated with Poseidon, and :math:`\mathcal{G}` is a fixed +where $F$ is instantiated with Poseidon, and $\mathcal{G}$ is a fixed independent base. - Poseidon: [#protocol-poseidonhash]_ @@ -234,14 +234,14 @@ Security and Privacy Considerations This ZIP defines a new shielded pool. As with Sapling, the Orchard protocol only supports spending Orchard notes, and moving ZEC into or out of the Orchard pool happens via the -:math:`\mathsf{valueBalanceOrchard}` transaction field. This has the following +$\mathsf{valueBalanceOrchard}$ transaction field. This has the following considerations: - The Orchard pool forms a separate anonymity set from the Sprout and Sapling pools. The new pool will start with zero notes (as Sapling did at its deployment), but transactions within Orchard will increase the size of the anonymity set more rapidly than Sapling, due to the arity-hiding nature of Orchard actions. -- The "transparent turnstile" created by the :math:`\mathsf{valueBalanceOrchard}` field, +- The "transparent turnstile" created by the $\mathsf{valueBalanceOrchard}$ field, combined with the consensus checks that each pool's balance cannot be negative, together enforce that any potential counterfeiting bugs in the Orchard protocol or implementation are contained within the Orchard pool, and similarly any potential counterfeiting bugs diff --git a/zips/zip-0225.rst b/zips/zip-0225.rst index a4bf7ce9e..c0b84b6c8 100644 --- a/zips/zip-0225.rst +++ b/zips/zip-0225.rst @@ -145,7 +145,7 @@ Transaction Format |``1`` |``flagsOrchard`` |``byte`` |An 8-bit value representing a set of flags. Ordered from LSB to MSB: | | | | | * ``enableSpendsOrchard`` | | | | | * ``enableOutputsOrchard`` | -| | | | * The remaining bits are set to ``0``. | +| | | | * The remaining bits are set to :math:`0\!`. | +-----------------------------+--------------------------+----------------------------------------+---------------------------------------------------------------------+ |``8`` |``valueBalanceOrchard`` |``int64`` |The net value of Orchard spends minus outputs. | +-----------------------------+--------------------------+----------------------------------------+---------------------------------------------------------------------+ @@ -153,7 +153,7 @@ Transaction Format | | | |height in the past. | +-----------------------------+--------------------------+----------------------------------------+---------------------------------------------------------------------+ |``varies`` |``sizeProofsOrchard`` |``compactSize`` |Length in bytes of ``proofsOrchard``. Value is | -| | | |:math:`2720 + 2272 \cdot \mathtt{nActionsOrchard}`. | +| | | |:math:`2720 + 2272 \cdot \mathtt{nActionsOrchard}\!`. | +-----------------------------+--------------------------+----------------------------------------+---------------------------------------------------------------------+ |``sizeProofsOrchard`` |``proofsOrchard`` |``byte[sizeProofsOrchard]`` |Encoding of aggregated zk-SNARK proofs for Orchard Actions. | +-----------------------------+--------------------------+----------------------------------------+---------------------------------------------------------------------+ @@ -163,15 +163,15 @@ Transaction Format +-----------------------------+--------------------------+----------------------------------------+---------------------------------------------------------------------+ * The fields ``valueBalanceSapling`` and ``bindingSigSapling`` are present if and only if - :math:`\mathtt{nSpendsSapling} + \mathtt{nOutputsSapling} > 0`. If ``valueBalanceSapling`` - is not present, then :math:`\mathsf{v^{balanceSapling}}`` is defined to be 0. + $\mathtt{nSpendsSapling} + \mathtt{nOutputsSapling} > 0$. If ``valueBalanceSapling`` + is not present, then $\mathsf{v^{balanceSapling}}$ is defined to be $0$. -* The field ``anchorSapling`` is present if and only if :math:`\mathtt{nSpendsSapling} > 0`. +* The field ``anchorSapling`` is present if and only if $\mathtt{nSpendsSapling} > 0$. * The fields ``flagsOrchard``, ``valueBalanceOrchard``, ``anchorOrchard``, ``sizeProofsOrchard``, ``proofsOrchard``, and ``bindingSigOrchard`` are present if and - only if :math:`\mathtt{nActionsOrchard} > 0`. If ``valueBalanceOrchard`` is not present, - then :math:`\mathsf{v^{balanceOrchard}}` is defined to be 0. + only if $\mathtt{nActionsOrchard} > 0$. If ``valueBalanceOrchard`` is not present, + then $\mathsf{v^{balanceOrchard}}$ is defined to be $0$. * The elements of ``vSpendProofsSapling`` and ``vSpendAuthSigsSapling`` have a 1:1 correspondence to the elements of ``vSpendsSapling`` and MUST be ordered such that the @@ -187,7 +187,7 @@ Transaction Format ``vActionsOrchard`` and MUST be ordered such that the proof or signature at a given index corresponds to the ``OrchardAction`` at the same index. -* For coinbase transactions, the ``enableSpendsOrchard`` bit MUST be set to ``0``. +* For coinbase transactions, the ``enableSpendsOrchard`` bit MUST be set to $0$. The encodings of ``tx_in``, and ``tx_out`` are as in a version 4 transaction (i.e. unchanged from Canopy). The encodings of ``SpendDescriptionV5``, ``OutputDescriptionV5`` @@ -216,21 +216,20 @@ and Consensus’ of the Zcash Protocol Specification [#protocol-spenddesc]_. Sapling Output Description (``OutputDescriptionV5``) ---------------------------------------------------- -+-----------------------------+--------------------------+--------------------------------------+------------------------------------------------------------+ -| Bytes | Name | Data Type | Description | -+=============================+==========================+======================================+============================================================+ -|``32`` |``cv`` |``byte[32]`` |A value commitment to the net value of the output note. | -+-----------------------------+--------------------------+--------------------------------------+------------------------------------------------------------+ -|``32`` |``cmu`` |``byte[32]`` |The u-coordinate of the note commitment for the output note.| -+-----------------------------+--------------------------+--------------------------------------+------------------------------------------------------------+ -|``32`` |``ephemeralKey`` |``byte[32]`` |An encoding of an ephemeral Jubjub public key. | -+-----------------------------+--------------------------+--------------------------------------+------------------------------------------------------------+ -|``580`` |``encCiphertext`` |``byte[580]`` |The encrypted contents of the note plaintext. | -+-----------------------------+--------------------------+--------------------------------------+------------------------------------------------------------+ -|``80`` |``outCiphertext`` |``byte[80]`` |The encrypted contents of the byte string created by | -| | | |concatenation of the transmission key with the ephemeral | -| | | |secret key. | -+-----------------------------+--------------------------+--------------------------------------+------------------------------------------------------------+ ++-----------------------------+--------------------------+--------------------------------------+----------------------------------------------------------------------+ +| Bytes | Name | Data Type | Description | ++=============================+==========================+======================================+======================================================================+ +|``32`` |``cv`` |``byte[32]`` |A value commitment to the net value of the output note. | ++-----------------------------+--------------------------+--------------------------------------+----------------------------------------------------------------------+ +|``32`` |``cmu`` |``byte[32]`` |The :math:`u\!`-coordinate of the note commitment for the output note.| ++-----------------------------+--------------------------+--------------------------------------+----------------------------------------------------------------------+ +|``32`` |``ephemeralKey`` |``byte[32]`` |An encoding of an ephemeral Jubjub public key. | ++-----------------------------+--------------------------+--------------------------------------+----------------------------------------------------------------------+ +|``580`` |``encCiphertext`` |``byte[580]`` |The encrypted contents of the note plaintext. | ++-----------------------------+--------------------------+--------------------------------------+----------------------------------------------------------------------+ +|``80`` |``outCiphertext`` |``byte[80]`` |The encrypted contents of the byte string created by concatenation of | +| | | |the transmission key with the ephemeral secret key. | ++-----------------------------+--------------------------+--------------------------------------+----------------------------------------------------------------------+ The encodings of each of these elements are defined in §7.4 ‘Output Description Encoding and Consensus’ of the Zcash Protocol Specification [#protocol-outputdesc]_. @@ -238,27 +237,26 @@ and Consensus’ of the Zcash Protocol Specification [#protocol-outputdesc]_. Orchard Action Description (``OrchardAction``) ---------------------------------------------- -+-----------------------------+--------------------------+--------------------------------------+------------------------------------------------------------+ -| Bytes | Name | Data Type | Description | -+=============================+==========================+======================================+============================================================+ -|``32`` |``cv`` |``byte[32]`` |A value commitment to the net value of the input note minus | -| | | |the output note. | -+-----------------------------+--------------------------+--------------------------------------+------------------------------------------------------------+ -|``32`` |``nullifier`` |``byte[32]`` |The nullifier of the input note. | -+-----------------------------+--------------------------+--------------------------------------+------------------------------------------------------------+ -|``32`` |``rk`` |``byte[32]`` |The randomized validating key for the element of | -| | | |spendAuthSigsOrchard corresponding to this Action. | -+-----------------------------+--------------------------+--------------------------------------+------------------------------------------------------------+ -|``32`` |``cmx`` |``byte[32]`` |The x-coordinate of the note commitment for the output note.| -+-----------------------------+--------------------------+--------------------------------------+------------------------------------------------------------+ -|``32`` |``ephemeralKey`` |``byte[32]`` |An encoding of an ephemeral Pallas public key | -+-----------------------------+--------------------------+--------------------------------------+------------------------------------------------------------+ -|``580`` |``encCiphertext`` |``byte[580]`` |The encrypted contents of the note plaintext. | -+-----------------------------+--------------------------+--------------------------------------+------------------------------------------------------------+ -|``80`` |``outCiphertext`` |``byte[80]`` |The encrypted contents of the byte string created by | -| | | |concatenation of the transmission key with the ephemeral | -| | | |secret key. | -+-----------------------------+--------------------------+--------------------------------------+------------------------------------------------------------+ ++-----------------------------+--------------------------+--------------------------------------+----------------------------------------------------------------------+ +| Bytes | Name | Data Type | Description | ++=============================+==========================+======================================+======================================================================+ +|``32`` |``cv`` |``byte[32]`` |A value commitment to the net value of the input note minus the | +| | | |output note. | ++-----------------------------+--------------------------+--------------------------------------+----------------------------------------------------------------------+ +|``32`` |``nullifier`` |``byte[32]`` |The nullifier of the input note. | ++-----------------------------+--------------------------+--------------------------------------+----------------------------------------------------------------------+ +|``32`` |``rk`` |``byte[32]`` |The randomized validating key for the element of | +| | | |spendAuthSigsOrchard corresponding to this Action. | ++-----------------------------+--------------------------+--------------------------------------+----------------------------------------------------------------------+ +|``32`` |``cmx`` |``byte[32]`` |The :math:`x\!`-coordinate of the note commitment for the output note.| ++-----------------------------+--------------------------+--------------------------------------+----------------------------------------------------------------------+ +|``32`` |``ephemeralKey`` |``byte[32]`` |An encoding of an ephemeral Pallas public key. | ++-----------------------------+--------------------------+--------------------------------------+----------------------------------------------------------------------+ +|``580`` |``encCiphertext`` |``byte[580]`` |The encrypted contents of the note plaintext. | ++-----------------------------+--------------------------+--------------------------------------+----------------------------------------------------------------------+ +|``80`` |``outCiphertext`` |``byte[80]`` |The encrypted contents of the byte string created by concatenation of | +| | | |the transmission key with the ephemeral secret key. | ++-----------------------------+--------------------------+--------------------------------------+----------------------------------------------------------------------+ The encodings of each of these elements are defined in §7.5 ‘Action Description Encoding and Consensus’ of the Zcash Protocol Specification [#protocol-actiondesc]_. @@ -292,23 +290,23 @@ ZIP 222 [#zip-0222]_ extension or by other means not yet determined. The original definitions for the transaction fields that have been removed are: -+-----------------------------+--------------------------+----------------------------------------+---------------------------------------------------------------------+ -| **Sprout Transaction Fields** | -+-----------------------------+--------------------------+----------------------------------------+---------------------------------------------------------------------+ -|``varies`` |``nJoinSplit`` |``compactSize`` |The number of JoinSplit descriptions in ``vJoinSplit``. | -+-----------------------------+--------------------------+----------------------------------------+---------------------------------------------------------------------+ -|``1698 * nJoinSplit`` |``vJoinSplit`` |``JSDescriptionGroth16[nJoinSplit]`` |A sequence of JoinSplit descrptions using Groth16 proofs, | -| | | |encoded per §7.2 ‘JoinSplit Description Encoding and Consensus’. | -+-----------------------------+--------------------------+----------------------------------------+---------------------------------------------------------------------+ -|``32`` |``joinSplitPubKey`` |``byte[32]`` |An encoding of a JoinSplitSig public validating key. | -+-----------------------------+--------------------------+----------------------------------------+---------------------------------------------------------------------+ -|``64`` |``joinSplitSig`` |``byte[64]`` |A signature on a prefix of the transaction encoding, | -| | | |to be verfied using joinSplitPubKey as specified in §4.11 | -| | | |‘Non-malleability (Sprout)’. | -+-----------------------------+--------------------------+----------------------------------------+---------------------------------------------------------------------+ ++-----------------------------+--------------------------+--------------------------------------+----------------------------------------------------------------------+ +| **Sprout Transaction Fields** | ++-----------------------------+--------------------------+--------------------------------------+----------------------------------------------------------------------+ +|``varies`` |``nJoinSplit`` |``compactSize`` |The number of JoinSplit descriptions in ``vJoinSplit``. | ++-----------------------------+--------------------------+--------------------------------------+----------------------------------------------------------------------+ +|``1698 * nJoinSplit`` |``vJoinSplit`` |``JSDescriptionGroth16[nJoinSplit]`` |A sequence of JoinSplit descrptions using Groth16 proofs, | +| | | |encoded per §7.2 ‘JoinSplit Description Encoding and Consensus’. | ++-----------------------------+--------------------------+--------------------------------------+----------------------------------------------------------------------+ +|``32`` |``joinSplitPubKey`` |``byte[32]`` |An encoding of a JoinSplitSig public validating key. | ++-----------------------------+--------------------------+--------------------------------------+----------------------------------------------------------------------+ +|``64`` |``joinSplitSig`` |``byte[64]`` |A signature on a prefix of the transaction encoding, | +| | | |to be verfied using joinSplitPubKey as specified in §4.11 | +| | | |‘Non-malleability (Sprout)’. | ++-----------------------------+--------------------------+--------------------------------------+----------------------------------------------------------------------+ * The ``joinSplitPubKey`` and ``joinSplitSig`` fields were specified to be - present if and only if :math:`\mathtt{nJoinSplit} > 0`. + present if and only if $\mathtt{nJoinSplit} > 0$. Reference implementation diff --git a/zips/zip-0226.rst b/zips/zip-0226.rst index dc656f234..f04d85663 100644 --- a/zips/zip-0226.rst +++ b/zips/zip-0226.rst @@ -31,7 +31,7 @@ The terms "Asset", "Custom Asset" and "Wrapped Asset" in this document are to be We define the following additional terms: -- Split Input: an Action input used to ensure that the output note of that Action is of a validly issued :math:`\mathsf{AssetBase}` (see [#zip-0227-assetidentifier]_) when there is no corresponding real input note, in situations where the number of outputs are larger than the number of inputs. See formal definition in `Split Notes`_. +- Split Input: an Action input used to ensure that the output note of that Action is of a validly issued $\mathsf{AssetBase}$ (see [#zip-0227-assetidentifier]_) when there is no corresponding real input note, in situations where the number of outputs are larger than the number of inputs. See formal definition in `Split Notes`_. - Split Action: an Action that contains a Split Input. Abstract @@ -48,23 +48,23 @@ This ZIP builds on the issuance mechanism introduced in ZIP 227 [#zip-0227]_. Overview ======== -In order to be able to represent different Assets, we need to define a data field that uniquely represents the Asset in question, which we call the Asset Identifier :math:`\mathsf{AssetId}\!`. -This Asset Identifier maps to an Asset Base :math:`\mathsf{AssetBase}` that is stored in OrchardZSA notes. +In order to be able to represent different Assets, we need to define a data field that uniquely represents the Asset in question, which we call the Asset Identifier $\mathsf{AssetId}$. +This Asset Identifier maps to an Asset Base $\mathsf{AssetBase}$ that is stored in OrchardZSA notes. These terms are formally defined in ZIP 227 [#zip-0227]_. -The Asset Identifier (via means of the Asset Digest and Asset Base) will be used to enforce that the balance of an Action Description [#protocol-actions]_ [#protocol-actionencodingandconsensus]_ is preserved across Assets (see the Orchard Binding Signature [#protocol-orchardbalance]_), and by extension the balance of an Orchard transaction. That is, the sum of all the :math:`\mathsf{value^{net}}` from each Action Description, computed as :math:`\mathsf{value^{old}} - \mathsf{value^{new}}\!`, must be balanced **only with respect to the same Asset Identifier**. This is especially important since we will allow different Action Descriptions to transfer notes of different Asset Identifiers, where the overall balance is checked without revealing which (or how many distinct) Assets are being transferred. +The Asset Identifier (via means of the Asset Digest and Asset Base) will be used to enforce that the balance of an Action Description [#protocol-actions]_ [#protocol-actionencodingandconsensus]_ is preserved across Assets (see the Orchard Binding Signature [#protocol-orchardbalance]_), and by extension the balance of an Orchard transaction. That is, the sum of all the $\mathsf{value^{net}}$ from each Action Description, computed as $\mathsf{value^{old}} - \mathsf{value^{new}}$, must be balanced **only with respect to the same Asset Identifier**. This is especially important since we will allow different Action Descriptions to transfer notes of different Asset Identifiers, where the overall balance is checked without revealing which (or how many distinct) Assets are being transferred. -As was initially proposed by Jack Grigg and Daira-Emma Hopwood [#initial-zsa-issue]_ [#generalized-value-commitments]_, we propose to make this happen by changing the value base point, :math:`\mathcal{V}^{\mathsf{Orchard}}\!`, in the Homomorphic Pedersen Commitment that derives the value commitment, :math:`\mathsf{cv^{net}}\!`, of the *net value* in an Orchard Action. +As was initially proposed by Jack Grigg and Daira-Emma Hopwood [#initial-zsa-issue]_ [#generalized-value-commitments]_, we propose to make this happen by changing the value base point, $\mathcal{V}^{\mathsf{Orchard}}$, in the Homomorphic Pedersen Commitment that derives the value commitment, $\mathsf{cv^{net}}$, of the *net value* in an Orchard Action. Because in a single transaction all value commitments are balanced, there must be as many different value base points as there are Asset Identifiers for a given shielded protocol used in a transaction. We propose to make the Asset Base an auxiliary input to the proof for each Action statement [#protocol-actionstatement]_, represented already as a point on the Pallas curve. The circuit then should check that the same Asset Base is used in the old note commitment and the new note commitment [#protocol-concretesinsemillacommit]_, **and** as the base point in the value commitment [#protocol-concretehomomorphiccommit]_. This ensures (1) that the input and output notes are of the same Asset Base, and (2) that only Actions with the same Asset Base will balance out in the Orchard binding signature. -In order to ensure the security of the transfers, and as we will explain below, we are redefining input dummy notes [#protocol-orcharddummynotes]_ for Custom Assets, as we need to enforce that the :math:`\mathsf{AssetBase}` of the output note of that Split Action is the output of a valid :math:`\mathsf{ZSAValueBase}` computation defined in ZIP 227 [#zip-0227]_. +In order to ensure the security of the transfers, and as we will explain below, we are redefining input dummy notes [#protocol-orcharddummynotes]_ for Custom Assets, as we need to enforce that the $\mathsf{AssetBase}$ of the output note of that Split Action is the output of a valid $\mathsf{ZSAValueBase}$ computation defined in ZIP 227 [#zip-0227]_. -We include the ability to pause the ZSA functionality, via a :math:`\mathsf{enableZSA}` boolean flag. +We include the ability to pause the ZSA functionality, via a $\mathsf{enableZSA}$ boolean flag. When this flag is set to false, the proof will fail for any non-native Asset, making it impossible to perform transactions involving Custom Assets. -When this flag is set to true, the circuit will allow transactions involving Custom Assets subject to the values of the :math:`\mathsf{enableSpendsOrchard}` and :math:`\mathsf{enableOutputsOrchard}` flags, similar to the vanilla Orchard setting. +When this flag is set to true, the circuit will allow transactions involving Custom Assets subject to the values of the $\mathsf{enableSpendsOrchard}$ and $\mathsf{enableOutputsOrchard}$ flags, similar to the vanilla Orchard setting. -Finally, in this ZIP we also describe the *burn* mechanism, which is a direct extension of the transfer mechanism. The burn process uses a similar mechanism to what is used in Orchard to unshield ZEC, by using the :math:`\mathsf{valueBalance}` of the Asset in question. Burning Assets is useful for many purposes, including bridging of Wrapped Assets and removing supply of Assets. +Finally, in this ZIP we also describe the *burn* mechanism, which is a direct extension of the transfer mechanism. The burn process uses a similar mechanism to what is used in Orchard to unshield ZEC, by using the $\mathsf{valueBalance}$ of the Asset in question. Burning Assets is useful for many purposes, including bridging of Wrapped Assets and removing supply of Assets. Specification ============= @@ -74,9 +74,9 @@ Most of the protocol is kept the same as the Orchard protocol released with NU5, Asset Identifiers ----------------- -For every new Asset, there MUST be a new and unique Asset Identifier. Every Asset is defined by an *Asset description*, :math:`\mathsf{asset\_desc}\!`, which is a global byte string (scoped across all future versions of Zcash). From this Asset description and the issuance validating key of the issuer, the specific Asset Identifier, :math:`\mathsf{AssetId}\!`, the Asset Digest, and the Asset Base (:math:`\mathsf{AssetBase}\!`) are derived as defined in ZIP 227 [#zip-0227]_. +For every new Asset, there MUST be a new and unique Asset Identifier. Every Asset is defined by an *Asset description*, $\mathsf{asset\_desc}$, which is a global byte string (scoped across all future versions of Zcash). From this Asset description and the issuance validating key of the issuer, the specific Asset Identifier, $\mathsf{AssetId}$, the Asset Digest, and the Asset Base ($\!\mathsf{AssetBase}$) are derived as defined in ZIP 227 [#zip-0227]_. -This Asset Base will be the base point of the value commitment for the specific Custom Asset. Note that the Asset Base of the ZEC Asset will be kept as the original value base point, :math:`\mathcal{V}^{\mathsf{Orchard}}\!`. +This Asset Base will be the base point of the value commitment for the specific Custom Asset. Note that the Asset Base of the ZEC Asset will be kept as the original value base point, $\mathcal{V}^{\mathsf{Orchard}}$. Rationale for Asset Identifiers ``````````````````````````````` @@ -86,40 +86,44 @@ In future network and protocol upgrades, the same Asset description string can b Note Structure & Commitment --------------------------- -Let :math:`\mathsf{Note^{OrchardZSA}}` be the type of a OrchardZSA note, i.e. -:math:`\mathsf{Note^{OrchardZSA}} := \mathsf{Note^{Orchard}} \times \mathbb{P}^*\!`. +Let $\mathsf{Note^{OrchardZSA}}$ be the type of a OrchardZSA note, i.e. +$\mathsf{Note^{OrchardZSA}} := \mathsf{Note^{Orchard}} \times \mathbb{P}^*$. -An OrchardZSA note differs from an Orchard note [#protocol-notes]_ by additionally including the Asset Base, :math:`\mathsf{AssetBase}\!`. So an OrchardZSA note is a tuple :math:`(\mathsf{d}, \mathsf{pk_d}, \mathsf{v}, \text{ρ}, \text{ψ}, \mathsf{AssetBase})\!`, +An OrchardZSA note differs from an Orchard note [#protocol-notes]_ by additionally including the Asset Base, $\mathsf{AssetBase}$. So an OrchardZSA note is a tuple $(\mathsf{d}, \mathsf{pk_d}, \mathsf{v}, \text{ρ}, \text{ψ}, \mathsf{AssetBase})$, where -- :math:`\mathsf{AssetBase} : \mathbb{P}^*` is the unique element of the Pallas group [#protocol-pallasandvesta]_ that identifies each Asset in the Orchard protocol, defined as the Asset Base in ZIP 227 [#zip-0227]_, a valid group element that is not the identity and is not :math:`\bot\!`. The byte representation of the Asset Base is defined as :math:`\mathsf{asset\_base} : \mathbb{B}^{[\ell_{\mathbb{P}}]} := \mathsf{repr}_{\mathbb{P}}(\mathsf{AssetBase})\!`. +- $\mathsf{AssetBase} : \mathbb{P}^*$ is the unique element of the Pallas group [#protocol-pallasandvesta]_ that identifies each Asset in the Orchard protocol, defined as the Asset Base in ZIP 227 [#zip-0227]_, a valid group element that is not the identity and is not $\bot$. The byte representation of the Asset Base is defined as $\mathsf{asset\_base} : \mathbb{B}^{[\ell_{\mathbb{P}}]} := \mathsf{repr}_{\mathbb{P}}(\mathsf{AssetBase})$. Note that the above assumes a canonical encoding, which is true for the Pallas group, but may not hold for future shielded protocols. -We define the note commitment scheme :math:`\mathsf{NoteCommit^{OrchardZSA}_{rcm}}` as follows: +We define the note commitment scheme $\mathsf{NoteCommit^{OrchardZSA}_{rcm}}$ as follows: -.. math:: \mathsf{NoteCommit}^{\mathsf{OrchardZSA}} : \mathsf{NoteCommit}^{\mathsf{Orchard}}.\!\mathsf{Trapdoor} \times \mathbb{B}^{[\ell_{\mathbb{P}}]} \times \mathbb{B}^{[\ell_{\mathbb{P}}]} \times \{0 .. 2^{\ell_{\mathsf{value}}} - 1\} \times \mathbb{F}_{q_{\mathbb{P}}} \times \mathbb{F}_{q_{\mathbb{P}}} \times \mathbb{P}^* \to \mathsf{NoteCommit}^{\mathsf{Orchard}}.\!\mathsf{Output} +* $\mathsf{NoteCommit}^{\mathsf{OrchardZSA}} : \mathsf{NoteCommit^{Orchard}.Trapdoor}\hspace{-1em}$ + $\hspace{1em}\times\, \mathbb{B}^{[\ell_{\mathbb{P}}]}\hspace{-1em}$ + $\hspace{1em}\times\, \mathbb{B}^{[\ell_{\mathbb{P}}]}\hspace{-1em}$ + $\hspace{1em}\times\, \{0 .. 2^{\ell_{\mathsf{value}}} - 1\}\hspace{-1em}$ + $\hspace{1em}\times\, \mathbb{F}_{q_{\mathbb{P}}}\hspace{-1em}$ + $\hspace{1em}\times\, \mathbb{F}_{q_{\mathbb{P}}}\hspace{-1em}$ + $\hspace{1em}\times\, \mathbb{P}^* \to \mathsf{NoteCommit^{Orchard}.Output}$ -where :math:`\mathbb{P}, \ell_{\mathbb{P}}, q_{\mathbb{P}}` are as defined for the Pallas curve [#protocol-pallasandvesta]_, and where :math:`\mathsf{NoteCommit^{Orchard}}.\!\mathsf{Trapdoor}` and :math:`\mathsf{Orchard}.\!\mathsf{Output}` are as defined in the Zcash protocol specification [#protocol-abstractcommit]_. +where $\mathbb{P}, \ell_{\mathbb{P}}, q_{\mathbb{P}}$ are as defined for the Pallas curve [#protocol-pallasandvesta]_, and where $\mathsf{NoteCommit^{Orchard}.\{Trapdoor, Output\}}$ are as defined in the Zcash protocol specification [#protocol-abstractcommit]_. This note commitment scheme is instantiated using the Sinsemilla Commitment [#protocol-concretesinsemillacommit]_ as follows: -.. math:: \begin{align} - \mathsf{NoteCommit^{OrchardZSA}_{rcm}}(\mathsf{g_d}\star, \mathsf{pk_d}\star, \mathsf{v}, \text{ρ}, \text{ψ}, \mathsf{AssetBase}) - := \begin{cases} - \mathsf{NoteCommit^{Orchard}_{rcm}}(\mathsf{g_d}\star, \mathsf{pk_d}\star, \mathsf{v}, \text{ρ}, \text{ψ}), &\text{if } \mathsf{AssetBase} = \mathcal{V}^{\mathsf{Orchard}} \\ - \mathsf{cm_{ZSA}} &\text{otherwise} - \end{cases} - \end{align} +.. math:: + \mathsf{NoteCommit^{OrchardZSA}_{rcm}}(\mathsf{g_d}\star, \mathsf{pk_d}\star, \mathsf{v}, \text{ρ}, \text{ψ}, \mathsf{AssetBase}) := + \begin{cases} + \mathsf{NoteCommit^{Orchard}_{rcm}}(\mathsf{g_d}\star, \mathsf{pk_d}\star, \mathsf{v}, \text{ρ}, \text{ψ}), &\!\!\text{if } \mathsf{AssetBase} = \mathcal{V}^{\mathsf{Orchard}} \\ + \mathsf{cm_{ZSA}} &\!\!\text{otherwise} + \end{cases} where: -.. math:: \begin{align} - \mathsf{cm_{ZSA}} :=&\;\;\mathsf{SinsemillaHashToPoint}(\texttt{"z.cash:ZSA-NoteCommit-M"}, \\ - &\;\;\;\;\;\mathsf{g_{d}\star} \,||\, \mathsf{pk_{d}\star} \,||\, \mathsf{I2LEBSP_{64}(v)} \,||\, \mathsf{I2LEBSP}_{\ell^{\mathsf{Orchard}}_{\mathsf{base}}}(\text{ρ}) \,||\, \mathsf{I2LEBSP}_{\ell^{\mathsf{Orchard}}_{\mathsf{base}}}(\text{ψ}) \,||\, \mathsf{asset\_base}) \\ - &\;\;+\;\;[\mathsf{rcm}]\,\mathsf{GroupHash}^{\mathbb{P}}(\texttt{"z.cash:Orchard-NoteCommit-r"}, \texttt{""}) - \end{align} +* $\mathsf{cm_{ZSA}} := \mathsf{SinsemillaHashToPoint}(\texttt{“z.cash:ZSA-NoteCommit-M”},\hspace{-6em}$ + $\hspace{6em}\mathsf{g_{d}\star} \,||\, \mathsf{pk_{d}\star} \,||\, \mathsf{I2LEBSP_{64}(v)} \,||\, \mathsf{I2LEBSP}_{\ell^{\mathsf{Orchard}}_{\mathsf{base}}}(\text{ρ})\hspace{-6em}$ + $\hspace{6em}\,||\, \mathsf{I2LEBSP}_{\ell^{\mathsf{Orchard}}_{\mathsf{base}}}(\text{ψ}) \,||\, \mathsf{asset\_base})\hspace{-4em}$ + $\hspace{4em}\,+\; [\mathsf{rcm}]\,\mathsf{GroupHash}^{\mathbb{P}}(\texttt{“z.cash:Orchard-NoteCommit-r”}, \texttt{“”})$ -Note that :math:`\mathsf{repr}_{\mathbb{P}}` and :math:`\mathsf{GroupHash}^{\mathbb{P}}` are as defined for the Pallas curve [#protocol-pallasandvesta]_, :math:`\ell^{\mathsf{Orchard}}_{\mathsf{base}}` is as defined in §5.3 [#protocol-constants]_, and :math:`\mathsf{I2LEBSP}` is as defined in §5.1 [#protocol-endian]_ of the Zcash protocol specification. +Note that $\mathsf{repr}_{\mathbb{P}}$ and $\mathsf{GroupHash}^{\mathbb{P}}$ are as defined for the Pallas curve [#protocol-pallasandvesta]_, $\ell^{\mathsf{Orchard}}_{\mathsf{base}}$ is as defined in §5.3 [#protocol-constants]_, and $\mathsf{I2LEBSP}$ is as defined in §5.1 [#protocol-endian]_ of the Zcash protocol specification. The nullifier is generated in the same manner as in the Orchard protocol [#protocol-commitmentsandnullifiers]_. @@ -131,13 +135,13 @@ It consists of Rationale for Note Commitment ````````````````````````````` -In the OrchardZSA protocol, the instance of the note commitment scheme, :math:`\mathsf{NoteCommit^{OrchardZSA}_{rcm}}\!`, differs from the Orchard note commitment :math:`\mathsf{NoteCommit^{Orchard}_{rcm}}` in that for Custom Assets, the Asset Base will be added as an input to the commitment computation. +In the OrchardZSA protocol, the instance of the note commitment scheme, $\mathsf{NoteCommit^{OrchardZSA}_{rcm}}$, differs from the Orchard note commitment $\mathsf{NoteCommit^{Orchard}_{rcm}}$ in that for Custom Assets, the Asset Base will be added as an input to the commitment computation. In the case where the Asset is the ZEC Asset, the commitment is computed identically to the Orchard note commitment, without making use of the ZEC Asset Base as an input. As we will see, the nested structure of the Sinsemilla-based commitment [#protocol-concretesinsemillacommit]_ allows us to add the Asset Base as a final recursive step. The note commitment output is still indistinguishable from the original Orchard ZEC note commitments, by definition of the Sinsemilla hash function [#protocol-concretesinsemillahash]_. OrchardZSA note commitments will therefore be added to the same Orchard Note Commitment Tree. In essence, we have: -.. math:: \mathsf{NoteCommit^{OrchardZSA}_{rcm}}(\mathsf{repr}_{\mathbb{P}}(\mathsf{g_d}), \mathsf{repr}_{\mathbb{P}}(\mathsf{pk_d}), \mathsf{v}, \text{ρ}, \text{ψ}, \mathsf{AssetBase}) \in \mathsf{NoteCommit^{Orchard}}.\!\mathsf{Output} +.. math:: \mathsf{NoteCommit^{OrchardZSA}_{rcm}}(\mathsf{repr}_{\mathbb{P}}(\mathsf{g_d}), \mathsf{repr}_{\mathbb{P}}(\mathsf{pk_d}), \mathsf{v}, \text{ρ}, \text{ψ}, \mathsf{AssetBase}) \in \mathsf{NoteCommit^{Orchard}.Output} This definition can be viewed as a generalization of the Orchard note commitment, and will allow maintaining a single commitment instance for the note commitment, which will be used both for pre-ZSA Orchard and OrchardZSA notes. @@ -148,20 +152,20 @@ In the case of the OrchardZSA protocol, the value of different Asset Identifiers .. math:: \mathsf{cv^{net}} := \mathsf{ValueCommit^{OrchardZSA}_{rcv}}(\mathsf{AssetBase_{AssetId}}, \mathsf{v^{net}_{AssetId}}) = [\mathsf{v^{net}_{AssetId}}]\,\mathsf{AssetBase_{AssetId}} + [\mathsf{rcv}]\,\mathcal{R}^{\mathsf{Orchard}} -where :math:`\mathsf{v^{net}_{AssetId}} = \mathsf{v^{old}_{AssetId}} - \mathsf{v^{new}_{AssetId}}` such that :math:`\mathsf{v^{old}_{AssetId}}` and :math:`\mathsf{v^{new}_{AssetId}}` are the values of the old and new notes of Asset Identifier :math:`\mathsf{AssetId}` respectively, +where $\mathsf{v^{net}_{AssetId}} = \mathsf{v^{old}_{AssetId}} - \mathsf{v^{new}_{AssetId}}$ such that .. _`asset base`: -:math:`\mathsf{AssetBase_{AssetId}}` is defined in ZIP 227 [#zip-0227]_, and +* $\mathsf{v^{old}_{AssetId}}$ and $\mathsf{v^{new}_{AssetId}}$ are the values of the old and new notes of Asset Identifier $\mathsf{AssetId}$ respectively, +* $\mathsf{AssetBase_{AssetId}}$ is defined in ZIP 227 [#zip-0227]_, and +* $\mathcal{R}^{\mathsf{Orchard}} := \mathsf{GroupHash^{\mathbb{P}}}(\texttt{“z.cash:Orchard-cv”}, \texttt{“r”})$, as in the Orchard protocol. -:math:`\mathcal{R}^{\mathsf{Orchard}} := \mathsf{GroupHash^{\mathbb{P}}}(\texttt{"z.cash:Orchard-cv"}, \texttt{"r"})\!`, as in the Orchard protocol. - -For ZEC, we define :math:`\mathsf{AssetBase}_{\mathsf{AssetId}} := \mathcal{V}^{\mathsf{Orchard}}` so that the value commitment for ZEC notes is computed identically to the Orchard protocol deployed in NU5 [#zip-0224]_. As such :math:`\mathsf{ValueCommit^{Orchard}_{rcv}}(\mathsf{v})` as defined in [#zip-0224]_ is used as :math:`\mathsf{ValueCommit^{OrchardZSA}_{rcv}}(\mathcal{V}^{\mathsf{Orchard}}, \mathsf{v})` here. +For ZEC, we define $\mathsf{AssetBase}_{\mathsf{AssetId}} := \mathcal{V}^{\mathsf{Orchard}}$ so that the value commitment for ZEC notes is computed identically to the Orchard protocol deployed in NU5 [#zip-0224]_. As such $\mathsf{ValueCommit^{Orchard}_{rcv}}(\mathsf{v})$ as defined in [#zip-0224]_ is used as $\mathsf{ValueCommit^{OrchardZSA}_{rcv}}(\mathcal{V}^{\mathsf{Orchard}}, \mathsf{v})$ here. Rationale for Value Commitment `````````````````````````````` -The Orchard Protocol uses a Homomorphic Pedersen Commitment [#protocol-concretehomomorphiccommit]_ to perform the value commitment, with fixed base points :math:`\mathcal{V}^{\mathsf{Orchard}}` and :math:`\mathcal{R}^{\mathsf{Orchard}}` as the values represent the amount of ZEC being transferred. +The Orchard Protocol uses a Homomorphic Pedersen Commitment [#protocol-concretehomomorphiccommit]_ to perform the value commitment, with fixed base points $\mathcal{V}^{\mathsf{Orchard}}$ and $\mathcal{R}^{\mathsf{Orchard}}$ as the values represent the amount of ZEC being transferred. The use of different value base points for different Assets enables the final balance of the transaction to be securely computed, such that each Asset Identifier is balanced independently, which is required as different Assets are not meant to be mutually fungible. @@ -174,9 +178,9 @@ It is enforced at the consensus level, by using an extension of the value balanc Burning makes it globally provable that a given amount of a Custom Asset has been destroyed. Note that the OrchardZSA Protocol does not allow for the burning of the Native Asset (i.e. ZEC or TAZ). -In the `OrchardZSA Transaction Structure`_, there is now an :math:`\mathsf{assetBurn}` set. -For every Custom Asset (represented by its :math:`\mathsf{AssetBase}\!`) that is burnt in the transaction, the sender adds to :math:`\mathsf{assetBurn}` the tuple :math:`(\mathsf{AssetBase}, \mathsf{v})`, where :math:`\mathsf{v}` is the amount of the Custom Asset the sender wants to burn. -We denote by :math:`L` the cardinality of the :math:`\mathsf{assetBurn}` set in a transaction. +In the `OrchardZSA Transaction Structure`_, there is now an $\mathsf{assetBurn}$ set. +For every Custom Asset (represented by its $\mathsf{AssetBase}$) that is burnt in the transaction, the sender adds to $\mathsf{assetBurn}$ the tuple $(\mathsf{AssetBase}, \mathsf{v})$, where $\mathsf{v}$ is the amount of the Custom Asset the sender wants to burn. +We denote by $L$ the cardinality of the $\mathsf{assetBurn}$ set in a transaction. As described in `Value Balance Verification`_, this provides the information for the validator of the transaction to compute the value commitment with the corresponding Asset Base. This ensures that the values are all balanced out on a per-Asset basis in the transaction. @@ -184,9 +188,9 @@ This ensures that the values are all balanced out on a per-Asset basis in the tr Additional Consensus Rules for the assetBurn set ```````````````````````````````````````````````` -1. It MUST be the case that for every :math:`(\mathsf{AssetBase}, \mathsf{v}) \in \mathsf{assetBurn}, \mathsf{AssetBase} \neq \mathcal{V}^{\mathsf{Orchard}}\!`. That is, the Native Asset is not allowed to be burnt by this mechanism. -2. It MUST be that for every :math:`(\mathsf{AssetBase}, \mathsf{v}) \in \mathsf{assetBurn}, \mathsf{v} \neq 0\!`. -3. There MUST be no duplication of Custom Assets in the :math:`\mathsf{assetBurn}` set. That is, every :math:`\mathsf{AssetBase}` has at most one entry in :math:`\mathsf{assetBurn}\!`. +1. It MUST be the case that for every $(\mathsf{AssetBase}, \mathsf{v}) \in \mathsf{assetBurn}, \mathsf{AssetBase} \neq \mathcal{V}^{\mathsf{Orchard}}$. That is, the Native Asset is not allowed to be burnt by this mechanism. +2. It MUST be that for every $(\mathsf{AssetBase}, \mathsf{v}) \in \mathsf{assetBurn}, \mathsf{v} \neq 0$. +3. There MUST be no duplication of Custom Assets in the $\mathsf{assetBurn}$ set. That is, every $\mathsf{AssetBase}$ has at most one entry in $\mathsf{assetBurn}$. The other consensus rule changes for the OrchardZSA protocol are specified in ZIP 227 [#zip-0227-consensus]_. @@ -198,21 +202,21 @@ Value Balance Verification In order to verify the balance of the different Assets, the verifier MUST perform a similar process as for the Orchard protocol [#protocol-orchardbalance]_, with the addition of the burn information. -For a total of :math:`n` Actions in a transfer, the prover MUST still sign the SIGHASH transaction hash using the binding signature key -:math:`\mathsf{bsk} = \sum_{i=1}^{n} \mathsf{rcv}_i\!`. +For a total of $n$ Actions in a transfer, the prover MUST still sign the SIGHASH transaction hash using the binding signature key +$\mathsf{bsk} = \sum_{i=1}^{n} \mathsf{rcv}_i$. The verifier MUST compute the value balance verification equation: .. math:: \mathsf{bvk} = (\sum_{i=1}^{n} \mathsf{cv}^{\mathsf{net}}_i) - \mathsf{ValueCommit_0^{OrchardZSA}(\mathcal{V}^{\mathsf{Orchard}}, v^{balanceOrchard})} - \sum_{(\mathsf{AssetBase}, \mathsf{v}) \in \mathsf{assetBurn}} \mathsf{ValueCommit_0^{OrchardZSA}}(\mathsf{AssetBase}, \mathsf{v}) -After computing :math:`\mathsf{bvk}\!`, the verifier MUST use it to verify the binding signature on the SIGHASH transaction hash. +After computing $\mathsf{bvk}$, the verifier MUST use it to verify the binding signature on the SIGHASH transaction hash. Rationale for Value Balance Verification ```````````````````````````````````````` -We assume :math:`n` Actions in a transfer. Out of these :math:`n` Actions, we further distinguish (for the sake of clarity) between Actions related to ZEC and Actions related to Custom Assets. -We denote by :math:`S_{\mathsf{ZEC}} \subseteq \{1 .. n\}` the set of indices of Actions that are related to ZEC, and by :math:`S_{\mathsf{CA}} = \{1 .. n\} \setminus S_{\mathsf{ZEC}}` the set of indices of Actions that are related to Custom Assets. +We assume $n$ Actions in a transfer. Out of these $n$ Actions, we further distinguish (for the sake of clarity) between Actions related to ZEC and Actions related to Custom Assets. +We denote by $S_{\mathsf{ZEC}} \subseteq \{1 .. n\}$ the set of indices of Actions that are related to ZEC, and by $S_{\mathsf{CA}} = \{1 .. n\} \setminus S_{\mathsf{ZEC}}$ the set of indices of Actions that are related to Custom Assets. The right hand side of the value balance verification equation can be expanded to: @@ -221,13 +225,13 @@ The right hand side of the value balance verification equation can be expanded t This equation contains the balance check of the Orchard protocol [#protocol-orchardbalance]_. With ZSA, transfer Actions for Custom Assets must also be balanced across Asset Bases. All Custom Assets are contained within the shielded pool, and cannot be unshielded via a regular transfer. -Custom Assets can be burnt, the mechanism for which reveals the amount and identifier of the Asset being burnt, within the :math:`\mathsf{assetBurn}` set. -As such, for a correctly constructed transaction, we will get :math:`\sum_{j \in S_{\mathsf{CA}}} \mathsf{cv}^{\mathsf{net}}_j - \sum_{(\mathsf{AssetBase}, \mathsf{v}) \in \mathsf{assetBurn}} [\mathsf{v}]\,\mathsf{AssetBase} = \sum_{j \in S_{\mathsf{CA}}} [\mathsf{rcv}^{\mathsf{net}}_j]\,\mathcal{R}^{\mathsf{Orchard}}\!`. +Custom Assets can be burnt, the mechanism for which reveals the amount and identifier of the Asset being burnt, within the $\mathsf{assetBurn}$ set. +As such, for a correctly constructed transaction, we will get $\sum_{j \in S_{\mathsf{CA}}} \mathsf{cv}^{\mathsf{net}}_j - \sum_{(\mathsf{AssetBase}, \mathsf{v}) \in \mathsf{assetBurn}} [\mathsf{v}]\,\mathsf{AssetBase} = \sum_{j \in S_{\mathsf{CA}}} [\mathsf{rcv}^{\mathsf{net}}_j]\,\mathcal{R}^{\mathsf{Orchard}}$. -When the Asset is not being burnt, the net balance of the input and output values is zero, and there will be no addition to the :math:`\mathsf{assetBurn}` vector. -Therefore, the relationship between :math:`\mathsf{bvk}` and :math:`\mathsf{bsk}` will hold if and only if, per Custom Asset, the sum of the net values of the relevant Actions equals the corresponding :math:`\mathsf{v}_k` value (or equals :math:`0` if that Asset is not in the :math:`\mathsf{assetBurn}` set), and for ZEC, the sum of the net values of the relevant Actions equals the :math:`\mathsf{v^{balanceOrchard}}` value. +When the Asset is not being burnt, the net balance of the input and output values is zero, and there will be no addition to the $\mathsf{assetBurn}$ vector. +Therefore, the relationship between $\mathsf{bvk}$ and $\mathsf{bsk}$ will hold if and only if, per Custom Asset, the sum of the net values of the relevant Actions equals the corresponding $\mathsf{v}_k$ value (or equals $0$ if that Asset is not in the $\mathsf{assetBurn}$ set), and for ZEC, the sum of the net values of the relevant Actions equals the $\mathsf{v^{balanceOrchard}}$ value. -As in the Orchard protocol, the binding signature verification key, :math:`\mathsf{bvk}\!`, will only be valid (and hence verify the signature correctly), as long as the committed values sum to zero. In contrast, in this protocol, the committed values must sum to zero **per Asset Base**, as the Pedersen commitments add up homomorphically only with respect to the same value base point. +As in the Orchard protocol, the binding signature verification key, $\mathsf{bvk}$, will only be valid (and hence verify the signature correctly), as long as the committed values sum to zero. In contrast, in this protocol, the committed values must sum to zero **per Asset Base**, as the Pedersen commitments add up homomorphically only with respect to the same value base point. Split Notes @@ -235,7 +239,7 @@ Split Notes A Split Input is a copy of a previously issued input note (that is, a note that has previously been included in the Merkle tree), with the following changes: -- A :math:`\mathsf{split\_flag}` boolean is set to 1. +- A $\mathsf{split\_flag}$ boolean is set to 1. - The value of the note is replaced with the value 0 during the computation of the value commitment. Input notes are sometimes split in two (or more) output notes, as in most cases, not all the value in a single note is sent to a single output. @@ -252,7 +256,7 @@ For Split Notes, the nullifier is generated as follows: .. math:: \mathsf{nf_{old}} = \mathsf{Extract}_{\mathbb{P}} ([(\mathsf{PRF^{nfOrchard}_{nk}} (\text{ρ}^{\mathsf{old}}) + \text{ψ}^{\mathsf{nf}}) \bmod q_{\mathbb{P}}]\,\mathcal{K}^\mathsf{Orchard} + \mathsf{cm^{old}} + \mathcal{L}^\mathsf{Orchard}) -where :math:`\text{ψ}^{\mathsf{nf}}` is sampled uniformly at random on :math:`\mathbb{F}_{q_{\mathbb{P}}}\!`, :math:`\mathcal{K}^{\mathsf{Orchard}}` is the Orchard Nullifier Base as defined in [#protocol-commitmentsandnullifiers]_, and :math:`\mathcal{L}^{\mathsf{Orchard}} := \mathsf{GroupHash^{\mathbb{P}}}(\texttt{"z.cash:Orchard"}, \texttt{"L"})\!`. +where $\text{ψ}^{\mathsf{nf}}$ is sampled uniformly at random on $\mathbb{F}_{q_{\mathbb{P}}}$, $\mathcal{K}^{\mathsf{Orchard}}$ is the Orchard Nullifier Base as defined in [#protocol-commitmentsandnullifiers]_, and $\mathcal{L}^{\mathsf{Orchard}} := \mathsf{GroupHash^{\mathbb{P}}}(\texttt{“z.cash:Orchard”}, \texttt{“L”})$. Rationale for Split Notes ````````````````````````` @@ -261,7 +265,7 @@ In the Orchard protocol, since each Action represents an input and an output, th The Orchard technique requires modification for the OrchardZSA protocol with multiple Asset Identifiers, as the output note of the split Actions *cannot* contain *just any* Asset Base. We must enforce it to be an actual output of a GroupHash computation (in fact, we want it to be of the same Asset Base as the original input note, but the binding signature takes care that the proper balancing is performed). Without this enforcement the prover could input a multiple (or linear combination) of an existing Asset Base, and thereby attack the network by overflowing the ZEC value balance and hence counterfeiting ZEC funds. -Therefore, for Custom Assets we enforce that *every* input note to an OrchardZSA Action must be proven to exist in the set of note commitments in the note commitment tree. We then enforce this real note to be “unspendable” in the sense that its value will be zeroed in split Actions and the nullifier will be randomized, making the note not spendable in the specific Action. Then, the proof itself ensures that the output note is of the same Asset Base as the input note. In the circuit, the split note functionality will be activated by a boolean private input to the proof (aka the :math:`\mathsf{split\_flag}` boolean). +Therefore, for Custom Assets we enforce that *every* input note to an OrchardZSA Action must be proven to exist in the set of note commitments in the note commitment tree. We then enforce this real note to be “unspendable” in the sense that its value will be zeroed in split Actions and the nullifier will be randomized, making the note not spendable in the specific Action. Then, the proof itself ensures that the output note is of the same Asset Base as the input note. In the circuit, the split note functionality will be activated by a boolean private input to the proof (aka the $\mathsf{split\_flag}$ boolean). This ensures that the value base points of all output notes of a transfer are actual outputs of a GroupHash, as they originate in the Issuance protocol which is publicly verified. Note that the Orchard dummy note functionality remains in use for ZEC notes, and the Split Input technique is used in order to support Custom Assets. @@ -277,28 +281,28 @@ All modifications in the Circuit are detailed in [#circuit-modifications]_. Asset Base Equality ``````````````````` -The following constraints must be added to ensure that the input and output note are of the same :math:`\mathsf{AssetBase}\!`: +The following constraints must be added to ensure that the input and output note are of the same $\mathsf{AssetBase}$: -- The Asset Base, :math:`\mathsf{AssetBase_{AssetId}}\!`, for the note is witnessed once, as an auxiliary input. -- In the Old note commitment integrity constraint in the Orchard Action statement [#protocol-actionstatement]_, :math:`\mathsf{NoteCommit^{Orchard}_{rcm^{old}}}(\mathsf{repr}_{\mathbb{P}}(\mathsf{g_d^{old}}), \mathsf{repr}_{\mathbb{P}}(\mathsf{pk_d^{old}}), \mathsf{v^{old}}, \text{ρ}^{\mathsf{old}}, \text{ψ}^{\mathsf{old}})` is replaced with :math:`\mathsf{NoteCommit^{OrchardZSA}_{rcm^{old}}}(\mathsf{repr}_{\mathbb{P}}(\mathsf{g_d^{old}}), \mathsf{repr}_{\mathbb{P}}(\mathsf{pk_d^{old}}), \mathsf{v^{old}}, \text{ρ}^{\mathsf{old}}, \text{ψ}^{\mathsf{old}}, \mathsf{AssetBase_{AssetId}})\!`. -- In the New note commitment integrity constraint in the Orchard Action statement [#protocol-actionstatement]_, :math:`\mathsf{NoteCommit^{Orchard}_{rcm^{new}}}(\mathsf{repr}_{\mathbb{P}}(\mathsf{g_d^{new}}), \mathsf{repr}_{\mathbb{P}}(\mathsf{pk_d^{new}}), \mathsf{v^{new}}, \text{ρ}^{\mathsf{new}}, \text{ψ}^{\mathsf{new}})` is replaced with :math:`\mathsf{NoteCommit^{OrchardZSA}_{rcm^{new}}}(\mathsf{repr}_{\mathbb{P}}(\mathsf{g_d^{new}}), \mathsf{repr}_{\mathbb{P}}(\mathsf{pk_d^{new}}), \mathsf{v^{new}}, \text{ρ}^{\mathsf{new}}, \text{ψ}^{\mathsf{new}}, \mathsf{AssetBase_{AssetId}})\!`. +- The Asset Base, $\mathsf{AssetBase_{AssetId}}$, for the note is witnessed once, as an auxiliary input. +- In the Old note commitment integrity constraint in the Orchard Action statement [#protocol-actionstatement]_, $\mathsf{NoteCommit^{Orchard}_{rcm^{old}}}(\mathsf{repr}_{\mathbb{P}}(\mathsf{g_d^{old}}), \mathsf{repr}_{\mathbb{P}}(\mathsf{pk_d^{old}}), \mathsf{v^{old}}, \text{ρ}^{\mathsf{old}}, \text{ψ}^{\mathsf{old}})$ is replaced with $\mathsf{NoteCommit^{OrchardZSA}_{rcm^{old}}}(\mathsf{repr}_{\mathbb{P}}(\mathsf{g_d^{old}}), \mathsf{repr}_{\mathbb{P}}(\mathsf{pk_d^{old}}), \mathsf{v^{old}}, \text{ρ}^{\mathsf{old}}, \text{ψ}^{\mathsf{old}}, \mathsf{AssetBase_{AssetId}})$. +- In the New note commitment integrity constraint in the Orchard Action statement [#protocol-actionstatement]_, $\mathsf{NoteCommit^{Orchard}_{rcm^{new}}}(\mathsf{repr}_{\mathbb{P}}(\mathsf{g_d^{new}}), \mathsf{repr}_{\mathbb{P}}(\mathsf{pk_d^{new}}), \mathsf{v^{new}}, \text{ρ}^{\mathsf{new}}, \text{ψ}^{\mathsf{new}})$ is replaced with $\mathsf{NoteCommit^{OrchardZSA}_{rcm^{new}}}(\mathsf{repr}_{\mathbb{P}}(\mathsf{g_d^{new}}), \mathsf{repr}_{\mathbb{P}}(\mathsf{pk_d^{new}}), \mathsf{v^{new}}, \text{ρ}^{\mathsf{new}}, \text{ψ}^{\mathsf{new}}, \mathsf{AssetBase_{AssetId}})$. -To make the evaluation of the note commitment easier, we add a boolean :math:`\mathsf{is\_native\_asset}` as an auxiliary witness. We also add some constraints to verify that this variable is activated (i.e. :math:`\mathsf{is\_native\_asset} = 1\!`) if the Asset Base is equal to :math:`\mathcal{V}^{\mathsf{Orchard}}` and this variable is not activated (i.e. :math:`\mathsf{is\_native\_asset} = 0\!`) if the Asset Base is not equal to :math:`\mathcal{V}^{\mathsf{Orchard}}\!`. +To make the evaluation of the note commitment easier, we add a boolean $\mathsf{is\_native\_asset}$ as an auxiliary witness. We also add some constraints to verify that this variable is activated (i.e. $\mathsf{is\_native\_asset} = 1$) if the Asset Base is equal to $\mathcal{V}^{\mathsf{Orchard}}$ and this variable is not activated (i.e. $\mathsf{is\_native\_asset} = 0$) if the Asset Base is not equal to $\mathcal{V}^{\mathsf{Orchard}}$. The :math:`\mathsf{enableZSA}` Flag -````````````````````````````````````` +``````````````````````````````````` -The following constraints must be added to disable transactions involving Custom Assets when the :math:`\mathsf{enableZSA}` flag is set to false: +The following constraints must be added to disable transactions involving Custom Assets when the $\mathsf{enableZSA}$ flag is set to false: -- if :math:`\mathsf{enableZSA}` is not activated (i.e. :math:`\mathsf{enableZSA} = 0\!`), then constrain :math:`\mathsf{is\_native\_asset} = 1\!`, since the :math:`\mathsf{AsssetBase}` must be equal to the native asset. +- if $\mathsf{enableZSA}$ is not activated (i.e. $\mathsf{enableZSA} = 0$), then constrain $\mathsf{is\_native\_asset} = 1$, since the $\mathsf{AsssetBase}$ must be equal to the native asset. Value Commitment Correctness ```````````````````````````` The following constraints must be added to ensure that the value commitment is computed using the witnessed Asset Base: -- The fixed-base multiplication constraint between the value and the value base point of the value commitment, :math:`\mathsf{cv}\!`, is replaced with a variable-base multiplication between the two. -- The witness to the value base point (as defined in the `asset base`_ equation) is the auxiliary input :math:`\mathsf{AssetBase_{AssetId}}\!`. +- The fixed-base multiplication constraint between the value and the value base point of the value commitment, $\mathsf{cv}$, is replaced with a variable-base multiplication between the two. +- The witness to the value base point (as defined in the `asset base`_ equation) is the auxiliary input $\mathsf{AssetBase_{AssetId}}$. Asset Identifier Consistency for Split Actions `````````````````````````````````````````````` @@ -306,13 +310,19 @@ Asset Identifier Consistency for Split Actions Senders must not be able to change the Asset Base for the output note in a Split Action. We do this via the following constraints: - The Value Commitment Integrity should be changed: - - Replace the input note value by a generic value, :math:`\mathsf{v}'\!`, as :math:`\mathsf{cv^{net}} = \mathsf{ValueCommit_rcv^{OrchardZSA}}(\mathsf{AssetBase_{AssetId}}, \mathsf{v}' - \mathsf{v^{new}})` -- Add a boolean :math:`\mathsf{split\_flag}` variable as an auxiliary witness. This variable is to be activated :math:`\mathsf{split\_flag} = 1` if the Action in question has a Split Input and :math:`\mathsf{split\_flag} = 0` if the Action is actually spending an input note: - - If :math:`\mathsf{split\_flag} = 1` then constrain :math:`\mathsf{v}' = 0` otherwise constrain :math:`\mathsf{v}' = \mathsf{v^{old}}` from the auxiliary input. - - If :math:`\mathsf{split\_flag} = 1` then constrain :math:`\mathsf{is\_native\_asset} = 0` because split notes are only available for Custom Assets. + + - Replace the input note value by a generic value, $\mathsf{v}'$, as $\mathsf{cv^{net}} = \mathsf{ValueCommit_rcv^{OrchardZSA}}(\mathsf{AssetBase_{AssetId}}, \mathsf{v}' - \mathsf{v^{new}})$ + +- Add a boolean $\mathsf{split\_flag}$ variable as an auxiliary witness. This variable is to be activated $\mathsf{split\_flag} = 1$ if the Action in question has a Split Input and $\mathsf{split\_flag} = 0$ if the Action is actually spending an input note: + + - If $\mathsf{split\_flag} = 1$ then constrain $\mathsf{v}' = 0$ otherwise constrain $\mathsf{v}' = \mathsf{v^{old}}$ from the auxiliary input. + - If $\mathsf{split\_flag} = 1$ then constrain $\mathsf{is\_native\_asset} = 0$ because split notes are only available for Custom Assets. + - The Merkle Path Validity should check the existence of the note commitment as usual (and not like with dummy notes): - - Check for all notes except dummy notes that :math:`(\mathsf{path}, \mathsf{pos})` is a valid Merkle path of depth :math:`\mathsf{MerkleDepth^{Orchard}}\!`, from :math:`\mathsf{cm^{old}}` to the anchor :math:`\mathsf{rt^{Orchard}}\!`. - - The new constraint is :math:`\underbrace{(\mathsf{v^{old}} = 0 \land \mathsf{is\_native\_asset} = 1)}_\text{It is a dummy note} \lor \underbrace{(\mathsf{Valid\,Merkle\,Path})}_\text{The Merkle Path is valid}\!`. + + - Check for all notes except dummy notes that $(\mathsf{path}, \mathsf{pos})$ is a valid Merkle path of depth $\mathsf{MerkleDepth^{Orchard}}$, from $\mathsf{cm^{old}}$ to the anchor $\mathsf{rt^{Orchard}}$. + - The new constraint is $\underbrace{(\mathsf{v^{old}} = 0 \land \mathsf{is\_native\_asset} = 1)}_\text{It is a dummy note} \lor \underbrace{(\mathsf{Valid\,Merkle\,Path})}_\text{The Merkle Path is valid}$. + - The Nullifier Integrity will be changed to prevent the identification of notes as defined in the `Split Notes`_ section. Backwards Compatibility with ZEC Notes @@ -432,7 +442,7 @@ T.4b: orchard_zsa_burn_digest ''''''''''''''''''''''''''''' A BLAKE2b-256 hash of the data from the burn fields of the transaction. For each tuple in -the :math:`\mathsf{assetBurn}` set, the following elements are included in the hash:: +the $\mathsf{assetBurn}$ set, the following elements are included in the hash:: T.4b.i : assetBase (field encoding bytes) T.4b.ii: valueBurn (field encoding bytes) @@ -442,7 +452,7 @@ The personalization field of this hash is set to:: "ZTxIdOrcBurnHash" In case the transaction does not perform the burning of any Assets (i.e. the -:math:`\mathsf{assetBurn}` set is empty), the ''orchard_zsa_burn_digest'' is:: +$\mathsf{assetBurn}$ set is empty), the ''orchard_zsa_burn_digest'' is:: BLAKE2b-256("ZTxIdOrcBurnHash", []) @@ -550,7 +560,7 @@ Backward Compatibility In order to have backward compatibility with the ZEC notes, we have designed the circuit to support both ZEC and OrchardZSA notes. As we specify above, there are three main reasons we can do this: -- Note commitments for ZEC notes will remain the same, while note commitments for Custom Assets will be computed taking into account the :math:`\mathsf{AssetBase}` value as well. +- Note commitments for ZEC notes will remain the same, while note commitments for Custom Assets will be computed taking into account the $\mathsf{AssetBase}$ value as well. - The existing Orchard shielded pool will continue to be used for the new OrchardZSA notes post the upgrade. - The value commitment is abstracted to allow for the value base-point as a variable private input to the proof. - The ZEC-based Actions will still include dummy input notes, whereas the OrchardZSA Actions will include split input notes and will not include dummy input notes. diff --git a/zips/zip-0227.rst b/zips/zip-0227.rst index f5e05edda..f8fb8db58 100644 --- a/zips/zip-0227.rst +++ b/zips/zip-0227.rst @@ -75,7 +75,7 @@ Requirements - Issuing or changing the attributes of a specific Asset should require cryptographic authorization. - The Asset identification should be unique (among all shielded pools) and different issuer public keys should not be able to generate the same Asset Identifier. - An issuer should be able to issue different Assets in the same transaction. In other words, in a single "issuance bundle", the issuer should be able publish many "issuance actions", potentially creating multiple Custom Assets. -- Every "issuance action" should contain a :math:`\mathsf{finalize}` boolean that defines whether the specific Custom Asset can have further tokens issued or not. +- Every "issuance action" should contain a $\mathsf{finalize}$ boolean that defines whether the specific Custom Asset can have further tokens issued or not. Specification: Issuance Keys and Issuance Authorization Signature Scheme @@ -83,9 +83,9 @@ Specification: Issuance Keys and Issuance Authorization Signature Scheme The OrchardZSA Protocol adds the following keys to the key components [#protocol-addressesandkeys]_ [#protocol-orchardkeycomponents]_: -1. The issuance authorizing key, denoted as :math:`\mathsf{isk}\!`, is the key used to authorize the issuance of Asset Identifiers by a given issuer, and is only used by that issuer. +1. The issuance authorizing key, denoted as $\mathsf{isk}$, is the key used to authorize the issuance of Asset Identifiers by a given issuer, and is only used by that issuer. -2. The issuance validating key, denoted as :math:`\mathsf{ik}\!`, is the key that is used to validate issuance transactions. This key is used to validate the issuance of Asset Identifiers by a given issuer, and is used by all blockchain users (specifically the owners of notes for that Asset, and consensus validators) to associate the Asset in question with the issuer. +2. The issuance validating key, denoted as $\mathsf{ik}$, is the key that is used to validate issuance transactions. This key is used to validate the issuance of Asset Identifiers by a given issuer, and is used by all blockchain users (specifically the owners of notes for that Asset, and consensus validators) to associate the Asset in question with the issuer. The relations between these keys are shown in the following diagram: @@ -100,20 +100,20 @@ The relations between these keys are shown in the following diagram: Issuance Authorization Signature Scheme --------------------------------------- -We instantiate the issuance authorization signature scheme :math:`\mathsf{IssueAuthSig}` as a BIP-340 Schnorr signature over the secp256k1 curve. The signing and validation algorithms, signature encoding, and public key encoding MUST follow BIP 340 [#bip-0340]_. +We instantiate the issuance authorization signature scheme $\mathsf{IssueAuthSig}$ as a BIP-340 Schnorr signature over the secp256k1 curve. The signing and validation algorithms, signature encoding, and public key encoding MUST follow BIP 340 [#bip-0340]_. -Batch verification MAY be used. Precomputation MAY be used if and only if it produces equivalent results; for example, for a given verification key :math:`pk` and :math:`\mathit{lift\_x}(\mathit{int}(pk))` MAY be precomputed. +Batch verification MAY be used. Precomputation MAY be used if and only if it produces equivalent results; for example, for a given verification key $pk$ and $\mathit{lift\_x}(\mathit{int}(pk))$ MAY be precomputed. We define the constants as per the secp256k1 standard parameters, as described in BIP 340. -The associated types of the :math:`\mathsf{IssueAuthSig}` signature scheme are as follows: +The associated types of the $\mathsf{IssueAuthSig}$ signature scheme are as follows: -* :math:`\mathsf{IssueAuthSig}.\!\mathsf{Message} = \mathbb{B}^{\mathbb{Y}^{[\mathbb{N}]}}` -* :math:`\mathsf{IssueAuthSig}.\!\mathsf{Signature} = \mathbb{B}^{\mathbb{Y}^{[64]}} \cup \{\bot\}` -* :math:`\mathsf{IssueAuthSig}.\!\mathsf{Public} = \mathbb{B}^{\mathbb{Y}^{[32]}} \cup \{\bot\}` -* :math:`\mathsf{IssueAuthSig}.\!\mathsf{Private} = \mathbb{B}^{\mathbb{Y}^{[32]}}` +* $\mathsf{IssueAuthSig.Message} = \mathbb{B}^{\mathbb{Y}^{[\mathbb{N}]}}$ +* $\mathsf{IssueAuthSig.Signature} = \mathbb{B}^{\mathbb{Y}^{[64]}} \cup \{\bot\}$ +* $\mathsf{IssueAuthSig.Public} = \mathbb{B}^{\mathbb{Y}^{[32]}} \cup \{\bot\}$ +* $\mathsf{IssueAuthSig.Private} = \mathbb{B}^{\mathbb{Y}^{[32]}}$ -where :math:`\mathbb{B}^{\mathbb{Y}^{[k]}}` denotes the set of sequences of :math:`k` bytes, and :math:`\mathbb{B}^{\mathbb{Y}^{[\mathbb{N}]}}` denotes the type of byte sequences of arbitrary length, as defined in the Zcash protocol specification [#protocol-notation]_. +where $\mathbb{B}^{\mathbb{Y}^{[k]}}$ denotes the set of sequences of $k$ bytes, and $\mathbb{B}^{\mathbb{Y}^{[\mathbb{N}]}}$ denotes the type of byte sequences of arbitrary length, as defined in the Zcash protocol specification [#protocol-notation]_. The issuance authorizing key generation algorithm and the issuance validating key derivation algorithm are defined in the `Issuance Key Derivation`_ section, while the corresponding signing and validation algorithms are defined in the `Issuance Authorization Signing and Validation`_ section. @@ -124,87 +124,87 @@ Issuance authorizing key generation for hierarchical deterministic wallets `````````````````````````````````````````````````````````````````````````` The issuance authorizing key is generated using the Hardened-only key derivation process defined in ZIP 32 [#zip-0032-hardened-only-key-derivation]_. -For the :math:`\mathsf{Issuance}` context, we define the following constants: +For the $\mathsf{Issuance}$ context, we define the following constants: -- :math:`\mathsf{Issuance.\!MKGDomain} := \texttt{"ZcashSA_Issue_V1"}` -- :math:`\mathsf{Issuance.\!CKDDomain} := \mathtt{0x81}\!` +- $\mathsf{Issuance.MKGDomain} := \texttt{“ZcashSA\_Issue\_V1”}$ +- $\mathsf{Issuance.CKDDomain} := \mathtt{0x81}$ -Let :math:`S` be a seed byte sequence of a chosen length, which MUST be at least 32 and at most 252 bytes. -We define the master extended issuance key :math:`m_{\mathsf{Issuance}} := \mathsf{MKGh}^{\mathsf{Issuance}}(S)\!`. +Let $S$ be a seed byte sequence of a chosen length, which MUST be at least 32 and at most 252 bytes. +We define the master extended issuance key $m_{\mathsf{Issuance}} := \mathsf{MKGh}^{\mathsf{Issuance}}(S)$. We use hardened-only child key derivation as defined in ZIP 32 [#zip-0032-hardened-only-child-key-derivation]_ for the issuance authorizing key. -:math:`\mathsf{CKDsk}((\mathsf{sk}_{par},\mathsf{c}_{par}), i) \rightarrow (\mathsf{sk}_{i}, \mathsf{c}_{i})` +$\mathsf{CKDsk}((\mathsf{sk}_{par},\mathsf{c}_{par}), i) \rightarrow (\mathsf{sk}_{i}, \mathsf{c}_{i})$ : -- Return :math:`\mathsf{CKDh}^{\mathsf{Issuance}}((\mathsf{sk}_{par},\mathsf{c}_{par}), i)\!` +- Return $\mathsf{CKDh}^{\mathsf{Issuance}}((\mathsf{sk}_{par},\mathsf{c}_{par}), i)$ -We use the notation of ZIP 32 [#zip-0032-orchard-key-path]_ for shielded HD paths, and define the issuance authorizing key path as :math:`m_{\mathsf{Issuance}} / \mathit{purpose}' / \mathit{coin\_type}' / \mathit{account}'\!`. We fix the path levels as follows: +We use the notation of ZIP 32 [#zip-0032-orchard-key-path]_ for shielded HD paths, and define the issuance authorizing key path as $m_{\mathsf{Issuance}} / \mathit{purpose}' / \mathit{coin\_type}' / \mathit{account}'.$ We fix the path levels as follows: -- :math:`\mathit{purpose}`: a constant set to :math:`227` (i.e. :math:`\mathtt{0xe3}\!`). :math:`\mathit{purpose}'` is thus :math:`227'` (or :math:`\mathtt{0x800000e3}\!`) following the BIP 43 recommendation. -- :math:`\mathit{coin\_type}`: Defined as in ZIP 32 [#zip-0032-key-path-levels]_. -- :math:`\mathit{account}`: fixed to index :math:`0\!`. +- $\mathit{purpose}$: a constant set to $227$ (i.e. $\mathtt{0xe3}$). $\mathit{purpose}'$ is thus $227'$ (or $\mathtt{0x800000e3}$) following the BIP 43 recommendation. [#bip-0043]_ +- $\mathit{coin\_type}$: Defined as in ZIP 32 [#zip-0032-key-path-levels]_. +- $\mathit{account}$: fixed to index $0$. -From the generated :math:`(\mathsf{sk}, \mathsf{c})\!`, we set the issuance authorizing key to be :math:`\mathsf{isk} := \mathsf{sk}\!`. +From the generated $(\mathsf{sk}, \mathsf{c})$, we set the issuance authorizing key to be $\mathsf{isk} := \mathsf{sk}$. Derivation of issuance validating key ````````````````````````````````````` -Define :math:`\mathsf{IssueAuthSig}.\!\mathsf{DerivePublic}\; : \; (\mathsf{isk}\; : \; \mathsf{IssueAuthSig}.\!\mathsf{Private}) \to \mathsf{IssueAuthSig}.\!\mathsf{Public}` as: +Define $\mathsf{IssueAuthSig.DerivePublic} \;{\small ⦂}\; (\mathsf{isk} \;{\small ⦂}\; \mathsf{IssueAuthSig.Private}) \to \mathsf{IssueAuthSig.Public}$ as: -* :math:`\mathsf{ik} := \textit{PubKey}(\mathsf{isk})` -* Return :math:`\bot` if the :math:`\textit{PubKey}` algorithm invocation fails, otherwise return :math:`\mathsf{ik}\!`. +* $\mathsf{ik} := \textit{PubKey}(\mathsf{isk})$ +* Return $\bot$ if the $\textit{PubKey}$ algorithm invocation fails, otherwise return $\mathsf{ik}$. -where the :math:`\textit{PubKey}` algorithm is defined in BIP 340 [#bip-0340]_. -Note that the byte representation of :math:`\mathsf{ik}` is in big-endian order as defined in BIP 340. +where the $\textit{PubKey}$ algorithm is defined in BIP 340 [#bip-0340]_. +Note that the byte representation of $\mathsf{ik}$ is in big-endian order as defined in BIP 340. -It is possible for the :math:`\textit{PubKey}` algorithm to fail with very low probability, which means that :math:`\mathsf{IssueAuthSig}.\!\mathsf{DerivePublic}` could return :math:`\bot` with very low probability. -If this happens, discard the keys and repeat with a different :math:`\mathsf{isk}\!`. +It is possible for the $\textit{PubKey}$ algorithm to fail with very low probability, which means that $\mathsf{IssueAuthSig.DerivePublic}$ could return $\bot$ with very low probability. +If this happens, discard the keys and repeat with a different $\mathsf{isk}$. This allows the issuer to use the same wallet it usually uses to transfer Assets, while keeping a disconnect from the other keys. Specifically, this method is aligned with the requirements and motivation of ZIP 32 [#zip-0032]_. It provides further anonymity and the ability to delegate issuance of an Asset (or in the future, generate a multi-signature protocol) while the rest of the keys remain in the wallet safe. Issuance Authorization Signing and Validation --------------------------------------------- -Define :math:`\mathsf{IssueAuthSig}.\!\mathsf{Sign}\; : \; (\mathsf{isk}\; : \; \mathsf{IssueAuthSig}.\!\mathsf{Private}) \times (M\; : \; \mathsf{IssueAuthSig}.\!\mathsf{Message}) \to \mathsf{IssueAuthSig}.\!\mathsf{Signature}` as: +Define $\mathsf{IssueAuthSig.Sign} \;{\small ⦂}\; (\mathsf{isk} \;{\small ⦂}\; \mathsf{IssueAuthSig.Private}) \times (M \;{\small ⦂}\; \mathsf{IssueAuthSig.Message}) \to \mathsf{IssueAuthSig.Signature}$ as: -* Let the auxiliary data :math:`a = [\mathtt{0x00}]^{32}\!`. -* Let :math:`\text{σ} = \mathsf{Sign}(\mathsf{isk}, M)\!`. -* Return :math:`\bot` if the :math:`\mathsf{Sign}` algorithm fails in the previous step, otherwise return :math:`\text{σ}\!`. +* Let the auxiliary data $a = [\mathtt{0x00}]^{32}$. +* Let $\text{σ} = \mathsf{Sign}(\mathsf{isk}, M)$. +* Return $\bot$ if the $\mathsf{Sign}$ algorithm fails in the previous step, otherwise return $\text{σ}$. -where the :math:`\mathsf{Sign}` algorithm is defined in BIP 340 and :math:`a` denotes the auxiliary data used in BIP 340 [#bip-0340]_. -Note that :math:`\mathsf{IssueAuthSig}.\!\mathsf{Sign}` could return :math:`\bot` with very low probability. +where the $\mathsf{Sign}$ algorithm is defined in BIP 340 and $a$ denotes the auxiliary data used in BIP 340 [#bip-0340]_. +Note that $\mathsf{IssueAuthSig.Sign}$ could return $\bot$ with very low probability. -Define :math:`\mathsf{IssueAuthSig}.\!\mathsf{Validate}\; : \; (\mathsf{ik}\; : \; \mathsf{IssueAuthSig}.\!\mathsf{Public}) \times (M\; : \; \mathsf{IssueAuthSig}.\!\mathsf{Message}) \times (\text{σ}\; : \; \mathsf{IssueAuthSig}.\!\mathsf{Signature}) \to \mathbb{B}` as: +Define $\mathsf{IssueAuthSig.Validate} \;{\small ⦂}\; (\mathsf{ik} \;{\small ⦂}\; \mathsf{IssueAuthSig.Public}) \times (M \;{\small ⦂}\; \mathsf{IssueAuthSig.Message}) \times (\text{σ} \;{\small ⦂}\; \mathsf{IssueAuthSig.Signature}) \to \mathbb{B}$ as: -* Return :math:`0` if :math:`\text{σ} = \bot\!`. -* Return :math:`1` if :math:`\mathsf{Verify}(\mathsf{ik}, M, \text{σ})` succeeds, otherwise :math:`0\!`. +* Return $0$ if $\text{σ} = \bot$. +* Return $1$ if $\mathsf{Verify}(\mathsf{ik}, M, \text{σ})$ succeeds, otherwise $0$. -where the :math:`\mathsf{Verify}` algorithm is defined in BIP 340 [#bip-0340]_. +where the $\mathsf{Verify}$ algorithm is defined in BIP 340 [#bip-0340]_. Specification: Asset Identifier =============================== -For every new Asset, there MUST be a new and unique Asset Identifier, denoted :math:`\mathsf{AssetId}\!`. We define this to be a globally unique pair :math:`\mathsf{AssetId} := (\mathsf{ik}, \mathsf{asset\_desc})\!`, where :math:`\mathsf{ik}` is the issuance key and :math:`\mathsf{asset\_desc}` is a byte string. +For every new Asset, there MUST be a new and unique Asset Identifier, denoted $\mathsf{AssetId}$. We define this to be a globally unique pair $\mathsf{AssetId} := (\mathsf{ik}, \mathsf{asset\_desc})$, where $\mathsf{ik}$ is the issuance key and $\mathsf{asset\_desc}$ is a byte string. -A given Asset Identifier is used across all Zcash protocols that support ZSAs -- that is, the OrchardZSA protocol and potentially future Zcash shielded protocols. For this Asset Identifier, we derive an Asset Digest, :math:`\mathsf{AssetDigest}\!`, which is simply is a :math:`\textsf{BLAKE2b-512}` hash of the Asset Identifier. +A given Asset Identifier is used across all Zcash protocols that support ZSAs -- that is, the OrchardZSA protocol and potentially future Zcash shielded protocols. For this Asset Identifier, we derive an Asset Digest, $\mathsf{AssetDigest}$, which is simply is a $\textsf{BLAKE2b-512}$ hash of the Asset Identifier. From the Asset Digest, we derive a specific Asset Base within each shielded protocol using the applicable hash-to-curve algorithm. This Asset Base is included in shielded notes. Let -- :math:`\mathsf{asset\_desc}` be the asset description, which includes any information pertaining to the issuance, and is a byte sequence of up to 512 bytes which SHOULD be a well-formed UTF-8 code unit sequence according to Unicode 15.0.0 or later. -- :math:`\mathsf{ik}` be the issuance validating key of the issuer, a public key used to verify the signature on the issuance transaction's SIGHASH. +- $\mathsf{asset\_desc}$ be the asset description, which includes any information pertaining to the issuance, and is a byte sequence of up to 512 bytes which SHOULD be a well-formed UTF-8 code unit sequence according to Unicode 15.0.0 or later. +- $\mathsf{ik}$ be the issuance validating key of the issuer, a public key used to verify the signature on the issuance transaction's SIGHASH. -Define :math:`\mathsf{AssetDigest_{AssetId}} := \textsf{BLAKE2b-512}(\texttt{"ZSA-Asset-Digest"},\; \mathsf{EncodeAssetId}(\mathsf{AssetId}))\!`, +Define $\mathsf{AssetDigest_{AssetId}} := \textsf{BLAKE2b-512}(\texttt{“ZSA-Asset-Digest”},\; \mathsf{EncodeAssetId}(\mathsf{AssetId}))$, where -- :math:`\mathsf{EncodeAssetId}(\mathsf{AssetId}) = \mathsf{EncodeAssetId}((\mathsf{ik}, \mathsf{asset\_desc})) := \mathtt{0x00} || \mathsf{ik} || \mathsf{asset\_desc}\!\!`. -- Note that the initial :math:`\mathtt{0x00}` byte is a version byte. +- $\mathsf{EncodeAssetId}(\mathsf{AssetId}) = \mathsf{EncodeAssetId}((\mathsf{ik}, \mathsf{asset\_desc})) := \mathtt{0x00} || \mathsf{ik} || \mathsf{asset\_desc}\!$. +- Note that the initial $\mathtt{0x00}$ byte is a version byte. -Define :math:`\mathsf{AssetBase_{AssetId}} := \mathsf{ZSAValueBase}(\mathsf{AssetDigest_{AssetId}})` +Define $\mathsf{AssetBase_{AssetId}} := \mathsf{ZSAValueBase}(\mathsf{AssetDigest_{AssetId}})$ -In the case of the OrchardZSA protocol, we define :math:`\mathsf{ZSAValueBase}(\mathsf{AssetDigest_{AssetId}}) := \mathsf{GroupHash}^\mathbb{P}(\texttt{"z.cash:OrchardZSA"}, \mathsf{AssetDigest_{AssetId}})` -where :math:`\mathsf{GroupHash}^\mathbb{P}` is defined as in [#protocol-concretegrouphashpallasandvesta]_. +In the case of the OrchardZSA protocol, we define $\mathsf{ZSAValueBase}(\mathsf{AssetDigest_{AssetId}}) := \mathsf{GroupHash}^\mathbb{P}(\texttt{"z.cash:OrchardZSA"}, \mathsf{AssetDigest_{AssetId}})$ +where $\mathsf{GroupHash}^\mathbb{P}$ is defined as in [#protocol-concretegrouphashpallasandvesta]_. The relations between the Asset Identifier, Asset Digest, and Asset Base are shown in the following diagram: @@ -216,9 +216,9 @@ The relations between the Asset Identifier, Asset Digest, and Asset Base are sho Diagram relating the Asset Identifier, Asset Digest, and Asset Base in the OrchardZSA Protocol -**Note:** To keep notations light and concise, we may omit :math:`\mathsf{AssetId}` (resp. :math:`\mathsf{Protocol}\!`) in the subscript (resp. superscript) when the Asset Identifier (resp. Protocol) is clear from the context. +**Note:** To keep notations light and concise, we may omit $\mathsf{AssetId}$ (resp. $\mathsf{Protocol}$) in the subscript (resp. superscript) when the Asset Identifier (resp. Protocol) is clear from the context. -Wallets MUST NOT display just the :math:`\mathsf{asset\_desc}` string to their users as the name of the Asset. Some possible alternatives include: +Wallets MUST NOT display just the $\mathsf{asset\_desc}$ string to their users as the name of the Asset. Some possible alternatives include: - Wallets could allow clients to provide an additional configuration file that stores a one-to-one mapping of names to Asset Identifiers via a petname system. This allows clients to rename the Assets in a way they find useful. Default versions of this file with well-known Assets listed can be made available online as a starting point for clients. - The Asset Digest could be used as a more compact bytestring to uniquely determine an Asset, and wallets could support clients scanning QR codes to load Asset information into their wallets. @@ -237,12 +237,12 @@ Issuance Action Description An issuance action, ``IssueAction``, is the instance of issuing a specific Custom Asset, and contains the following fields: -- ``assetDescSize``: the size of the Asset description, a number between :math:`0` and :math:`512\!`. +- ``assetDescSize``: the size of the Asset description, a number between $0$ and $512$. - ``asset_desc``: the Asset description, a byte string of up to 512 bytes as defined in the `Specification: Asset Identifier`_ section. - ``vNotes``: an array of ``Note`` containing the unencrypted output notes of the recipients of the Asset. -- ``flagsIssuance``: a byte that stores the :math:`\mathsf{finalize}` boolean that defines whether the issuance of that specific Custom Asset is finalized or not. +- ``flagsIssuance``: a byte that stores the $\mathsf{finalize}$ boolean that defines whether the issuance of that specific Custom Asset is finalized or not. -The :math:`\mathsf{finalize}` boolean is set by the Issuer to signal that there will be no further issuance of the specific Custom Asset. +The $\mathsf{finalize}$ boolean is set by the Issuer to signal that there will be no further issuance of the specific Custom Asset. As we will see in `Specification: Consensus Rule Changes`_, transactions that attempt to issue further amounts of a Custom Asset that has previously been finalized will be rejected. The complete encoding of these fields into an ``IssueAction`` is defined in ZIP 230 [#zip-0230-issuance-action-description]_. @@ -257,9 +257,9 @@ An issuance bundle is the aggregate of all the issuance-related information. Specifically, contains all the issuance actions and the issuer signature on the transaction SIGHASH that validates the issuance itself. It contains the following fields: -- :math:`\mathsf{ik}`: the issuance validating key, that allows the validators to verify that the :math:`\mathsf{AssetId}` is properly associated with the issuer. +- $\mathsf{ik}$: the issuance validating key, that allows the validators to verify that the $\mathsf{AssetId}$ is properly associated with the issuer. - ``vIssueActions``: an array of issuance actions, of type ``IssueAction``. -- :math:`\mathsf{issueAuthSig}`: the signature of the transaction SIGHASH, signed by the issuance authorizing key, :math:`\mathsf{isk}\!`, that validates the issuance. +- $\mathsf{issueAuthSig}$: the signature of the transaction SIGHASH, signed by the issuance authorizing key, $\mathsf{isk}$, that validates the issuance. The issuance bundle is added within the transaction format as a new bundle. The detailed encoding of the issuance bundle as a part of the V6 transaction format is defined in ZIP 230 [#zip-0230-transaction-format]_. @@ -270,21 +270,21 @@ The issuer program performs the following operations: For all actions ``IssueAction``: -- encode :math:`\mathsf{asset\_desc}` as a UTF-8 byte string of size up to 512. -- compute :math:`\mathsf{AssetDigest}` from the issuance validating key :math:`\mathsf{ik}` and :math:`\mathsf{asset\_desc}` as decribed in the `Specification: Asset Identifier`_ section. -- compute :math:`\mathsf{AssetBase}` from :math:`\mathsf{AssetDigest}` as decribed in the `Specification: Asset Identifier`_ section. -- set the :math:`\mathsf{finalize}` boolean as desired (if more issuance actions are to be created for this :math:`\mathsf{AssetBase}\!`, set :math:`\mathsf{finalize} = 0\!`, otherwise set :math:`\mathsf{finalize} = 1\!`). -- for each recipient :math:`i`: +- encode $\mathsf{asset\_desc}$ as a UTF-8 byte string of size up to 512. +- compute $\mathsf{AssetDigest}$ from the issuance validating key $\mathsf{ik}$ and $\mathsf{asset\_desc}$ as decribed in the `Specification: Asset Identifier`_ section. +- compute $\mathsf{AssetBase}$ from $\mathsf{AssetDigest}$ as decribed in the `Specification: Asset Identifier`_ section. +- set the $\mathsf{finalize}$ boolean as desired (if more issuance actions are to be created for this $\mathsf{AssetBase}$, set $\mathsf{finalize} = 0$, otherwise set $\mathsf{finalize} = 1$). +- for each recipient $i$: - - generate a ZSA output note that includes the Asset Base. For an OrchardZSA note this is :math:`\mathsf{note}_i = (\mathsf{d}_i, \mathsf{pk}_{\mathsf{d}_i}, \mathsf{v}_i, \text{ρ}_i, \mathsf{rseed}_i, \mathsf{AssetBase}, \mathsf{rcm}_i)\!`. + - generate a ZSA output note that includes the Asset Base. For an OrchardZSA note this is $\mathsf{note}_i = (\mathsf{d}_i, \mathsf{pk}_{\mathsf{d}_i}, \mathsf{v}_i, \text{ρ}_i, \mathsf{rseed}_i, \mathsf{AssetBase}, \mathsf{rcm}_i)$. - encode the ``IssueAction`` into the vector ``vIssueActions`` of the bundle. For the ``IssueBundle``: - encode the ``vIssueActions`` vector. -- encode the :math:`\mathsf{ik}` as 32 byte-string. -- sign the SIGHASH transaction hash with the issuance authorizing key, :math:`\mathsf{isk}\!`, using the :math:`\mathsf{IssueAuthSig}` signature scheme. The signature is then added to the issuance bundle. +- encode the $\mathsf{ik}$ as 32 byte-string. +- sign the SIGHASH transaction hash with the issuance authorizing key, $\mathsf{isk}$, using the $\mathsf{IssueAuthSig}$ signature scheme. The signature is then added to the issuance bundle. **Note:** that the commitment is not included in the ``IssuanceAction`` itself. As explained below, it is computed later by the validators and added to the note commitment tree. @@ -294,22 +294,22 @@ Specification: Global Issuance State Issuance requires the following additions to the global state: -A map, :math:`\mathsf{issued\_assets} : \mathbb{P}^* \to \{0 .. \mathsf{MAX\_ISSUE}\} \times \mathbb{B} \!`, from the Asset Base, :math:`\mathsf{AssetBase} : \mathbb{P}^*`, to a tuple :math:`(\mathsf{balance}, \mathsf{final})\!`, for every Asset that has been issued. -We use the notation :math:`\mathsf{issued\_assets}(\mathsf{AssetBase}).\!\mathsf{balance}` and :math:`\mathsf{issued\_assets}(\mathsf{AssetBase}).\!\mathsf{final}` to access, respectively, the elements of the tuple stored in the global state for a given :math:`\mathsf{AssetBase}\!`. -If :math:`\mathsf{issued\_assets}(\mathsf{AssetBase}) = \bot\!`, it is assumed that :math:`\mathsf{issued\_assets}(\mathsf{AssetBase}).\!\mathsf{balance} = 0` and :math:`\mathsf{issued\_assets}(\mathsf{AssetBase}).\!\mathsf{final} = 0\!`. +A map, $\mathsf{issued\_assets} : \mathbb{P}^* \to \{0 .. \mathsf{MAX\_ISSUE}\} \times \mathbb{B}$, from the Asset Base, $\mathsf{AssetBase} : \mathbb{P}^*$, to a tuple $(\mathsf{balance}, \mathsf{final})$, for every Asset that has been issued. +We use the notation $\mathsf{issued\_assets}(\mathsf{AssetBase}).\!\mathsf{balance}$ and $\mathsf{issued\_assets}(\mathsf{AssetBase}).\!\mathsf{final}$ to access, respectively, the elements of the tuple stored in the global state for a given $\mathsf{AssetBase}$. +If $\mathsf{issued\_assets}(\mathsf{AssetBase}) = \bot$, it is assumed that $\mathsf{issued\_assets}(\mathsf{AssetBase}).\!\mathsf{balance} = 0$ and $\mathsf{issued\_assets}(\mathsf{AssetBase}).\!\mathsf{final} = 0$. -For any Asset represented by :math:`\mathsf{AssetBase}\!`: +For any Asset represented by $\mathsf{AssetBase}$: -- :math:`\mathsf{issued\_assets}(\mathsf{AssetBase}).\!\mathsf{balance} \in \{0 .. \mathsf{MAX\_ISSUE}\}` stores the amount of the Asset in circulation, computed as the amount of the Asset that has been issued less the amount of the Asset that has been burnt. -- :math:`\mathsf{issued\_assets}(\mathsf{AssetBase}).\!\mathsf{final} : \mathbb{B}` is a Boolean that stores the finalization status of the Asset (i.e.: whether the :math:`\mathsf{finalize}` flag has been set to :math:`1` in any preceding issuance transaction for the Asset). The value of :math:`\mathsf{issued\_assets}(\mathsf{AssetBase}).\!\mathsf{final}` for any :math:`\mathsf{AssetBase}` cannot be changed from :math:`1` to :math:`0\!`. +- $\mathsf{issued\_assets}(\mathsf{AssetBase}).\!\mathsf{balance} \in \{0 .. \mathsf{MAX\_ISSUE}\}$ stores the amount of the Asset in circulation, computed as the amount of the Asset that has been issued less the amount of the Asset that has been burnt. +- $\mathsf{issued\_assets}(\mathsf{AssetBase}).\!\mathsf{final} : \mathbb{B}$ is a Boolean that stores the finalization status of the Asset (i.e.: whether the $\mathsf{finalize}$ flag has been set to $1$ in any preceding issuance transaction for the Asset). The value of $\mathsf{issued\_assets}(\mathsf{AssetBase}).\!\mathsf{final}$ for any $\mathsf{AssetBase}$ cannot be changed from $1$ to $0$. -The maximum total supply of any issued Custom Asset is denoted by the constant :math:`\mathsf{MAX\_ISSUE} := 2^{64} - 1 \!`. +The maximum total supply of any issued Custom Asset is denoted by the constant $\mathsf{MAX\_ISSUE} := 2^{64} - 1$. Management of the Global Issuance State --------------------------------------- -The issuance state, that is, the :math:`\mathsf{issued\_assets}` map, MUST be updated by a node during the processing of any transaction that contains burn information, or an issuance bundle. +The issuance state, that is, the $\mathsf{issued\_assets}$ map, MUST be updated by a node during the processing of any transaction that contains burn information, or an issuance bundle. The issuance state is chained as follows: - The issuance state for the first block post the activation of the OrchardZSA protocol is the empty map. @@ -318,7 +318,7 @@ The issuance state is chained as follows: - The final issuance state of a block is the output issuance state of the last transaction in the block. We describe the consensus rule changes that govern the management of the global issuance state in the `Specification: Consensus Rule Changes`_ section. -We use :math:`\mathsf{issued\_assets}_{\mathsf{IN}}` and :math:`\mathsf{issued\_assets}_{\mathsf{OUT}}\!` to denote the input issuance state and output issuance state for a transaction, respectively. +We use $\mathsf{issued\_assets}_{\mathsf{IN}}$ and $\mathsf{issued\_assets}_{\mathsf{OUT}}$ to denote the input issuance state and output issuance state for a transaction, respectively. Specification: Consensus Rule Changes @@ -326,24 +326,24 @@ Specification: Consensus Rule Changes For every transaction: -- The output issuance state of the transaction MUST be initialized to be the same as the input issuance state, :math:`\mathsf{issued\_assets}_{\mathsf{OUT}} = \mathsf{issued\_assets}_{\mathsf{IN}}\!`. -- The :math:`\mathsf{assetBurn}` set MUST satisfy the consensus rules specified in ZIP 226 [#zip-0226-assetburn]_. -- It MUST be the case that for all :math:`(\mathsf{AssetBase}, \mathsf{v}) \in \mathsf{assetBurn}\!`, :math:`\mathsf{issued\_assets}_{\mathsf{OUT}}(\mathsf{AssetBase}).\!\mathsf{balance} \geq \mathsf{v}\!`. The node then MUST update :math:`\mathsf{issued\_assets}_{\mathsf{OUT}}(\mathsf{AssetBase})` prior to processing the issuance bundle in the following manner. For every :math:`(\mathsf{AssetBase}, \mathsf{v}) \in \mathsf{AssetBurn}\!`, :math:`\mathsf{issued\_assets}_{\mathsf{OUT}}(\mathsf{AssetBase}).\!\mathsf{balance} = \mathsf{issued\_assets}_{\mathsf{OUT}}(\mathsf{AssetBase}).\!\mathsf{balance} - \mathsf{v}\!`. -- Let :math:`\mathsf{SigHash}` be the SIGHASH transaction hash of this transaction, as defined in §4.10 of the protocol specification [#protocol-sighash]_ with the modifications described in ZIP 226 [#zip-0226-txiddigest]_, using :math:`\mathsf{SIGHASH\_ALL}\!`. -- The issuance authorization signature, :math:`\mathsf{issueAuthSig}\!`, MUST be a valid :math:`\mathsf{IssueAuthSig}` signature over :math:`\mathsf{SigHash}\!`, i.e. :math:`\mathsf{IssueAuthSig}.\!\mathsf{Validate}(\mathsf{ik}, \mathsf{SigHash}, \mathsf{issueAuthSig}) = 1\!`. -- For every issuance action description (:math:`\!\mathsf{IssueAction}_\mathsf{i},\ 1 \leq i \leq \mathtt{nIssueActions}\!`) in the issuance bundle: - - - It MUST be the case that :math:`0 < \mathtt{assetDescSize} \leq 512\!`. - - It MUST be the case that :math:`\mathsf{asset\_desc}` is a string of length :math:`\mathtt{assetDescSize}` bytes. - - Elements of every issue note description in ``IssueAction`` MUST be valid encodings of the types given in `Issue Note Description`_, and MUST encode the same :math:`\mathsf{AssetBase}`. - - This :math:`\mathsf{AssetBase}` MUST satisfy the derivation from the issuance validating key and asset description described in the `Specification: Asset Identifier`_ section. - - It MUST be the case that :math:`\mathsf{issued\_assets}_{\mathsf{OUT}}(\mathsf{AssetBase}).\!\mathsf{final} \neq 1\!`. - - For every issue note description (:math:`\!\mathsf{note}_{\mathsf{j}},\ 1 \leq j \leq \mathtt{nNotes}\!`) in ``IssueAction``: - - - It MUST be the case that :math:`\mathsf{issued\_assets}_{\mathsf{OUT}}.\!\mathsf{balance} + \mathsf{v} \leq \mathsf{MAX\_ISSUE}\!`, where :math:`\mathsf{v}` is the value of :math:`\mathsf{note}_{\mathsf{j}}`. The node then MUST update :math:`\mathsf{issued\_assets}_{\mathsf{OUT}}.\!\mathsf{balance} = \mathsf{issued\_assets}_{\mathsf{OUT}}.\!\mathsf{balance} + \mathsf{v}\!`. - - The node MUST compute the note commitment, :math:`\mathsf{cm}_{\mathsf{i,j}}\!`, as defined in the Note Structure and Commitment section of ZIP 226 [#zip-0226-notestructure]_. - - If :math:`\mathsf{finalize} = 1` within the ``flagsIssuance`` field of ``IssueAction``, the node MUST set :math:`\mathsf{issued\_assets}_{\mathsf{OUT}}(\mathsf{AssetBase}).\!\mathsf{final} = 1\!`. -- If all the consensus rules are satisfied, the node MUST add the note commitments, :math:`\mathsf{cm}_{\mathsf{i,j}}\ \forall\ \mathsf{i} \in \{1..\mathtt{nIssueActions}\},\ \mathsf{j} \in \{1..\mathtt{nNotes}\}\!`, to the Merkle tree of note commitments. +- The output issuance state of the transaction MUST be initialized to be the same as the input issuance state, $\mathsf{issued\_assets}_{\mathsf{OUT}} = \mathsf{issued\_assets}_{\mathsf{IN}}$. +- The $\mathsf{assetBurn}$ set MUST satisfy the consensus rules specified in ZIP 226 [#zip-0226-assetburn]_. +- It MUST be the case that for all $(\mathsf{AssetBase}, \mathsf{v}) \in \mathsf{assetBurn}$, $\mathsf{issued\_assets}_{\mathsf{OUT}}(\mathsf{AssetBase}).\!\mathsf{balance} \geq \mathsf{v}$. The node then MUST update $\mathsf{issued\_assets}_{\mathsf{OUT}}(\mathsf{AssetBase})$ prior to processing the issuance bundle in the following manner. For every $(\mathsf{AssetBase}, \mathsf{v}) \in \mathsf{AssetBurn}$, $\mathsf{issued\_assets}_{\mathsf{OUT}}(\mathsf{AssetBase}).\!\mathsf{balance} = \mathsf{issued\_assets}_{\mathsf{OUT}}(\mathsf{AssetBase}).\!\mathsf{balance} - \mathsf{v}$. +- Let $\mathsf{SigHash}$ be the SIGHASH transaction hash of this transaction, as defined in §4.10 of the protocol specification [#protocol-sighash]_ with the modifications described in ZIP 226 [#zip-0226-txiddigest]_, using $\mathsf{SIGHASH\_ALL}$. +- The issuance authorization signature, $\mathsf{issueAuthSig}$, MUST be a valid $\mathsf{IssueAuthSig}$ signature over $\mathsf{SigHash}$, i.e. $\mathsf{IssueAuthSig}.\!\mathsf{Validate}(\mathsf{ik}, \mathsf{SigHash}, \mathsf{issueAuthSig}) = 1$. +- For every issuance action description ($\mathsf{IssueAction}_\mathsf{i},\ 1 \leq i \leq \mathtt{nIssueActions}$) in the issuance bundle: + + - It MUST be the case that $0 < \mathtt{assetDescSize} \leq 512$. + - It MUST be the case that $\mathsf{asset\_desc}$ is a string of length $\mathtt{assetDescSize}$ bytes. + - Elements of every issue note description in ``IssueAction`` MUST be valid encodings of the types given in `Issue Note Description`_, and MUST encode the same $\mathsf{AssetBase}$. + - This $\mathsf{AssetBase}$ MUST satisfy the derivation from the issuance validating key and asset description described in the `Specification: Asset Identifier`_ section. + - It MUST be the case that $\mathsf{issued\_assets}_{\mathsf{OUT}}(\mathsf{AssetBase}).\!\mathsf{final} \neq 1$. + - For every issue note description ($\mathsf{note}_{\mathsf{j}},\ 1 \leq j \leq \mathtt{nNotes}$) in ``IssueAction``: + + - It MUST be the case that $\mathsf{issued\_assets}_{\mathsf{OUT}}.\!\mathsf{balance} + \mathsf{v} \leq \mathsf{MAX\_ISSUE}$, where $\mathsf{v}$ is the value of $\mathsf{note}_{\mathsf{j}}$. The node then MUST update $\mathsf{issued\_assets}_{\mathsf{OUT}}.\!\mathsf{balance} = \mathsf{issued\_assets}_{\mathsf{OUT}}.\!\mathsf{balance} + \mathsf{v}$. + - The node MUST compute the note commitment, $\mathsf{cm}_{\mathsf{i,j}}$, as defined in the Note Structure and Commitment section of ZIP 226 [#zip-0226-notestructure]_. + - If $\mathsf{finalize} = 1$ within the ``flagsIssuance`` field of ``IssueAction``, the node MUST set $\mathsf{issued\_assets}_{\mathsf{OUT}}(\mathsf{AssetBase}).\!\mathsf{final} = 1$. +- If all the consensus rules are satisfied, the node MUST add the note commitments, $\mathsf{cm}_{\mathsf{i,j}}\ \forall\ \mathsf{i} \in \{1..\mathtt{nIssueActions}\},\ \mathsf{j} \in \{1..\mathtt{nNotes}\}$, to the Merkle tree of note commitments. - (Replay Protection) If an issue bundle is present, the fees MUST be greater than zero. @@ -354,14 +354,14 @@ The following is a list of rationale for different decisions made in the proposa - The issuance key structure is independent of the original key tree, but derived in an analogous manner (via ZIP 32). This keeps the issuance details and the Asset Identifiers consistent across multiple shielded pools. It also separates the issuance authority from the spend authority, allowing for the potential transfer of issuance authority without compromising the spend authority. - The Custom Asset is described via a combination of the issuance validating key and an asset description string, to preclude the possibility of two different issuers creating colliding Custom Assets. -- The :math:`\mathsf{asset\_desc}` is a general byte string in order to allow for a wide range of information type to be included that may be associated with the Assets. Some are: +- The $\mathsf{asset\_desc}$ is a general byte string in order to allow for a wide range of information type to be included that may be associated with the Assets. Some are: - links for storage such as for NFTs. - metadata for Assets, encoded in any format. - bridging information for Wrapped Assets (chain of origin, issuer name, etc) - information to be committed by the issuer, though not enforceable by the protocol. -- We limit the size of the :math:`\mathsf{asset\_desc}` string to 512 bytes as it is a reasonable size to store metadata about the Asset, for example in JSON format. +- We limit the size of the $\mathsf{asset\_desc}$ string to 512 bytes as it is a reasonable size to store metadata about the Asset, for example in JSON format. - We require non-zero fees in the presence of an issue bundle, in order to preclude the possibility of a transaction containing only an issue bundle. If a transaction includes only an issue bundle, the SIGHASH transaction hash would be computed solely based on the issue bundle. A duplicate bundle would have the same SIGHASH transaction hash, potentially allowing for a replay attack. Rationale for Global Issuance State @@ -372,11 +372,11 @@ However, unlike for the shielded ZEC pools, there is no individual transaction f Therefore, we require that all nodes maintain a record of the current amount in circulation for every issued Custom Asset, and update this record based on the issuance and burn transactions processed. This allows for efficient detection of balance violations for any Asset, in which scenario we specify a consensus rule to reject the transaction or block. -We limit the total issuance of any Asset to a maximum of :math:`\mathsf{MAX\_ISSUE}`. +We limit the total issuance of any Asset to a maximum of $\mathsf{MAX\_ISSUE}$. This is a practical limit that also allows an issuer to issue the complete supply of an Asset in a single transaction. Nodes also need to reject transactions that issue Custom Assets that have been previously finalized. -The :math:`\mathsf{issued\_assets}` map allows nodes to store whether or not a given Asset has been finalized. +The $\mathsf{issued\_assets}$ map allows nodes to store whether or not a given Asset has been finalized. Concrete Applications @@ -384,18 +384,18 @@ Concrete Applications **Asset Features** -- By using the :math:`\mathsf{finalize}` boolean and the burning mechanism defined in [#zip-0226]_, issuers can control the supply production of any Asset associated to their issuer keys. For example, +- By using the $\mathsf{finalize}$ boolean and the burning mechanism defined in [#zip-0226]_, issuers can control the supply production of any Asset associated to their issuer keys. For example, - - by setting :math:`\mathsf{finalize} = 1` from the first issuance action for that Asset Identifier, the issuer is in essence creating a one-time issuance transaction. This is useful when the max supply is capped from the beginning and the distribution is known in advance. All tokens are issued at once and distributed as needed. + - by setting $\mathsf{finalize} = 1$ from the first issuance action for that Asset Identifier, the issuer is in essence creating a one-time issuance transaction. This is useful when the max supply is capped from the beginning and the distribution is known in advance. All tokens are issued at once and distributed as needed. - Issuers can also stop the existing supply production of any Asset associated to their issuer keys. This could be done by - - issuing a last set of tokens of that specific :math:`\mathsf{AssetId}\!`, for which :math:`\mathsf{finalize} = 1\!`, or by - - issuing a transaction with a single note in the issuance action pertaining to that :math:`\mathsf{AssetId}\!`, where the note will contain a :math:`\mathsf{value} = 0\!`. This can be used for application-specific purposes (NFT collections) or for security purposes to revoke the Asset issuance (see Security and Privacy Considerations). + - issuing a last set of tokens of that specific $\mathsf{AssetId}$, for which $\mathsf{finalize} = 1$, or by + - issuing a transaction with a single note in the issuance action pertaining to that $\mathsf{AssetId}$, where the note will contain a $\mathsf{value} = 0$. This can be used for application-specific purposes (NFT collections) or for security purposes to revoke the Asset issuance (see Security and Privacy Considerations). - The issuance and burn mechanisms can be used in conjunction to determine the supply of Assets on the Zcash ecosystem. This allows for the bridging of Assets defined on other chains. -- Furthermore, NFT issuance is enabled by issuing in a single bundle several issuance actions, where each :math:`\mathsf{AssetId}` corresponds to :math:`\mathsf{value} = 1` at the fundamental unit level. Issuers and users should make sure that :math:`\mathsf{finalize} = 1` for each of the actions in this scenario. +- Furthermore, NFT issuance is enabled by issuing in a single bundle several issuance actions, where each $\mathsf{AssetId}$ corresponds to $\mathsf{value} = 1$ at the fundamental unit level. Issuers and users should make sure that $\mathsf{finalize} = 1$ for each of the actions in this scenario. @@ -490,7 +490,7 @@ T.5a.iii: flagsIssuance ''''''''''''''''''''''' An 8-bit value representing a set of flags. Ordered from LSB to MSB: -- :math:`\mathsf{finalize}` +- $\mathsf{finalize}$ - The remaining bits are set to `0\!`. @@ -562,7 +562,7 @@ Parameter Value :math:`issuance\_fee` :math:`100 \cdot marginal\_fee` per issuance action (as defined below) ===================================== ========================================================================== -Wallets implementing this specification SHOULD use a conventional fee, viz. :math:`zsa\_conventional\_fee`, that is +Wallets implementing this specification SHOULD use a conventional fee, viz. $zsa\_conventional\_fee$, that is calculated in zatoshis. Additional definitions that are used in the formula for the calculation are in the table below: ================================ ====== ==================================================================================================================== @@ -575,14 +575,14 @@ Input Units Description The other inputs to this formula are taken from transaction fields defined in the Zcash protocol specification [#protocol-txnencoding]_ and the global state. They are defined in the Fee calculation section of ZIP 317 [#zip-0317-fee-calc]_. -Note that :math:`nOrchardActions`, that is used in the computation of :math:`logical\_actions`, is redefined in the above table, and now combines the actions for native ZEC as well as OrchardZSA transfer actions for Custom Assets. +Note that $nOrchardActions$, that is used in the computation of $logical\_actions$, is redefined in the above table, and now combines the actions for native ZEC as well as OrchardZSA transfer actions for Custom Assets. -The formula for the computation of the :math:`zsa\_logical\_actions` (with the updated computation of :math:`logical\_actions` as described above) is: +The formula for the computation of the $zsa\_logical\_actions$ (with the updated computation of $logical\_actions$ as described above) is: .. math:: zsa\_logical\_actions = logical\_actions \;+ nTotalOutputsZSAIssuance -The formula for the computation of the :math:`zsa\_conventional\_fee` is: +The formula for the computation of the $zsa\_conventional\_fee$ is: .. math:: \begin{array}{rcl} @@ -629,7 +629,7 @@ Issuance Key Compromise The design of this protocol does not currently allow for rotation of the issuance validating key that would allow for replacing the key of a specific Asset. In case of compromise, the following actions are recommended: -- If an issuance validating key is compromised, the :math:`\mathsf{finalize}` boolean for all the Assets issued with that key should be set to :math:`1` and the issuer should change to a new issuance authorizing key, and issue new Assets, each with a new :math:`\mathsf{AssetId}\!`. +- If an issuance validating key is compromised, the $\mathsf{finalize}$ boolean for all the Assets issued with that key should be set to $1$ and the issuer should change to a new issuance authorizing key, and issue new Assets, each with a new $\mathsf{AssetId}$. Bridging Assets --------------- @@ -642,7 +642,7 @@ Other Considerations Implementing Zcash Nodes ------------------------ -Although not enforced in the global state, it is RECOMMENDED that Zcash full validators keep track of the total supply of Assets as a mutable mapping :math:`\mathsf{issuanceSupplyInfoMap}` from :math:`\mathsf{AssetId}` to :math:`(\mathsf{totalSupply}, \mathsf{finalize})` in order to properly keep track of the total supply for different Asset Identifiers. This is useful for wallets and other applications that need to keep track of the total supply of Assets. +Although not enforced in the global state, it is RECOMMENDED that Zcash full validators keep track of the total supply of Assets as a mutable mapping $\mathsf{issuanceSupplyInfoMap}$ from $\mathsf{AssetId}$ to $(\mathsf{totalSupply}, \mathsf{finalize})$ in order to properly keep track of the total supply for different Asset Identifiers. This is useful for wallets and other applications that need to keep track of the total supply of Assets. Fee Structures -------------- @@ -690,6 +690,7 @@ References .. [#zip-0244] `ZIP 244: Transaction Identifier Non-Malleability `_ .. [#zip-0244-sigdigest] `ZIP 244: Transaction Identifier Non-Malleability: Signature Digest `_ .. [#zip-0317-fee-calc] `ZIP 317: Proportional Transfer Fee Mechanism, Fee calculation `_ +.. [#bip-0043] `BIP 43: Purpose Field for Deterministic Wallets `_ .. [#bip-0340] `BIP 340: Schnorr Signatures for secp256k1 `_ .. [#protocol-notation] `Zcash Protocol Specification, Version 2024.5.1 [NU6]. Section 2: Notation `_ .. [#protocol-addressesandkeys] `Zcash Protocol Specification, Version 2024.5.1 [NU6]. Section 3.1: Payment Addresses and Keys `_ diff --git a/zips/zip-0230.rst b/zips/zip-0230.rst index 5d0bfce85..5d24ae7e9 100644 --- a/zips/zip-0230.rst +++ b/zips/zip-0230.rst @@ -201,10 +201,10 @@ Transaction Format * The fields ``valueBalanceSapling`` and ``bindingSigSapling`` are present if and only if - :math:`\mathtt{nSpendsSapling} + \mathtt{nOutputsSapling} > 0\!`. If ``valueBalanceSapling`` - is not present, then :math:`\mathsf{v^{balanceSapling}}`` is defined to be :math:`0\!`. + $\mathtt{nSpendsSapling} + \mathtt{nOutputsSapling} > 0$. If ``valueBalanceSapling`` + is not present, then $\mathsf{v^{balanceSapling}}$ is defined to be $0$. -* The field ``anchorSapling`` is present if and only if :math:`\mathtt{nSpendsSapling} > 0\!`. +* The field ``anchorSapling`` is present if and only if $\mathtt{nSpendsSapling} > 0$. * The elements of ``vSpendProofsSapling`` and ``vSpendAuthSigsSapling`` have a 1:1 correspondence to the elements of ``vSpendsSapling`` and MUST be ordered such that the @@ -216,12 +216,12 @@ Transaction Format to the ``OutputDescriptionV6`` at the same index. * The fields ``valueBalanceOrchard`` and ``bindingSigOrchard`` are present if and - only if :math:`\mathtt{nActionGroupsOrchard} > 0\!`. If ``valueBalanceOrchard`` is not present, - then :math:`\mathsf{v^{balanceOrchard}}` is defined to be :math:`0\!`. + only if $\mathtt{nActionGroupsOrchard} > 0$. If ``valueBalanceOrchard`` is not present, + then $\mathsf{v^{balanceOrchard}}$ is defined to be $0$. -* The fields ``ik`` and ``issueAuthSig`` are present if and only if :math:`\mathtt{nIssueActions} > 0\!`. +* The fields ``ik`` and ``issueAuthSig`` are present if and only if $\mathtt{nIssueActions} > 0$. -* For coinbase transactions, the ``enableSpendsOrchard`` and ``enableZSAs`` bits MUST be set to :math:`0\!`. +* For coinbase transactions, the ``enableSpendsOrchard`` and ``enableZSAs`` bits MUST be set to $0$. The encodings of ``tx_in``, and ``tx_out`` are as in a version 4 transaction (i.e. unchanged from Canopy). The encodings of ``SpendDescriptionV6``, ``OutputDescriptionV6`` @@ -418,6 +418,13 @@ An issuance note, ``IssueNote`` contains the following fields: +-----------------------------+--------------------------+--------------------------------------+--------------------------------------------------------------------+ +Deployment +========== + +Version 6 transactions are proposed to be allowed on the network starting from +Network Upgrade 7. [#zip-0254]_ + + Reference implementation ======================== @@ -438,5 +445,6 @@ References .. [#zip-0227] `ZIP 227: Issuance of Zcash Shielded Assets `_ .. [#zip-0228] `ZIP 228: Asset Swaps for Zcash Shielded Assets `_ .. [#zip-0244] `ZIP 244: Transaction Identifier Non-Malleability `_ +.. [#zip-0254] `ZIP 254: Deployment of the NU7 Network Upgrade `_ .. [#zip-0317] `ZIP 317: Proportional Transfer Fee Mechanism `_ .. [#zip-0317-fee-calc] `ZIP 317: Proportional Transfer Fee Mechanism, Fee calculation `_ diff --git a/zips/zip-0231.md b/zips/zip-0231.md index 924a8fc99..cf002832f 100644 --- a/zips/zip-0231.md +++ b/zips/zip-0231.md @@ -19,9 +19,15 @@ The key words "MUST", "MUST NOT", "SHOULD", and "MAY" in this document are to be interpreted as described in BCP 14 [^BCP14] when, and only when, they appear in all capitals. +The term "network upgrade" in this document is to be interpreted as described in +ZIP 200. [^zip-0200] + The character § is used when referring to sections of the Zcash Protocol Specification. [^protocol] +The terms "Mainnet" and "Testnet" are to be interpreted as described in +§ 3.12 ‘Mainnet and Testnet’. [^protocol-networks] + # Abstract @@ -80,8 +86,8 @@ while decreasing the amount of data that needs to be stored on-chain overall. - The exact number and exact lengths of distinct decryptable memos should not be revealed, even to the transaction recipients, although an upper bound on the total length of memo data that the observer does not have the capability - to view will be leaked to transaction recipients, and the overall maximum possible length of - memo data will be revealed on-chain. + to view will be leaked to transaction recipients, and the overall maximum + possible length of memo data will be revealed on-chain. - A recipient can determine whether or not they have been given the capability to view any memo solely by decrypting the note ciphertext. - Memo chunks within a transaction can be individually pruned from block storage @@ -97,7 +103,7 @@ while decreasing the amount of data that needs to be stored on-chain overall. - Recipients do not need to be able to receive multiple memos per note. This capability can however be enabled under the existing proposal by "chaining" memos, including the decryption key for another memo within the memo that - is decryptabble by a recipient. + is decryptable by a recipient. # Specification @@ -106,101 +112,6 @@ Since this proposal is defined only for v6 and later transactions, it is not necessary to consider Sprout JoinSplit outputs. The following sections apply to both Sapling and Orchard outputs. -## Changes to the Zcash Protocol Specification - -The following changes affecting the definitions of note plaintexts and note ciphertexts, -and the algorithms for encryption and decryption. - -In § 3.2.1 ‘Note Plaintexts and Memo Fields’: - -* Change - - > Each Sapling or Orchard note plaintext (denoted $\mathbf{np}$) consists of - > - > $\hspace{2em}(\mathsf{leadByte} ⦂ \mathbb{B^{Y}}, \mathsf{d} ⦂ \mathbb{B^{[\ell_{\mathsf{d}}]}}, \mathsf{rseed} ⦂ \mathbb{B^{Y[32]}}, \mathsf{memo} ⦂ \mathbb{B^{Y[512]}})$ - - to - - > The form of a Sapling or Orchard note plaintext depends on the version of - > the transaction in which it will be included; specifically whether that - > version is pre-v6, or v6-onward. - > - > Each pre-v6 Sapling or Orchard note plaintext (denoted $\mathbf{np}$) consists of - > - > $\hspace{2em}(\mathsf{leadByte} ⦂ \mathbb{B^{Y}}, \mathsf{d} ⦂ \mathbb{B^{[\ell_{\mathsf{d}}]}}, \mathsf{rseed} ⦂ \mathbb{B^{Y[32]}}, \mathsf{memo} ⦂ \mathbb{B^{Y[512]}})$ - > - > Each v6-onward Sapling or Orchard note plaintext (denoted $\mathbf{np}$) consists of - > - > $\hspace{2em}(\mathsf{leadByte} ⦂ \mathbb{B^{Y}}, \mathsf{d} ⦂ \mathbb{B^{[\ell_{\mathsf{d}}]}}, \mathsf{rseed} ⦂ \mathbb{B^{Y[32]}}, \mathsf{K^{memo}} ⦂ \mathbb{B^{Y[32]}})$ - -In § 5.5 ‘Encodings of Note Plaintexts and Memo Fields’ [^protocol-noteptencoding]: - -* Change the paragraph that describes "The encoding of a Sapling or Orchard note plaintext" - to refer to "The encoding of a pre-v6 Sapling or Orchard note plaintext". - -* Add a new paragraph at the end of the section: - - > The encoding of a v6-onward Sapling or Orchard note plaintext consists of: - > - > | | | | | | - > |---------------------------|---------------------|---------------------|--------------------------|-----------------------------| - > | 8-bit $\mathsf{leadByte}$ | 88-bit $\mathsf{d}$ | 64-bit $\mathsf{v}$ | 256-bit $\mathsf{rseed}$ | 32-byte $\mathsf{K^{memo}}$ | - > - > * A byte 0x03, indicating this version of the encoding of a v6-onward - > Sapling or Orchard note plaintext. - > * 11 bytes specifying $\mathsf{d}$. - > * 8 bytes specifying $\mathsf{v}$. - > * 32 bytes specifying $\mathsf{rseed}$. - > * 32 bytes specifying $\mathsf{K^{memo}}$. - > - > A value consisting of 32 $\mathtt{0xFF}$ bytes for $\mathsf{K^{memo}}$ is used - > to indicate that there is no memo for this note plaintext. - -In § 4.7.2 ‘Sending Notes (Sapling)’ [^protocol-saplingsend] and -§ 4.7.3 ‘Sending Notes (Orchard)’ [^protocol-orchardsend]: - -* Add a reference to this ZIP specifying the construction of the memo bundle and - derivation of $\mathsf{K^{memo}}$ in the case of a v6-onward note plaintext. - -* Change - - > Let $\mathbf{np} = (\mathsf{leadByte}, \mathsf{d}, \mathsf{v}, \mathsf{rseed}, \mathsf{memo})\!$. - - to - - > Let $\mathbf{np}$ be the encoding of a Sapling note plaintext using $\mathsf{leadByte}$, $\mathsf{d}$, - > $\mathsf{v}$, $\mathsf{rseed}$, and either $\mathsf{memo}$ for a pre-v6 note plaintext or - > $\mathsf{K^{memo}}$ for a v6-onward note plaintext. - - replacing "Sapling" with Orchard in the case of § 4.7.3. - -In § 4.20.1 ‘Encryption (Sapling and Orchard)’ [^protocol-saplingandorchardinband]: - -* Change - - > Let $\mathbf{np} = (\mathsf{leadByte}, \mathsf{d}, \mathsf{v}, \mathsf{rseed}, \mathsf{memo})$ - > be the Sapling or Orchard note plaintext. $\mathbf{np}$ is encoded as defined - > in § 5.5 ‘Encodings of Note Plaintexts and Memo Fields’. - - to - - > Let $\mathbf{np}$ be the encoding of the Sapling or Orchard note plaintext (which may be - > pre-v6 or v6-onward), as defined in § 5.5 ‘Encodings of Note Plaintexts and Memo Fields’. - -* Add another normative note to that section: - - > * $\mathsf{C^{enc}}$ will be of length either 580 or 100 bytes, depending on whether - > $\mathbf{np}$ is a pre-v6 or v6-onward note plaintext. - -In § 4.20.2 ‘Decryption using an Incoming Viewing Key (Sapling and Orchard)’ [^protocol-decryptivk] -and § 4.20.3 ‘Decryption using a Full Viewing Key (Sapling and Orchard)’ [^protocol-decryptovk]: - -* Replace $\mathsf{memo} ⦂ \mathbb{B^{Y[512]}}$ with $\mathsf{memoOrKey}$. -* Specify that the type of $\mathsf{memoOrKey}$ is $\mathbb{B^{Y[512]}}$ when - decrypting a pre-v6 note ciphertext, or $\mathbb{B^{Y[32]}}$ when decrypting a - v6-onward note ciphertext. In the latter case, it is used as $\mathsf{K^{memo}}$ - to decrypt the memo bundle as described in subsequent sections of this ZIP. - ## Memo bundle A memo bundle consists of a sequence of 256-byte memo chunks, each individually @@ -225,7 +136,7 @@ be used to encrypt more than one memo within a single transaction. If an output no memo data, it is assigned the memo key consisting of 32 $\mathtt{0xFF}$ bytes. In note plaintexts of v6-onward transactions, the 512-byte memo field is replaced -by $\mathsf{K^{memo}}\!$. +by $\mathsf{K^{memo}}$. The transaction builder generates a 32-byte salt value $\mathsf{salt}$ from a CSPRNG. A new salt MUST be generated for each memo bundle. @@ -248,12 +159,12 @@ as follows: $\hspace{2em}\mathsf{IETF\_AEAD\_CHACHA20\_POLY1305}(\mathsf{encryption\_key}, \mathsf{nonce}, \mathsf{memo\_chunk})$ -where $\mathsf{nonce} = \mathsf{I2BEOSP}_{88}(\mathsf{counter}) || [\mathsf{final\_chunk}]\!$. +where $\mathsf{nonce} = \mathsf{I2BEOSP}_{88}(\mathsf{counter}) \,||\, [\mathsf{final\_chunk}]$. This is a variant of the STREAM construction [^stream]. -- $\mathsf{counter}$ is a big-endian chunk counter starting at zero and incrementing by - one for each subsequent chunk within a particular memo. +- $\mathsf{counter}$ is a big-endian chunk counter starting at zero and incrementing + by one for each subsequent chunk within a particular memo. - $\mathsf{final\_chunk}$ is the byte $\mathtt{0x01}$ for the final memo chunk, and $\mathtt{0x00}$ for all preceding chunks. @@ -350,6 +261,105 @@ in ZIP 317 [^zip-0317]. Nodes must reject `GetData` responses having an `fAllPruned` value that is nonzero, or any byte of `pruned` that is nonzero. +## Changes to the Zcash Protocol Specification + +The following changes affecting the definitions of note plaintexts and note ciphertexts, +and the algorithms for encryption and decryption. + +In § 3.2.1 ‘Note Plaintexts and Memo Fields’: + +* Change + + > Each Sapling or Orchard note plaintext (denoted $\mathbf{np}$) consists of + > + > $\hspace{2em}(\mathsf{leadByte} \;⦂\; \mathbb{B^{Y}}, \mathsf{d} \;⦂\; \mathbb{B^{[\ell_{\mathsf{d}}]}}, \mathsf{rseed} \;⦂\; \mathbb{B^{Y[32]}}, \mathsf{memo} \;⦂\; \mathbb{B^{Y[512]}})$ + + to + + > The form of a Sapling or Orchard note plaintext depends on the version of + > the transaction in which it will be included; specifically whether that + > version is pre-v6, or v6-onward. + > + > Each pre-v6 Sapling or Orchard note plaintext (denoted $\mathbf{np}$) consists of + > + > $\hspace{2em}(\mathsf{leadByte} \;⦂\; \mathbb{B^{Y}}, \mathsf{d} \;⦂\; \mathbb{B^{[\ell_{\mathsf{d}}]}}, \mathsf{rseed} \;⦂\; \mathbb{B^{Y[32]}}, \mathsf{memo} \;⦂\; \mathbb{B^{Y[512]}})$ + > + > Each v6-onward Sapling or Orchard note plaintext (denoted $\mathbf{np}$) consists of + > + > $\hspace{2em}(\mathsf{leadByte} \;⦂\; \mathbb{B^{Y}}, \mathsf{d} \;⦂\; \mathbb{B^{[\ell_{\mathsf{d}}]}}, \mathsf{rseed} \;⦂\; \mathbb{B^{Y[32]}}, \mathsf{K^{memo}} \;⦂\; \mathbb{B^{Y[32]}})$ + +In § 5.5 ‘Encodings of Note Plaintexts and Memo Fields’ [^protocol-noteptencoding]: + +* Change the paragraph that describes "The encoding of a Sapling or Orchard note plaintext" + to refer to "The encoding of a pre-v6 Sapling or Orchard note plaintext". + +* Add a new paragraph at the end of the section: + + > The encoding of a v6-onward Sapling or Orchard note plaintext consists of: + > + > | | | | | | + > |---------------------------|---------------------|---------------------|--------------------------|-----------------------------| + > | 8-bit $\mathsf{leadByte}$ | 88-bit $\mathsf{d}$ | 64-bit $\mathsf{v}$ | 256-bit $\mathsf{rseed}$ | 32-byte $\mathsf{K^{memo}}$ | + > + > * A byte 0x03, indicating this version of the encoding of a v6-onward + > Sapling or Orchard note plaintext. + > * 11 bytes specifying $\mathsf{d}$. + > * 8 bytes specifying $\mathsf{v}$. + > * 32 bytes specifying $\mathsf{rseed}$. + > * 32 bytes specifying $\mathsf{K^{memo}}$. + > + > A value consisting of 32 $\mathtt{0xFF}$ bytes for $\mathsf{K^{memo}}$ is used + > to indicate that there is no memo for this note plaintext. + +In § 4.7.2 ‘Sending Notes (Sapling)’ [^protocol-saplingsend] and +§ 4.7.3 ‘Sending Notes (Orchard)’ [^protocol-orchardsend]: + +* Add a reference to this ZIP specifying the construction of the memo bundle and + derivation of $\mathsf{K^{memo}}$ in the case of a v6-onward note plaintext. + +* Change + + > Let $\mathbf{np} = (\mathsf{leadByte}, \mathsf{d}, \mathsf{v}, \mathsf{rseed}, \mathsf{memo})$. + + to + + > Let $\mathbf{np}$ be the encoding of a Sapling note plaintext using $\mathsf{leadByte}$, $\mathsf{d}$, + > $\mathsf{v}$, $\mathsf{rseed}$, and either $\mathsf{memo}$ for a pre-v6 note plaintext or + > $\mathsf{K^{memo}}$ for a v6-onward note plaintext. + + replacing "Sapling" with Orchard in the case of § 4.7.3. + +In § 4.20.1 ‘Encryption (Sapling and Orchard)’ [^protocol-saplingandorchardinband]: + +* Change + + > Let $\mathbf{np} = (\mathsf{leadByte}, \mathsf{d}, \mathsf{v}, \mathsf{rseed}, \mathsf{memo})$ + > be the Sapling or Orchard note plaintext. $\mathbf{np}$ is encoded as defined + > in § 5.5 ‘Encodings of Note Plaintexts and Memo Fields’. + + to + + > Let $\mathbf{np}$ be the encoding of the Sapling or Orchard note plaintext (which may be + > pre-v6 or v6-onward), as defined in § 5.5 ‘Encodings of Note Plaintexts and Memo Fields’. + +* Add another normative note to that section: + + > * $\mathsf{C^{enc}}$ will be of length either 580 or 100 bytes, depending on whether + > $\mathbf{np}$ is a pre-v6 or v6-onward note plaintext. + +In § 4.20.2 ‘Decryption using an Incoming Viewing Key (Sapling and Orchard)’ [^protocol-decryptivk] +and § 4.20.3 ‘Decryption using a Full Viewing Key (Sapling and Orchard)’ [^protocol-decryptovk]: + +* Replace $\mathsf{memo} \;⦂\; \mathbb{B^{Y[512]}}$ with $\mathsf{memoOrKey}$. +* Specify that the type of $\mathsf{memoOrKey}$ is $\mathbb{B^{Y[512]}}$ when + decrypting a pre-v6 note ciphertext, or $\mathbb{B^{Y[32]}}$ when decrypting a + v6-onward note ciphertext. In the latter case, it is used as $\mathsf{K^{memo}}$ + to decrypt the memo bundle as described in [Memo bundle]. + +## Applicability + +All of these changes apply identically to Mainnet and Testnet. + # Open issues @@ -358,6 +368,10 @@ or any byte of `pruned` that is nonzero. `memo_chunk_limit == 64` is recommended. This results in a maximum of 16 KiB of memo data per transaction. +## Interaction with ZIP 302 [^zip-0302] + +TBD + # Rationale @@ -380,10 +394,8 @@ With 10 KiB limit on amount of memo data as the constant in this table, the maximum number of unique memos you can create, and the cost in bytes of that memo data plus auth when using a 32-byte memo key, is: -| | Memo size | +| Chunk size | Memo size ≤ 256 bytes| Memo size = 512 bytes| |------------|----------------------|----------------------| -| Chunk size | ≤ 256 bytes | 512 bytes | -|============|======================|======================| | Pre-231 | 20 @ 10240 ( 0.00%) | 20 @ 10240 ( 0.00%) | | 512 | 20 @ 11220 (+ 9.57%) | 20 @ 11220 (+ 9.57%) | | 256 | 40 @ 12200 (+19.14%) | 20 @ 11540 (+12.70%) | @@ -401,10 +413,8 @@ in between). If we used a 16-byte memo key instead of 32 bytes, the transaction size overhead becomes: -| | Memo size | +| Chunk size | Memo size ≤ 256 bytes| Memo size = 512 bytes| |------------|----------------------|----------------------| -| Chunk size | ≤ 256 bytes | 512 bytes | -|============|======================|======================| | Pre-231 | 20 @ 10240 ( 0.00%) | 20 @ 10240 ( 0.00%) | | 512 | 20 @ 10900 (+ 6.45%) | 20 @ 10900 (+ 6.45%) | | 256 | 40 @ 11560 (+12.89%) | 20 @ 11220 (+ 9.57%) | @@ -486,6 +496,11 @@ Combined with the memo bundle size restriction, the maximum additional fee for a memo bundle over prior transactions is 0.0019 ZEC. +# Deployment + +This ZIP is proposed to activate with Network Upgrade 7. [^zip-0254] + + # Reference implementation TBD @@ -499,6 +514,8 @@ TBD [^protocol-noteptconcept]: [Zcash Protocol Specification, Version 2024.5.1 [NU6]. Section 3.2.1: Note Plaintexts and Memo Fields](protocol/protocol.pdf#noteptconcept) +[^protocol-networks]: [Zcash Protocol Specification, Version 2024.5.1 [NU6]. Section 3.12: Mainnet and Testnet](protocol/protocol.pdf#networks) + [^protocol-abstractprfs]: [Zcash Protocol Specification, Version 2024.5.1 [NU6]. Section 4.1.2: Pseudo Random Functions](protocol/protocol.pdf#abstractprfs) [^protocol-saplingsend]: [Zcash Protocol Specification, Version 2024.5.1 [NU6]. Section 4.7.2: Sending Notes (Sapling)](protocol/protocol.pdf#saplingsend) @@ -515,7 +532,9 @@ TBD [^protocol-inbandrationale]: [Zcash Protocol Specification, Version 2024.5.1 [NU6]. Section 8.7: In-band secret distribution](protocol/protocol.pdf#inbandrationale) -[^stream]: [Online Authenticated-Encryption and its Nonce-Reuse Misuse-Resistance](https://eprint.iacr.org/2015/189) +[^zip-0200]: [ZIP 200: Network Upgrade Mechanism](zip-0200.rst) + +[^zip-0254]: [ZIP 254: Deployment of the NU7 Network Upgrade](zip-0254.rst) [^zip-0302]: [ZIP 302: Standardized Memo Field Format](zip-0302.rst) @@ -523,6 +542,8 @@ TBD [^zip-0317]: [ZIP 317: Proportional Transfer Fee Mechanism](zip-0317.rst) +[^stream]: [Online Authenticated-Encryption and its Nonce-Reuse Misuse-Resistance](https://eprint.iacr.org/2015/189) + [^pczt]: [zcash/zips issue #693: Standardize a protocol for creating shielded transactions offline](https://github.com/zcash/zips/issues/693) [^rfc-8439]: [RFC 8439: ChaCha20 and Poly1305 for IETF Protocols](https://www.rfc-editor.org/rfc/rfc8439.html) diff --git a/zips/zip-0233.md b/zips/zip-0233.md index eaeea1aba..cb14919c2 100644 --- a/zips/zip-0233.md +++ b/zips/zip-0233.md @@ -15,35 +15,49 @@ License: BSD-2-Clause Discussions-To: ``` + # Terminology -The key words "MUST", "SHOULD", "SHOULD NOT", "MAY", "RECOMMENDED", "OPTIONAL", -and "REQUIRED" in this document are to be interpreted as described in RFC 2119. -[1] +The key word "MUST" in this document is to be interpreted as described in +BCP 14 [^BCP14] when, and only when, it appears in all capitals. + +The term "network upgrade" in this document is to be interpreted as described +in ZIP 200. [^zip-0200] + +The character § is used when referring to sections of the Zcash Protocol +Specification. [^protocol] + +The terms "Mainnet" and "Testnet" are to be interpreted as described in +§ 3.12 ‘Mainnet and Testnet’. [^protocol-networks] + +"ZEC/TAZ" refers to the native currency of Zcash on a given network, i.e. +ZEC on Mainnet and TAZ on Testnet. -The term "network upgrade" in this document is to be interpreted as described in -ZIP 200. [2] +"Block Subsidy" - The algorithmic issuance of ZEC/TAZ on block creation, as +defined by consensus. This is split between the miner and Funding Streams. -"Block Subsidy” - the algorithmic issuance of ZEC on block creation. Part of the -consensus rules. Split between the miner and the Dev Fund. Also known as Block -Reward. +"Issuance" - The method by which ZEC/TAZ becomes available for circulation +on the network. [TODO: there is a potential terminology conflict between +this and issuance as defined in ZIP 227.] -"Issuance" - The method by which ZEC becomes available for circulation on the -network. +"Burning" - The method by which ZEC/TAZ becomes unavailable for circulation +on the network. -"We" - the ZIP Owners and Authors, listed in the above front matter. +$\mathsf{MAX\_MONEY}$, as defined in § 5.3 ‘Constants’ [^protocol-constants], +is the total ZEC/TAZ supply cap measured in zatoshi, corresponding to +21,000,000 ZEC. This is slightly larger than the supply cap for the current +issuance mechanism, but is the value used in existing critical consensus +checks. -"`MAX_MONEY`" is the total ZEC supply cap, defined as 21,000,000 ZEC. This is -slightly larger than the supply cap for the current issuance mechanism, but is -the value used in existing critical consensus checks. # Abstract -We propose the introduction of a mechanism to voluntarily burn funds, removing -those funds entirely from circulation on the network. This mechanism, in -combination with ZIPs 234 and 235, comprises a long-term strategy for the -sustainability of the network. We will refer to the combined effects of these -three ZIPs as the “Network Sustainability Mechanism”. +This ZIP proposes the introduction of a mechanism to voluntarily burn funds, +removing those funds entirely from circulation on the network. This mechanism, +in combination with ZIP 234 [^zip-0234] and ZIP 235 [^zip-0235], comprises a +long-term strategy for the sustainability of the network. We will refer to the +combined effects of these three ZIPs as the “Network Sustainability Mechanism”. + # Motivation @@ -52,69 +66,78 @@ design shared by Bitcoin-like systems: 1. **Long Term Consensus Sustainability:** By enabling the burning of funds, the network gains the ability to create "headroom" between the chain value and - `MAX_MONEY`. This lays necessary groundwork for extending the miner reward - system, which currently has a clear final end date. + $\mathsf{MAX\_MONEY}$. This lays necessary groundwork for extending the + block subsidy system, which currently has a clear final end date. 2. **Benefits to ZEC Holders:** Burning funds reduces the supply of ZEC, benefiting network users in proportion to their holdings without requiring them to opt into any scheme, introducing extra risk, active oversight, or accounting complexity. + # Specification -The modifications required are: - -1. The addition of a transaction field representing an amount to burn for a - given transaction. -2. The inclusion of the burn amount in the calculated total output value for a - given transaction. -3. Consensus rules to ensure the burned amount is no longer available for - circulation on the network. - -## Transaction Format - -The following field is added to the v6 transaction format [3]: - -+-------+----------------+------------+------------------------------------------------------+ -| Bytes | Name | Data Type | Description | -+=======+================+============+======================================================+ -| 8 | ``burnAmount`` | ``uint64`` | The amount of input value to be burned, in zatoshis. | -+-------+----------------+------------+------------------------------------------------------+ - -**Note:** Older transaction versions can continue to be supported after a -network upgrade, but burning is not possible for these transactions. For -example, NU5 supports both v4 and v5 transaction formats, for both coinbase and -non-coinbase transactions. - -## Consensus Rules - -The burned value must now be considered when calculating the total output value -of a transaction. It should be treated similarly to a transparent output, -except that there is no way for this value to be used as an input in a future -transaction. - -## Digests - -The transaction digest algorithm defined in ZIP 244 [4] is to be modified for v6 -transactions as follows: - -Section T.1: header_digest [5] is specified in draft-txv6-sighash [6] to read: - -> A BLAKE2b-256 hash of the following values: -> -> ``` -> T.1a: version (4-byte little-endian version identifier including ``fOverwintered`` flag) -> T.1b: version_group_id (4-byte little-endian version group identifier) -> T.1c: consensus_branch_id (4-byte little-endian consensus branch id) -> T.1d: lock_time (4-byte little-endian ``nLockTime`` value) -> T.1e: expiry_height (4-byte little-endian block height) -> T.1f: burn_amount (8-byte little-endian burn amount value) -> ``` -> -> The personalization field of this hash is set to: -> -> ``` -> ZTxIdHeadersHash -> ``` +## Burn amount + +Each transaction gains a $\mathsf{burn\_amount}$ property, specifying the +value in zatoshis that is burned when the transaction is mined. The burned value +subtracts from the remaining value in the "transparent transaction value pool" +as described in § 3.4 ‘Transactions and Treestates’ [^protocol-transactions]. + +$\mathsf{burn\_amount}$ does not result in an output being produced in any +chain value pool, and therefore from the point at which the transaction is +applied to the global chain state, $\mathsf{burn\_amount}$ is subtracted from the +issued supply. It is unavailable for circulation on the network at least through +to the end of the block in which the transaction is mined. ZIP 234 [^zip-0234] +specifies a potential mechanism by which the burned funds would again become +available. + +## Changes to ZIP 230 [^zip-0230] + +The following field is appended to the Common Transaction Fields of the v6 +transaction format after `nExpiryHeight` [^zip-0230-transaction-format]: + +| Bytes | Name | Data Type | Description | +|-------|--------------|-----------|----------------------------------------------------------| +| 8 | `burnAmount` | `uint64` | The value to be burned in this transaction, in zatoshis. | + +The $\mathsf{burn\_amount}$ of a transaction is defined to be the value of the +`burnAmount` field if present, and otherwise 0. + +Notes: + +* If both this ZIP and ZIP 2002 are selected for inclusion in the same Network + Upgrade, then the ambiguity in ordering of the fields added by these ZIPs + would need to be resolved. +* Older transaction versions can continue to be supported after a network upgrade, + but burning is not possible for these transactions. For example, NU5 supports + both v4 and v5 transaction formats, for both coinbase and non-coinbase transactions. + +## Changes to the Zcash Protocol Specification + +Make a change to § 3.4 ‘Transactions and Treestates’ [^protocol-transactions] +implementing the specification in [Burn amount]. + +In § 7.1 ‘Transaction Encoding and Consensus’ [^protocol-txnconsensus], add: + +> [NU7 onward] $\mathsf{burn\_amount}$ MUST be in the range $\{ 0 .. \mathsf{MAX\_MONEY} \}$. + +## Modifications relative to ZIP 244 [^zip-0244] + +Relative to the sighash algorithm defined in ZIP 244, the sighash algorithm +that applies to v6 transactions differs by appending the encoding of +$\mathsf{burn\_amount}$ to the Common Transaction Fields that are the input +to the digest in T.1: `header_digest` [^zip-0244-t-1-header-digest]: + +> T.1f: burn_amount (8-byte little-endian burn amount) + +Note: If both this ZIP and ZIP 2002 are selected for inclusion in the same +Network Upgrade, then the ambiguity in ordering of the fields added by these +ZIPs would need to be resolved. + +## Applicability + +All of these changes apply identically to Mainnet and Testnet. + # Rationale @@ -127,22 +150,38 @@ An explicit value distinguishes the burned ZEC from the transaction fee. Explicitness also ensures any arithmetic flaws in any implementations are more likely to be observed and caught immediately. + # Deployment -This ZIP is proposed to activate with Network Upgrade 7. +This ZIP is proposed to activate with Network Upgrade 7. [^zip-0254] + # References -**[1]: [Key words for use in RFCs to Indicate Requirement -Levels](https://www.rfc-editor.org/rfc/rfc2119.html)** +[^BCP14]: [Information on BCP 14 — "RFC 2119: Key words for use in RFCs to Indicate Requirement Levels" and "RFC 8174: Ambiguity of Uppercase vs Lowercase in RFC 2119 Key Words"](https://www.rfc-editor.org/info/bcp14) + +[^protocol]: [Zcash Protocol Specification, Version 2024.5.1 [NU6] or later](protocol/protocol.pdf) + +[^protocol-transactions]: [Zcash Protocol Specification, Version 2024.5.1 [NU6]. Section 3.4: Transactions And Treestates](protocol/protocol.pdf#transactions) + +[^protocol-networks]: [Zcash Protocol Specification, Version 2024.5.1 [NU6]. Section 3.12: Mainnet and Testnet](protocol/protocol.pdf#networks) + +[^protocol-constants]: [Zcash Protocol Specification, Version 2024.5.1 [NU6]. Section 5.3: Constants](protocol/protocol.pdf#constants) + +[^protocol-txnconsensus]: [Zcash Protocol Specification, Version 2024.5.1 [NU6]. Section 7.1.2 Transaction Consensus Rules](protocol/protocol.pdf#txnconsensus) + +[^zip-0200]: [ZIP 200: Network Upgrade Mechanism](zip-0200.rst) + +[^zip-0230]: [ZIP 230: Version 6 Transaction Format](zip-0230.rst) + +[^zip-0230-transaction-format]: [ZIP 230: Version 6 Transaction Format. Section 'Transaction Format'](zip-0230#transaction-format) -**[2]: [ZIP 200: Network Upgrade Mechanism](zip-0200.rst)** +[^zip-0234]: [ZIP 234: Network Sustainability Mechanism: Issuance Smoothing](zip-0234.rst) -**[3]: [ZIP 230: Version 6 Transaction Format](zip-0230.rst)** +[^zip-0235]: [ZIP 235: Burn 60% of Transaction Fees](zip-0235.rst) -**[4]: [ZIP 244: Transaction Identifier Non-Malleability](zip-0244.rst)** +[^zip-0244]: [ZIP 244: Transaction Identifier Non-Malleability](zip-0244.rst) -**[5]: [ZIP 244: Transaction Identifier Non-Malleability. Section T.1: Header -Digest](zip-0244.rst#t-1-header-digest)** +[^zip-0244-t-1-header-digest]: [ZIP 244: Transaction Identifier Non-Malleability. Section T.1: header_digest](zip-0244.rst#t-1-header-digest) -**[6]: [Draft Tx v6 Sighash](zips/draft-txv6-sighash)** +[^zip-0254]: [ZIP 254: Deployment of the NU7 Network Upgrade](zip-0254.rst) diff --git a/zips/zip-0234.md b/zips/zip-0234.md index f8db92969..bcc331b30 100644 --- a/zips/zip-0234.md +++ b/zips/zip-0234.md @@ -12,27 +12,50 @@ Status: Draft Category: Consensus Created: 2023-08-23 License: BSD-2-Clause +Discussions-To: ``` + # Terminology -The key words “MUST”, “SHOULD”, “SHOULD NOT”, “MAY”, “RECOMMENDED”, “OPTIONAL”, -and “REQUIRED” in this document are to be interpreted as described in RFC 2119. -[1] +The key word "MUST" in this document is to be interpreted as described in +BCP 14 [^BCP14] when, and only when, it appears in all capitals. + +The term "network upgrade" in this document is to be interpreted as described +in ZIP 200. [^zip-0200] + +The character § is used when referring to sections of the Zcash Protocol +Specification. [^protocol] + +The terms "Mainnet" and "Testnet" are to be interpreted as described in +§ 3.12 ‘Mainnet and Testnet’. [^protocol-networks] + +The symbol "$\,\cdot\,$" means multiplication, as described in § 2 ‘Notation’. +[^protocol-notation] + +"ZEC/TAZ" refers to the native currency of Zcash on a given network, i.e. +ZEC on Mainnet and TAZ on Testnet. + +The terms "Block Subsidy", "Issuance", and "Burning" are to be interpreted +as described in ZIP 233. [^zip-0233] -"Network upgrade" - to be interpreted as described in ZIP 200. [2] +Let $\mathsf{PostBlossomHalvingInterval}$ be as defined in [^protocol-diffadjustment]. -"Block Subsidy” - the algorithmic issuance of ZEC on block creation. Part of the -consensus rules. Split between the miner and the Dev Fund. Also known as Block -Reward. +$\mathsf{MAX\_MONEY}$, as defined in § 5.3 ‘Constants’ [^protocol-constants], +is the total ZEC/TAZ supply cap measured in zatoshi, corresponding to +21,000,000 ZEC. This is slightly larger than the supply cap for the current +issuance mechanism, but is the value used in existing critical consensus +checks. -"Issuance" - The method by which ZEC becomes available for circulation on the -network. +"Issued Supply" - The Issued Supply at a given height of a block chain is +the total ZEC/TAZ value in all chain value pool balances at that height, as +calculated by $\mathsf{IssuedSupply}(\mathsf{height})$ defined in +§ 4.17 ‘Chain Value Pool Balances’. [^protocol-chainvaluepoolbalances] -Let `PostBlossomHalvingInterval` be as defined in [#protocol-diffadjustment]_. +"Money Reserve" - The Money Reserve at a given height of a block chain is +the total ZEC/TAZ value remaining to be issued, as calculated by +$\mathsf{MAX\_MONEY} - \mathsf{IssuedSupply}(\mathsf{height})$. -"Money Reserve" - `MAX_MONEY - ChainValue`, where `ChainValue` includes all ZEC -available on the network, across all value pools. # Abstract @@ -43,8 +66,9 @@ inherited from Bitcoin, we propose a smooth logarithmic curve, defined as a fixed portion of the current value of the Money Reserve at a given block height. The new issuance scheme would approximate the current issuance over 4-year -intervals, assuming no ZEC is burned during that time, and retains the overall -supply cap of `MAX_MONEY`. +intervals, assuming no ZEC/TAZ is burned during that time, and retains the +overall supply cap of `MAX_MONEY`. + # Motivation @@ -71,7 +95,7 @@ Furthermore, the halvings schedule is fixed and does not provide any way to This new NSM-based issuance scheme solves these problems by ensuring a more consistent and predictable rate of coin issuance, while preserving the core -aspects of Zcash's issuance policy and the 21 million coin cap. At the same +aspects of Zcash's issuance policy and the 21-million-coin cap. At the same time, it introduces the first mechanism to recreate and distribute ZEC that has been removed from circulation, as well as unclaimed transaction fees, across future block subsidies. @@ -81,87 +105,96 @@ future block subsidies. Smoothing the issuance curve is possible using an exponential decay formula that satisfies the following requirements: -1. The issuance can be summarized into a reasonably simple explanation -2. Block subsidies approximate a continuous function +1. The issuance can be summarized into a reasonably simple explanation. +2. Block subsidies approximate a continuous function. 3. If the Money Reserve is greater than 0, then the block subsidy must be - non-zero, preventing any final "unmined" zatoshis -4. For any 4 year period, all paid out block subsidies are approximately equal - to half of the Money Reserve at the beginning of that 4 year period, if no - ZEC is burned during those 4 years -5. Decrease the short-term impact of the deployment of this ZIP on block reward + non-zero, preventing any final "unmined" zatoshis. +4. For any 4-year period, all paid out block subsidies are approximately equal + to half of the Money Reserve at the beginning of that 4-year period, if no + ZEC is burned during those 4 years. +5. Decrease the short-term impact of the deployment of this ZIP on block subsidy recipients, and minimize the potential reputation risk to Zcash of changing - the block reward amount. - -TODO daira: add a requirement that makes the initial total issuance match the previous total issuance + the block subsidy amount. +6. The immediate change in issuance when this mechanism activates should be + minimal. # Specification ## Parameters -`BLOCK_SUBSIDY_FRACTION` = 4126 / 10,000,000,000 or `0.0000004126` +$\mathsf{BLOCK\_SUBSIDY\_FRACTION} = 4126 / 10\_000\_000\_000 = 0.0000004126$ -`DEPLOYMENT_BLOCK_HEIGHT` = `TBD` +$\mathsf{DEPLOYMENT\_BLOCK\_HEIGHT} = \mathsf{TBD}$ The block height will be chosen by the following criteria: - It is after NU7 activation height. -- It is calculated to be the lowest height after the the second halving at +- It is calculated to be the lowest height after the second halving at which the NSM issuance would be less than the current BTC-style issuance - _neglecting_ any burnt ZEC (ie. assuming the amount of ZEC burnt is exactly 0). - -This selection is intended to achieve Key Objective 6 while still being a -constant height. An alternative would be to have a dynamic "latch" style -activation which would calculate the activation height by testing the "less -than" conditional with every block after the second halving. We prefer the -pre-defined constant height parameter to give everyone more _time_ certainty at -the cost of _issuance level_ certainty. The difference in up-front calculation -versus dynamic calculation is whether or not burns are accounted for (since -future burns cannot be calculated up-front). This means with the pre-defined -constant parameter approach, issuance will jump _up_ some amount at activation. -This amount should be equivalent to all ZEC burnt prior to that height times -`BLOCK_SUBSIDY_FRACTION`. For example, if a total of 100,000 ZEC were burnt -prior to the pre-defined constant activation height, then at activation the -issuance would be larger than BTC-style issuance by `100_000 ZEC * -BLOCK_SUBSIDY_FRACTION` which we calculate equals `0.04126 ZEC`. This example -is chosen to demonstrate that a very large burn amount (much larger than -expected) would elevate issuance by a relatively small amount. For this reason, -we believe a pre-defined constant is a better approach to achieving Key -Objective 6 than a "dynamic latch" logic because it is so much simpler to -implement and reason about. - -`MoneyReserveAfter(block_height)` = The value of the Money Reserve after the -specified block height. + _neglecting_ any burnt ZEC (i.e. assuming the amount of ZEC burnt is + exactly 0). + +This selection is intended to achieve Key Objective 6 while still being at +a constant, predictable height. An alternative would be to have a dynamic +"latch"-style activation, which would calculate the activation height by +testing the "less than" conditional with every block after the second halving. +We prefer the pre-defined constant height parameter, to give everyone more +_time_ certainty at the cost of _issuance level_ certainty. + +The difference in up-front calculation versus dynamic calculation is in +whether or not burns are accounted for (since future burns cannot be +calculated up-front). This means with the pre-defined constant parameter +approach, issuance will jump _up_ some amount at activation. This amount +should be equivalent to all ZEC burnt prior to that height times +$\mathsf{BLOCK\_SUBSIDY\_FRACTION}$. For example, if a total of 100,000 ZEC +were burnt prior to the pre-defined constant activation height, then at +activation the issuance would be larger than BTC-style issuance by +$100\_000\textsf{ ZEC} \cdot \mathsf{BLOCK\_SUBSIDY\_FRACTION}$, +which we calculate equals $0.04126$ ZEC. This example is chosen to +demonstrate that a very large burn amount (much larger than expected) would +elevate issuance by a relatively small amount. For this reason, we believe +a pre-defined constant is a better approach to achieving Key Objective 6 +than a "dynamic latch" logic because it is so much simpler to implement +and reason about. + +$\mathsf{MoneyReserveAfter}(\mathsf{height}) =$ The value of the Money Reserve +after the specified block height. ## Issuance Calculation -At the `DEPLOYMENT_BLOCK_HEIGHT`, nodes should switch from the current issuance +At the $\mathsf{DEPLOYMENT\_BLOCK\_HEIGHT}$, nodes should switch from the current issuance calculation, to the following: -`BlockSubsidy(block_height) = ceiling(BLOCK_SUBSIDY_FRACTION * MoneyReserveAfter(block_height - 1))` +$\mathsf{BlockSubsidy}(\mathsf{height}) = \mathsf{ceiling}(\mathsf{BLOCK\_SUBSIDY\_FRACTION} \cdot \mathsf{MoneyReserveAfter}(\mathsf{height} - 1))$ + +## Applicability + +All of these changes apply identically to Mainnet and Testnet. + # Rationale * Using an exponential decay function satisfies **Requirements 1** and **2** above. * We round up to the next zatoshi to satisfy **Requirement 3** above. -## `BLOCK_SUBSIDY_FRACTION` +## BLOCK_SUBSIDY_FRACTION -Let `IntendedMoneyReserveFractionRemainingAfterFourYears` = 0.5. +Let $\mathsf{IntendedMoneyReserveFractionRemainingAfterFourYears} = 0.5$. -The value `4126 / 10_000_000_000` satisfies the approximation within +0.002%: +The value $4126 / 10\_000\_000\_000$ satisfies the approximation within $\pm 0.002\%$: -`(1 - BLOCK_SUBSIDY_FRACTION)^PostBlossomHalvingInterval ≈ IntendedMoneyReserveFractionRemainingAfterFourYears` +$(1 - \mathsf{BLOCK\_SUBSIDY\_FRACTION})^\mathsf{PostBlossomHalvingInterval} \approx \mathsf{IntendedMoneyReserveFractionRemainingAfterFourYears}$ -Meaning after a period of 4 years around half of Money Reserve will be issued as -block subsidies, thus satisfying **Requirement 4**. +This implies that after a period of 4 years around half of Money Reserve will +have been issued as block subsidies, thus satisfying **Requirement 4**. -The largest possible value in the Money Reserve is `MAX_MONEY`, in the +The largest possible value in the Money Reserve is $\mathsf{MAX\_MONEY}$, in the theoretically possible case that all issued funds are burned. If this happened, -the largest interim sum in the block subsidy calculation would be `MAX_MONEY * -4126 / 10000000000`. +the largest interim sum in the block subsidy calculation would be +$\mathsf{MAX\_MONEY} \cdot 4126 / 10\_000\_000\_000$. -This uses 62.91 bits, which is just under the 63 bit limit for 64-bit signed -two's-complement integer amount types. +This uses 62.91 bits, which is just under the 63-bit limit for signed +two's complement 64-bit integer amount types. The numerator could be brought closer to the limit by using a larger denominator, but the difference in the amount issued would be very small. So we @@ -181,10 +214,6 @@ is implemented. ![A graph showing the balance of the Money Reserve assuming smooth issuance is implemented](../rendered/assets/images/zip-0234-balance.png) -# Deployment - -The implementation of this ZIP MUST be deployed at the same time or after the -Network Sustainability Mechanism Burning function is deployed (ZIP-0233). # Appendix: Simulation @@ -212,15 +241,37 @@ Halving 1 at block 1680000: shows that the difference between the smoothed out and the current issuance schemes is 238 ZEC after 1680000 blocks (around 4 years). + # Appendix: Considerations for the Future Future protocol changes may not increase the payout rate to a reasonable approximation beyond the four year half-life constraint. + +# Deployment + +This ZIP is proposed to activate with Network Upgrade 7. [^zip-0254] +It MUST be deployed at the same time or after ZIP 233 ("NSM: Burning" [^zip-0233]). + + # References -[1] RFC-2119: https://datatracker.ietf.org/doc/html/rfc2119 +[^BCP14]: [Information on BCP 14 — "RFC 2119: Key words for use in RFCs to Indicate Requirement Levels" and "RFC 8174: Ambiguity of Uppercase vs Lowercase in RFC 2119 Key Words"](https://www.rfc-editor.org/info/bcp14) + +[^protocol]: [Zcash Protocol Specification, Version 2024.5.1 [NU6] or later](protocol/protocol.pdf) + +[^protocol-notation]: [Zcash Protocol Specification, Version 2024.5.1 [NU6]. Section 2: Notation](protocol/protocol.pdf#notation) + +[^protocol-networks]: [Zcash Protocol Specification, Version 2024.5.1 [NU6]. Section 3.12: Mainnet and Testnet](protocol/protocol.pdf#networks) + +[^protocol-chainvaluepoolbalances]: [Zcash Protocol Specification, Version 2024.5.1 [NU6]. Section 4.17 Chain Value Pool Balances](protocol/protocol.pdf#chainvaluepoolbalances) + +[^protocol-constants]: [Zcash Protocol Specification, Version 2024.5.1 [NU6]. Section 5.3: Constants](protocol/protocol.pdf#constants) + +[^protocol-diffadjustment]: [Zcash Protocol Specification, Version 2024.5.1 [NU6]. Section 7.7.3 Difficulty Adjustment](protocol/protocol.pdf#diffadjustment) + +[^zip-0200]: [ZIP 200: Network Upgrade Mechanism](zip-0200.rst) -[2] [ZIP-200: Network Upgrade Mechanism](zip-0200.rst) +[^zip-0233]: [ZIP 233: Network Sustainability Mechanism: Burning](zip-0233.md) -[3] [ZIP_233: Network Sustainability Mechanism: Burning](zip-0233.md) +[^zip-0254]: [ZIP 254: Deployment of the NU7 Network Upgrade](zip-0254.rst) diff --git a/zips/zip-0235.md b/zips/zip-0235.md index 026a77679..acfbdff73 100644 --- a/zips/zip-0235.md +++ b/zips/zip-0235.md @@ -15,35 +15,43 @@ License: BSD-2-Clause Discussions-To: ``` + # Terminology -The key words “MUST”, “SHOULD”, “SHOULD NOT”, “MAY”, “RECOMMENDED”, “OPTIONAL”, -and “REQUIRED” in this document are to be interpreted as described in RFC 2119. -[1] +The key word "MUST" in this document is to be interpreted as described in +BCP 14 [^BCP14] when, and only when, it appears in all capitals. + +The term "network upgrade" in this document is to be interpreted as described +in ZIP 200. [^zip-0200] + +The character § is used when referring to sections of the Zcash Protocol +Specification. [^protocol] -The term “network upgrade” in this document is to be interpreted as described in -ZIP 200. [2] +The terms "Mainnet" and "Testnet" are to be interpreted as described in +§ 3.12 ‘Mainnet and Testnet’. [^protocol-networks] -"Block Subsidy” - the algorithmic issuance of ZEC on block creation. Part of the -consensus rules. Split between the miner and the Dev Fund. Also known as Block -Reward. +The symbol "$\,\cdot\,$" means multiplication, as described in § 2 ‘Notation’. +[^protocol-notation] -"Issuance" - The method by which ZEC becomes available for circulation on the -network. +"ZEC/TAZ" refers to the native currency of Zcash on a given network, i.e. +ZEC on Mainnet and TAZ on Testnet. + +The terms "Block Subsidy", "Issuance", and "Burning" are to be interpreted +as described in ZIP 233. [^zip-0233] -“We” - the ZIP authors, owners listed in the above front matter # Abstract -We propose to burn 60% of transaction fees, while the remaining 40% be directed -as before, providing a deflationary effect, and building the groundwork for -long-term support of the Zcash network via the new block subsidy rules proposed -by ZIP-234. +This ZIP proposes to burn 60% of transaction fees, while the remaining 40% is +directed as before, providing a deflationary effect, and building the groundwork +for long-term support of the Zcash network via the new block subsidy rules +proposed by ZIP 234 [^zip-0234]. + # Motivation -ZIP-233 ("Network Sustainability Mechanism: Burning") describes a method by -which ZEC can be burned to support network sustainability. +ZIP 233 ("Network Sustainability Mechanism: Burning" [^zip-0233]) describes a +method by which ZEC can be burned to support network sustainability. By introducing a requirement that a certain proportion of transaction fees be burned, we ensure that ZEC will be removed from circulating supply to contribute @@ -52,10 +60,10 @@ to the long-term sustainability of the network as described below: ## Benefits to the Network 1. **Network Sustainability**: This mechanism involves temporarily reducing the - supply of ZEC, similar to asset burning in Ethereum’s EIP-1559, but with - long-term sustainability benefits, as the burned funds effectively boost - future mining rewards, making it an attractive option for current and future - Zcash users. + supply of ZEC, similar to asset burning in Ethereum’s EIP-1559 [^eip-1559], + but with long-term sustainability benefits, as the burned funds effectively + boost future mining rewards, making it an attractive option for current and + future Zcash users. 2. **Incentivizing Transaction Inclusion**: By maintaining a 40% share of transaction fees for miners, we continue incentivizing miners to prioritize including transactions in their blocks. This helps ensure the continued @@ -75,28 +83,30 @@ to the long-term sustainability of the network as described below: instrumental in addressing unforeseen issues and seizing strategic advantages as the Zcash ecosystem evolves. + # Requirements * For each block, at least 60% (rounded down) of the total fees are to be -burned. + burned. * No restrictions are placed on the destination of the remaining proportion of -fees. + fees. * Any fractions are rounded in favor of the miner. + # Specification ## Consensus Rule Changes -For a given block, the coinbase transaction MUST have a `burnAmount` that is -greater than or equal to `floor(transactionFees * 6 / 10)`. +For a given block, the coinbase transaction MUST have a $\mathsf{burn\_amount}$, +as defined in [^zip-0233], that is greater than or equal to +$\mathsf{floor}(\mathsf{transactionFees} \cdot 6 / 10)$. -Previous transaction versions are not supported for coinbase transactions, due -to there being no explicit mechanism to burn the required funds. +The version of a coinbase transaction MUST be v6 or later [^zip-0230]. -# Deployment +## Applicability + +All of these changes apply identically to Mainnet and Testnet. -The implementation of this ZIP MUST be deployed at the same time or after -ZIP-233 ("NSM: Burning"), and ZIP-234 ("NSM: Issuance Smoothing"). # Rationale @@ -105,18 +115,29 @@ implementation and protocol changes. Additionally, transaction fees are currently small enough that the reduction in miner fees is unlikely to be a concern. +## Rationale for requiring the coinbase transaction to be v6 or later + +There is no explicit mechanism in prior transaction versions to burn the +required funds. Since $\mathsf{burn\_amount} = 0$ for transaction versions +prior to v6, absent the rule about the coinbase transaction version it +would be technically possible to satisfy the constraint on $\mathsf{burn\_amount}$ +with earlier versions than v6, but only when $\mathsf{transactionFees} = 0$. +That would introduce a corner case in the transaction consensus rules that +is not useful, since it is expected that the $\mathsf{transactionFees}$ +will normally be non-zero. + ## Estimated impact on miners Over 100,000 blocks starting at block 2235515, there were 316130 transactions. 60608 of them are categorized as 'sandblasting' transactions. The remaining -transactions have an average of 5.46 logical actions (see ZIP-317 [4]). +transactions have an average of 5.46 logical actions (see ZIP 317 [^zip-0317]). -The total fees paid to miners from those transactions, assuming the ZIP-317 +The total fees paid to miners from those transactions, assuming the ZIP 317 regime, would be 87.86 ZEC. 100,000 blocks is approximately 3 months of blocks. Extrapolating to a year, we would expect 351.44 ZEC in fees paid to miners over a year. -If 60% of these fees burned, that would be 210.864 ZEC per year. [5] +If 60% of these fees burned, that would be 210.864 ZEC per year. [^zsf-fee-estimator] ## Considerations for the Future @@ -139,14 +160,34 @@ sustainability, including but not limited to: - Cross-chain bridge usage / Cross-chain messaging - Note sorting micro-transactional fees + +# Deployment + +The implementation of this ZIP MUST be deployed at the same time or after +ZIP 233 ("NSM: Burning" [^zip-0233]), and ZIP 234 ("NSM: Issuance Smoothing" +[^zip-0234]). + + # References -[1] RFC-2119: https://datatracker.ietf.org/doc/html/rfc2119 +[^BCP14]: [Information on BCP 14 — "RFC 2119: Key words for use in RFCs to Indicate Requirement Levels" and "RFC 8174: Ambiguity of Uppercase vs Lowercase in RFC 2119 Key Words"](https://www.rfc-editor.org/info/bcp14) + +[^protocol]: [Zcash Protocol Specification, Version 2024.5.1 [NU6] or later](protocol/protocol.pdf) + +[^protocol-notation]: [Zcash Protocol Specification, Version 2024.5.1 [NU6]. Section 2: Notation](protocol/protocol.pdf#notation) + +[^protocol-networks]: [Zcash Protocol Specification, Version 2024.5.1 [NU6]. Section 3.12: Mainnet and Testnet](protocol/protocol.pdf#networks) + +[^zip-0200]: [ZIP 200: Network Upgrade Mechanism](zip-0200.rst) + +[^zip-0230]: [ZIP 230: Version 6 Transaction Format](zip-0230.rst) + +[^zip-0233]: [ZIP 233: Network Sustainability Mechanism: Burning](zip-0233.rst) -[2] ZIP 200: [Network Upgrade Mechanism](zip-0200.rst) +[^zip-0234]: [ZIP 234: Network Sustainability Mechanism: Issuance Smoothing](zip-0234.rst) -[3] ZIP 233: [Establish the Zcash Sustainability Fund on the Protocol Level](zip-0233.md) +[^zip-0317]: [ZIP 317: Proportional Transfer Fee Mechanism](zip-0317.rst) -[4] ZIP 317: [Proportional Transfer Fee Mechanism](zip-0317.rst) +[^zsf-fee-estimator]: [GitHub repository eigerco/zsf-fee-estimator](https://github.com/eigerco/zsf-fee-estimator) -[5] https://github.com/eigerco/zsf-fee-estimator +[^eip-1559]: [EIP-1559: Fee market change for ETH 1.0 chain](https://eips.ethereum.org/EIPS/eip-1559) diff --git a/zips/zip-0244.rst b/zips/zip-0244.rst index 8972feda7..19f5e10c3 100644 --- a/zips/zip-0244.rst +++ b/zips/zip-0244.rst @@ -762,9 +762,9 @@ rooted at ``hashMerkleRoot``. This new commitment is named ``hashAuthDataRoot`` and is the root of a binary Merkle tree of transaction authorizing data commitments having height -:math:`\mathsf{ceil(log_2(tx\_count))}`, padded with leaves having the "null" -hash value ``[0u8; 32]``. Note that :math:`\mathsf{log_2(tx\_count)}` is -well-defined because :math:`\mathsf{tx\_count} > 0`, due to the coinbase +$\mathsf{ceil(log_2(tx\_count))}$, padded with leaves having the "null" +hash value ``[0u8; 32]``. Note that $\mathsf{log_2(tx\_count)}$ is +well-defined because $\mathsf{tx\_count} > 0$, due to the coinbase transaction in each block. Non-leaf hashes in this tree are BLAKE2b-256 hashes personalized by the string ``"ZcashAuthDatHash"``. diff --git a/zips/zip-0254.md b/zips/zip-0254.md index 723339e1a..783cf7857 100644 --- a/zips/zip-0254.md +++ b/zips/zip-0254.md @@ -8,20 +8,27 @@ License: MIT Discussions-To: + # Terminology -The key word "MUST" in this document are to be interpreted as described in -BCP 14 [^BCP14] when, and only when, they appear in all capitals. +The key word "MUST" in this document is to be interpreted as described in +BCP 14 [^BCP14] when, and only when, it appears in all capitals. + +The term "network upgrade" in this document is to be interpreted as described +in ZIP 200. [^zip-0200] + +The character § is used when referring to sections of the Zcash Protocol +Specification. [^protocol] -The term "network upgrade" in this document is to be interpreted as described in ZIP 200 [^zip-0200]. +The terms "Mainnet" and "Testnet" are to be interpreted as described in +§ 3.12 ‘Mainnet and Testnet’. [^protocol-networks] -The terms "Testnet" and "Mainnet" are to be interpreted as described in -section 3.12 of the Zcash Protocol Specification [^protocol-networks]. # Abstract This proposal defines the deployment of the NU7 network upgrade. + # Specification ## NU7 deployment @@ -31,9 +38,11 @@ The primary sources of information about NU7 consensus protocol changes are: * The Zcash Protocol Specification [^protocol]. * ZIP 200: Network Upgrade Mechanism [^zip-0200]. -The network handshake and peer management mechanisms defined in ZIP 201 [^zip-0201] also apply to this upgrade. +The network handshake and peer management mechanisms defined in ZIP 201 +[^zip-0201] also apply to this upgrade. -The following network upgrade constants [^zip-0200] are defined for the NU7 upgrade: +The following network upgrade constants [^zip-0200] are defined for the +NU7 upgrade: CONSENSUS_BRANCH_ID : `0x77190AD8` @@ -46,13 +55,21 @@ MIN_NETWORK_PROTOCOL_VERSION (NU7) : Testnet: `170130` : Mainnet: `170140` -For each network (Testnet and Mainnet), nodes compatible with NU7 activation on that network MUST advertise a network protocol version that is greater than or equal to the MIN_NETWORK_PROTOCOL_VERSION (NU7) for that activation. +For each network (Testnet and Mainnet), nodes compatible with NU7 activation +on that network MUST advertise a network protocol version that is greater +than or equal to the MIN_NETWORK_PROTOCOL_VERSION (NU7) for that activation. + +## Backward compatibility -# Backward compatibility +Prior to the network upgrade activating on each network, NU7 and pre-NU7 +nodes are compatible and can connect to each other. However, NU7 nodes will +have a preference for connecting to other NU7 nodes, so pre-NU7 nodes will +gradually be disconnected in the run up to activation. -Prior to the network upgrade activating on each network, NU7 and pre-NU7 nodes are compatible and can connect to each other. However, NU7 nodes will have a preference for connecting to other NU7 nodes, so pre-NU7 nodes will gradually be disconnected in the run up to activation. +Once the network upgrades, even though pre-NU7 nodes can still accept the +numerically larger protocol version used by NU7 as being valid, NU7 nodes +will always disconnect peers using lower protocol versions. -Once the network upgrades, even though pre-NU7 nodes can still accept the numerically larger protocol version used by NU7 as being valid, NU7 nodes will always disconnect peers using lower protocol versions. # References diff --git a/zips/zip-0304.rst b/zips/zip-0304.rst index 995eefc7b..de65e29a6 100644 --- a/zips/zip-0304.rst +++ b/zips/zip-0304.rst @@ -67,29 +67,29 @@ Conventions The following constants and functions used in this ZIP are defined in the Zcash protocol specification: [#protocol]_ -- :math:`\mathsf{MerkleDepth}^\mathsf{Sapling}` and - :math:`\mathsf{Uncommitted}^\mathsf{Sapling}` [#protocol-constants]_ -- :math:`\mathsf{MerkleCRH}^\mathsf{Sapling}` [#protocol-saplingmerklecrh]_ -- :math:`\mathsf{DiversifyHash}(\mathsf{d})` [#protocol-concretediversifyhash]_ -- :math:`\mathsf{MixingPedersenHash}(\mathsf{cm}, position)` [#protocol-concretemixinghash]_ -- :math:`\mathsf{PRF}^\mathsf{nfSapling}_\mathsf{nk}(ρ)` [#protocol-concreteprfs]_ -- :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, σ)` [#protocol-concretespendauthsig]_ -- :math:`\mathsf{NoteCommit}^\mathsf{Sapling}_\mathsf{rcm}(\mathsf{g_d}, \mathsf{pk_d}, value)` [#protocol-concretewindowedcommit]_ -- :math:`\mathsf{ValueCommit}_\mathsf{rcv}(value)` [#protocol-concretehomomorphiccommit]_ +- $\mathsf{MerkleDepth}^\mathsf{Sapling}$ and + $\mathsf{Uncommitted}^\mathsf{Sapling}$ [#protocol-constants]_ +- $\mathsf{MerkleCRH}^\mathsf{Sapling}$ [#protocol-saplingmerklecrh]_ +- $\mathsf{DiversifyHash}(\mathsf{d})$ [#protocol-concretediversifyhash]_ +- $\mathsf{MixingPedersenHash}(\mathsf{cm}, position)$ [#protocol-concretemixinghash]_ +- $\mathsf{PRF}^\mathsf{nfSapling}_\mathsf{nk}(ρ)$ [#protocol-concreteprfs]_ +- $\mathsf{SpendAuthSig.RandomizePrivate}(α, \mathsf{sk})$, + $\mathsf{SpendAuthSig.RandomizePublic}(α, \mathsf{vk})$, + $\mathsf{SpendAuthSig.Sign}(\mathsf{sk}, m)$, and + $\mathsf{SpendAuthSig.Verify}(\mathsf{vk}, m, σ)$ [#protocol-concretespendauthsig]_ +- $\mathsf{NoteCommit}^\mathsf{Sapling}_\mathsf{rcm}(\mathsf{g_d}, \mathsf{pk_d}, value)$ [#protocol-concretewindowedcommit]_ +- $\mathsf{ValueCommit}_\mathsf{rcv}(value)$ [#protocol-concretehomomorphiccommit]_ We also reproduce some notation and functions here for convenience: -- :math:`a\,||\,b` means the concatenation of sequences :math:`a` then :math:`b`. +- $a\,||\,b$ means the concatenation of sequences $a$ then $b$. -- :math:`\mathsf{repr}_\mathbb{J}(P)` is the representation of the Jubjub elliptic curve - point :math:`P` as a bit sequence, defined in [#protocol-jubjub]_. +- $\mathsf{repr}_\mathbb{J}(P)$ is the representation of the Jubjub elliptic curve + point $P$ as a bit sequence, defined in [#protocol-jubjub]_. -- :math:`\mathsf{BLAKE2b}\text{-}\mathsf{256}(p, x)` refers to unkeyed BLAKE2b-256 in +- $\mathsf{BLAKE2b}\text{-}\mathsf{256}(p, x)$ refers to unkeyed BLAKE2b-256 in sequential mode, with an output digest length of 32 bytes, 16-byte personalization - string :math:`p`, and input :math:`x`. + string $p$, and input $x$. Requirements @@ -120,7 +120,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 :math:`1` zatoshi and :math:`\mathsf{rcm} = 0`. +- A fake Sapling note with a value of $1$ zatoshi and $\mathsf{rcm} = 0$. - A Sapling commitment tree that is empty except for the commitment for the fake note. Signature algorithm @@ -128,86 +128,86 @@ Signature algorithm The inputs to the signature algorithm are: -- The payment address :math:`(\mathsf{d}, \mathsf{pk_d})`, -- Its corresponding expanded spending key :math:`(\mathsf{ask}, \mathsf{nsk}, \mathsf{ovk})`, +- The payment address $(\mathsf{d}, \mathsf{pk_d})$, +- Its corresponding expanded spending key $(\mathsf{ask}, \mathsf{nsk}, \mathsf{ovk})$, - The SLIP-44 [#slip-0044]_ coin type, and -- The message :math:`msg` to be signed. +- The message $msg$ to be signed. The signature is created as follows: -- Derive the full viewing key :math:`(\mathsf{ak}, \mathsf{nk}, \mathsf{ovk})` from the expanded spending key. +- Derive the full viewing key $(\mathsf{ak}, \mathsf{nk}, \mathsf{ovk})$ from the expanded spending key. -- Let :math:`\mathsf{g_d} = \mathsf{DiversifyHash}(\mathsf{d})`. +- Let $\mathsf{g_d} = \mathsf{DiversifyHash}(\mathsf{d})$. -- Let :math:`\mathsf{cm} = \mathsf{NoteCommit}^\mathsf{Sapling}_0(\mathsf{repr}_\mathbb{J}(\mathsf{g_d}), \mathsf{repr}_\mathbb{J}(\mathsf{pk_d}), 1)`. +- Let $\mathsf{cm} = \mathsf{NoteCommit}^\mathsf{Sapling}_0(\mathsf{repr}_\mathbb{J}(\mathsf{g_d}), \mathsf{repr}_\mathbb{J}(\mathsf{pk_d}), 1)$. -- 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:`\mathsf{cm}` at position 0, and - :math:`\mathsf{Uncommitted}^\mathsf{Sapling}` at all other positions. +- Let $\mathsf{rt}$ be the root of a Merkle tree with depth + $\mathsf{MerkleDepth}^\mathsf{Sapling}$ and hashing function + $\mathsf{MerkleCRH}^\mathsf{Sapling}$, containing $\mathsf{cm}$ at position 0, and + $\mathsf{Uncommitted}^\mathsf{Sapling}$ at all other positions. -- Let :math:`path` be the Merkle path from position 0 to :math:`\mathsf{rt}`. [#protocol-merklepath]_ +- Let $path$ be the Merkle path from position 0 to $\mathsf{rt}$. [#protocol-merklepath]_ -- Let :math:`\mathsf{cv} = \mathsf{ValueCommit}_0(1)`. +- Let $\mathsf{cv} = \mathsf{ValueCommit}_0(1)$. - This is a constant and may be pre-computed. -- Let :math:`\mathsf{nf} = \mathsf{PRF}^\mathsf{nfSapling}_{\mathsf{repr}_\mathbb{J}(\mathsf{nk})}(\mathsf{repr}_\mathbb{J}(\mathsf{MixingPedersenHash}(\mathsf{cm}, 0)))`. +- Let $\mathsf{nf} = \mathsf{PRF}^\mathsf{nfSapling}_{\mathsf{repr}_\mathbb{J}(\mathsf{nk})}(\mathsf{repr}_\mathbb{J}(\mathsf{MixingPedersenHash}(\mathsf{cm}, 0)))$. -- Select a random :math:`α`. +- Select a random $α$. -- Let :math:`\mathsf{rk} = \mathsf{SpendAuthSig.RandomizePublic}(α, \mathsf{ak})`. +- Let $\mathsf{rk} = \mathsf{SpendAuthSig.RandomizePublic}(α, \mathsf{ak})$. -- Let :math:`zkproof` be the byte sequence representation of 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})`. +- Let $zkproof$ be the byte sequence representation of a Sapling spend proof with primary input + $(\mathsf{rt}, \mathsf{cv}, \mathsf{nf}, \mathsf{rk})$ + and auxiliary input $(path, 0, \mathsf{g_d}, \mathsf{pk_d}, 1, 0, \mathsf{cm}, 0, α, \mathsf{ak}, \mathsf{nsk})$. [#protocol-spendstatement]_ -- Let :math:`\mathsf{rsk} = \mathsf{SpendAuthSig.RandomizePrivate}(α, \mathsf{ask})`. +- Let $\mathsf{rsk} = \mathsf{SpendAuthSig.RandomizePrivate}(α, \mathsf{ask})$. -- Let :math:`coinType` be the 4-byte little-endian encoding of the coin type in its index +- Let $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 $digest = \mathsf{BLAKE2b}\text{-}\mathsf{256}(\texttt{“ZIP304Signed”}\,||\,coinType, zkproof\,||\,msg)$. -- Let :math:`spendAuthSig = \mathsf{SpendAuthSig.Sign}(\mathsf{rsk}, digest)`. +- Let $spendAuthSig = \mathsf{SpendAuthSig.Sign}(\mathsf{rsk}, digest)$. -- Return :math:`(\mathsf{nf}, \mathsf{rk}, zkproof, spendAuthSig)`. +- Return $(\mathsf{nf}, \mathsf{rk}, zkproof, spendAuthSig)$. Verification algorithm ---------------------- The inputs to the verification algorithm are: -- The payment address :math:`(\mathsf{d}, \mathsf{pk_d})`, +- The payment address $(\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:`(\mathsf{nf}, \mathsf{rk}, zkproof, spendAuthSig)`. +- The message $msg$ that is claimed to be signed, and +- The ZIP 304 signature $(\mathsf{nf}, \mathsf{rk}, zkproof, spendAuthSig)$. The signature MUST be verified as follows: -- Let :math:`coinType` be the 4-byte little-endian encoding of the coin type in its index +- Let $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 $digest = \mathsf{BLAKE2b}\text{-}\mathsf{256}(\texttt{“ZIP304Signed”}\,||\,coinType, zkproof\,||\,msg)$. -- If :math:`\mathsf{SpendAuthSig.Verify}(\mathsf{rk}, digest, spendAuthSig) = 0`, return false. +- If $\mathsf{SpendAuthSig.Verify}(\mathsf{rk}, digest, spendAuthSig) = 0$, return false. -- 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 $\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:`\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:`\mathsf{cm}` at position 0, and - :math:`\mathsf{Uncommitted}^\mathsf{Sapling}` at all other positions. +- Let $\mathsf{rt}$ be the root of a Merkle tree with depth + $\mathsf{MerkleDepth}^\mathsf{Sapling}$ and hashing function + $\mathsf{MerkleCRH}^\mathsf{Sapling}$, containing $\mathsf{cm}$ at position 0, and + $\mathsf{Uncommitted}^\mathsf{Sapling}$ at all other positions. -- Let :math:`path` be the Merkle path from position 0 to :math:`\mathsf{rt}`. [#protocol-merklepath]_ +- Let $path$ be the Merkle path from position 0 to $\mathsf{rt}$. [#protocol-merklepath]_ -- Let :math:`\mathsf{cv} = \mathsf{ValueCommit}_0(1)`. +- Let $\mathsf{cv} = \mathsf{ValueCommit}_0(1)$. - This is a constant and may be pre-computed. -- Decode and verify :math:`zkproof` as a Sapling spend proof with primary input - :math:`(\mathsf{rt}, \mathsf{cv}, \mathsf{nf}, \mathsf{rk})`. [#protocol-spendstatement]_ If verification fails, return false. +- Decode and verify $zkproof$ as a Sapling spend proof with primary input + $(\mathsf{rt}, \mathsf{cv}, \mathsf{nf}, \mathsf{rk})$. [#protocol-spendstatement]_ If verification fails, return false. - Return true. @@ -215,13 +215,13 @@ Signature encoding ------------------ The raw form of a ZIP 304 signature is -:math:`\mathsf{nf}\,||\,\mathsf{LEBS2OSP}_{256}(\mathsf{repr}_{\mathbb{J}}(\mathsf{rk}))\,||\,zkproof\,||\,spendAuthSig`, +$\mathsf{nf}\,||\,\mathsf{LEBS2OSP}_{256}(\mathsf{repr}_{\mathbb{J}}(\mathsf{rk}))\,||\,zkproof\,||\,spendAuthSig$, for a total size of 320 bytes. When encoding a ZIP 304 signature in a human-readable format, implementations **SHOULD** use standard Base64 for compatibility with the ``signmessage`` and ``verifymessage`` RPC methods in ``zcashd``. ZIP 304 signatures in this form are 428 bytes. The encoded form is -the string :math:`\texttt{"zip304:"}` followed by the result of Base64-encoding [#RFC4648]_ +the string $\texttt{“zip304:”}$ followed by the result of Base64-encoding [#RFC4648]_ the raw form of the signature. Rationale @@ -232,13 +232,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 :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 +We use a note value of $1$ zatoshi instead of zero to ensure that the payment address is +fully bound to $zkproof$. Notes with zero value have certain constraints disabled inside the circuit. -We set :math:`\mathsf{rcm}` and :math:`\mathsf{rcv}` to zero because we do not need the hiding properties of +We set $\mathsf{rcm}$ and $\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:`\mathsf{rcm}` and :math:`\mathsf{rcv}` from the signature. +and can thus omit both $\mathsf{rcm}$ and $\mathsf{rcv}$ from the signature. Security and Privacy Considerations @@ -251,18 +251,18 @@ the payment address, as the first 32 bytes of each signature will be identical. A signature is bound to a specific diversified address of the spending key. Signatures for different diversified addresses of the same spending key are unlinkable, as long as -:math:`α` is never re-used across signatures. +$α$ is never re-used across signatures. Most of the data within a ZIP 304 signature is inherently non-malleable: -- :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. +- $\mathsf{nf}$ is a binary public input to $zkproof$. +- $\mathsf{rk}$ is internally bound to $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 +The one component that is inherently malleable is $zkproof$. The zero-knowledge property of a Groth16 proof implies that anyone can take a valid proof, and re-randomize it to obtain another valid proof with a different encoding. We prevent this by binding the -encoding of :math:`zkproof` to :math:`spendAuthSig`, by including :math:`zkproof` in the +encoding of $zkproof$ to $spendAuthSig$, by including $zkproof$ in the message digest. diff --git a/zips/zip-0307.rst b/zips/zip-0307.rst index 720443c80..5e536a428 100644 --- a/zips/zip-0307.rst +++ b/zips/zip-0307.rst @@ -253,39 +253,39 @@ server here without loss of generality. Local processing ---------------- -Given a ``CompactBlock`` at block height :math:`\mathsf{height}` received in height-sequential +Given a ``CompactBlock`` at block height $\mathsf{height}$ received in height-sequential order from a proxy server, a light client can process it in four ways: Scanning for relevant transactions `````````````````````````````````` For every ``CompactOutput`` in the ``CompactBlock``, the light client can trial-decrypt it against a set of Sapling incoming viewing keys. The procedure for trial-decrypting a -``CompactOutput`` :math:`(\mathtt{cmu}, \mathtt{ephemeralKey}, \mathsf{ciphertext})` with an incoming -viewing key :math:`\mathsf{ivk}` is a slight deviation from the standard decryption process +``CompactOutput`` $(\mathtt{cmu}, \mathtt{ephemeralKey}, \mathsf{ciphertext})$ with an incoming +viewing key $\mathsf{ivk}$ is a slight deviation from the standard decryption process [#protocol-saplingdecryptivk]_ (all constants and algorithms are as defined there): -- let :math:`\mathsf{epk} = \mathsf{abst}_{\mathbb{J}}(\mathtt{ephemeralKey})` -- if :math:`\mathsf{epk} = \bot`, return :math:`\bot` -- let :math:`\mathsf{sharedSecret} = \mathsf{KA^{Sapling}.Agree}(\mathsf{ivk}, \mathsf{epk})` -- let :math:`K^{\mathsf{enc}} = \mathsf{KDF^{Sapling}}(\mathsf{sharedSecret}, \mathtt{ephemeralKey})` -- let :math:`P^{\mathsf{enc}} = \mathsf{ChaCha20.Decrypt}_{K^{\mathsf{enc}}}(\mathsf{ciphertext})` -- extract :math:`\mathbf{np} = (\mathsf{leadByte}, \mathsf{d}, \mathsf{v}, \mathsf{rseed})` from :math:`P^{\mathsf{enc}}` -- [Pre-Canopy] if :math:`\mathsf{leadByte} \neq 0x01`, return :math:`\bot` -- [Pre-Canopy] let :math:`\mathsf{\underline{rcm}} = \mathsf{rseed}` -- [Canopy onward] if :math:`\mathsf{height} < \mathsf{CanopyActivationHeight} + \mathsf{ZIP212GracePeriod}` and :math:`\mathsf{leadByte} \not\in \{ \mathtt{0x01}, \mathtt{0x02} \}`, return :math:`\bot` -- [Canopy onward] if :math:`\mathsf{height} < \mathsf{CanopyActivationHeight} + \mathsf{ZIP212GracePeriod}` and :math:`\mathsf{leadByte} \neq \mathtt{0x02}`, return :math:`\bot` -- [Canopy onward] let :math:`\mathsf{\underline{rcm}} = \begin{cases}\mathsf{rseed}, &\text{if } \mathsf{leadByte} = \mathtt{0x01} \\ \mathsf{ToScalar}(\mathsf{PRF^{expand}_{rseed}}([5])), &\text{otherwise}\end{cases}` -- let :math:`\mathsf{rcm} = \mathsf{LEOS2IP}_{256}(\mathsf{\underline{rcm}})` and :math:`\mathsf{g_d} = \mathsf{DiversifyHash}(\mathsf{d})` -- if :math:`\mathsf{rcm} \geq r_{\mathbb{J}}` or :math:`\mathsf{g_d} = \bot`, return :math:`\bot` -- [Canopy onward] if :math:`\mathsf{leadByte} \neq \mathtt{0x01}`: - - * :math:`\mathsf{esk} = \mathsf{ToScalar}(\mathsf{PRF^{expand}_{rseed}}([4]))` - * if :math:`\mathsf{repr}_{\mathbb{J}}(\mathsf{KA^{Sapling}.DerivePublic}(\mathsf{esk}, \mathsf{g_d})) \neq \mathtt{ephemeralKey}`, return :math:`\bot` - -- let :math:`\mathsf{pk_d} = \mathsf{KA^{Sapling}.DerivePublic}(\mathsf{ivk}, \mathsf{g_d})` -- let :math:`\mathsf{cm}_u' = \mathsf{Extract}_{\mathbb{J}^{(r)}}(\mathsf{NoteCommit^{Sapling}_{rcm}}(\mathsf{repr}_{\mathbb{J}}(\mathsf{g_d}), \mathsf{repr}_{\mathbb{J}}(\mathsf{pk_d}), \mathsf{v}))`. -- if :math:`\mathsf{LEBS2OSP}_{256}(\mathsf{cm}_u') \neq \mathtt{cmu}`, return :math:`\bot` -- return :math:`\mathbf{np}`. +- let $\mathsf{epk} = \mathsf{abst}_{\mathbb{J}}(\mathtt{ephemeralKey})$ +- if $\mathsf{epk} = \bot$, return $\bot$ +- let $\mathsf{sharedSecret} = \mathsf{KA^{Sapling}.Agree}(\mathsf{ivk}, \mathsf{epk})$ +- let $K^{\mathsf{enc}} = \mathsf{KDF^{Sapling}}(\mathsf{sharedSecret}, \mathtt{ephemeralKey})$ +- let $P^{\mathsf{enc}} = \mathsf{ChaCha20.Decrypt}_{K^{\mathsf{enc}}}(\mathsf{ciphertext})$ +- extract $\mathbf{np} = (\mathsf{leadByte}, \mathsf{d}, \mathsf{v}, \mathsf{rseed})$ from $P^{\mathsf{enc}}$ +- [Pre-Canopy] if $\mathsf{leadByte} \neq 0x01$, return $\bot$ +- [Pre-Canopy] let $\mathsf{\underline{rcm}} = \mathsf{rseed}$ +- [Canopy onward] if $\mathsf{height} < \mathsf{CanopyActivationHeight} + \mathsf{ZIP212GracePeriod}$ and $\mathsf{leadByte} \not\in \{ \mathtt{0x01}, \mathtt{0x02} \}$, return $\bot$ +- [Canopy onward] if $\mathsf{height} < \mathsf{CanopyActivationHeight} + \mathsf{ZIP212GracePeriod}$ and $\mathsf{leadByte} \neq \mathtt{0x02}$, return $\bot$ +- [Canopy onward] let $\mathsf{\underline{rcm}} = \begin{cases}\mathsf{rseed}, &\text{if } \mathsf{leadByte} = \mathtt{0x01} \\ \mathsf{ToScalar}(\mathsf{PRF^{expand}_{rseed}}([5])), &\text{otherwise}\end{cases}$ +- let $\mathsf{rcm} = \mathsf{LEOS2IP}_{256}(\mathsf{\underline{rcm}})$ and $\mathsf{g_d} = \mathsf{DiversifyHash}(\mathsf{d})$ +- if $\mathsf{rcm} \geq r_{\mathbb{J}}$ or $\mathsf{g_d} = \bot$, return $\bot$ +- [Canopy onward] if $\mathsf{leadByte} \neq \mathtt{0x01}$: + + * $\mathsf{esk} = \mathsf{ToScalar}(\mathsf{PRF^{expand}_{rseed}}([4]))$ + * if $\mathsf{repr}_{\mathbb{J}}(\mathsf{KA^{Sapling}.DerivePublic}(\mathsf{esk}, \mathsf{g_d})) \neq \mathtt{ephemeralKey}$, return $\bot$ + +- let $\mathsf{pk_d} = \mathsf{KA^{Sapling}.DerivePublic}(\mathsf{ivk}, \mathsf{g_d})$ +- let $\mathsf{cm}_u' = \mathsf{Extract}_{\mathbb{J}^{(r)}}(\mathsf{NoteCommit^{Sapling}_{rcm}}(\mathsf{repr}_{\mathbb{J}}(\mathsf{g_d}), \mathsf{repr}_{\mathbb{J}}(\mathsf{pk_d}), \mathsf{v}))$. +- if $\mathsf{LEBS2OSP}_{256}(\mathsf{cm}_u') \neq \mathtt{cmu}$, return $\bot$ +- return $\mathbf{np}$. Creating and updating note witnesses ```````````````````````````````````` diff --git a/zips/zip-0311.rst b/zips/zip-0311.rst index b55b94bac..c83d91af1 100644 --- a/zips/zip-0311.rst +++ b/zips/zip-0311.rst @@ -145,27 +145,27 @@ Conventions The following functions used in this ZIP are defined in the Zcash protocol specification: [#protocol]_ -- :math:`\mathsf{DiversifyHash}(\mathsf{d})` [#protocol-concretediversifyhash]_ +- $\mathsf{DiversifyHash}(\mathsf{d})$ [#protocol-concretediversifyhash]_ -- :math:`\mathsf{SpendAuthSig.RandomizePrivate}(α, \mathsf{sk})`, - :math:`\mathsf{SpendAuthSig.Sign}(\mathsf{sk}, m)`, and - :math:`\mathsf{SpendAuthSig.Verify}(\mathsf{vk}, m, σ)` [#protocol-concretespendauthsig]_ +- $\mathsf{SpendAuthSig.RandomizePrivate}(α, \mathsf{sk})$, + $\mathsf{SpendAuthSig.Sign}(\mathsf{sk}, m)$, and + $\mathsf{SpendAuthSig.Verify}(\mathsf{vk}, m, σ)$ [#protocol-concretespendauthsig]_ We reproduce some notation and functions from [#protocol]_ here for convenience: -- :math:`[k] P` means scalar multiplication of the elliptic curve point :math:`P` by the - scalar :math:`k`. +- $[k] P$ means scalar multiplication of the elliptic curve point $P$ by the + scalar $k$. -- :math:`\mathsf{BLAKE2b}\text{-}\mathsf{256}(p, x)` refers to unkeyed BLAKE2b-256 in +- $\mathsf{BLAKE2b}\text{-}\mathsf{256}(p, x)$ refers to unkeyed BLAKE2b-256 in sequential mode, with an output digest length of 32 bytes, 16-byte personalization - string :math:`p`, and input :math:`x`. + string $p$, and input $x$. We also define the following notation here: -- :math:`[a..b]` means the sequence of values inclusive of :math:`a` and exclusive of - :math:`b`. +- $[a..b]$ means the sequence of values inclusive of $a$ and exclusive of + $b$. -- :math:`\mathsf{length}(a)` means the length of the sequence :math:`a`. +- $\mathsf{length}(a)$ means the length of the sequence $a$. Specification @@ -181,11 +181,11 @@ A payment disclosure has the following fields: - `msg`: A message field, which could contain a challenge value from the party to whom the payment disclosure is directed. -- :math:`\mathsf{transparentInputs}`: A sequence of the transparent inputs for which we are - proving spend authority :math:`[0..\mathsf{length}(\mathsf{tx.vin})]` +- $\mathsf{transparentInputs}$: A sequence of the transparent inputs for which we are + proving spend authority $[0..\mathsf{length}(\mathsf{tx.vin})]$ - - :math:`\mathsf{index}`: An index into :math:`\mathsf{tx.vin}`. - - :math:`\mathsf{sig}`: A BIP 322 signature. [#bip-0322]_ + - $\mathsf{index}$: An index into $\mathsf{tx.vin}$. + - $\mathsf{sig}$: A BIP 322 signature. [#bip-0322]_ - TODO: `zcashd` currently only supports the legacy format defined in BIP 322. We may want to backport full BIP 322 support before having transparent input support in @@ -194,27 +194,27 @@ A payment disclosure has the following fields: process. We will likely need to migrate it over to an equivalent ZIP that specifies these for Zcash (which has a different set of script validation consensus rules). -- :math:`\mathsf{saplingSpends}`: A sequence of the Sapling Spends for which we are proving - spend authority :math:`[0..\mathsf{length}(\mathsf{tx.shieldedSpends})]` +- $\mathsf{saplingSpends}$: A sequence of the Sapling Spends for which we are proving + spend authority $[0..\mathsf{length}(\mathsf{tx.shieldedSpends})]$ - - :math:`\mathsf{index}`: An index into :math:`\mathsf{tx.shieldedSpends}`. - - :math:`\mathsf{cv}`: A value commitment to the spent note. - - :math:`\mathsf{rk}`: A randomized public key linked to the spent note. - - :math:`\mathsf{zkproof_{spend}}`: A Sapling spend proof. + - $\mathsf{index}$: An index into $\mathsf{tx.shieldedSpends}$. + - $\mathsf{cv}$: A value commitment to the spent note. + - $\mathsf{rk}$: A randomized public key linked to the spent note. + - $\mathsf{zkproof_{spend}}$: A Sapling spend proof. - [Optional] A payment address proof `addr_proof`: - - Any :math:`(\mathsf{d, pk_d})` such that - :math:`\mathsf{pk_d} = [\mathsf{ivk}] \mathsf{DiversifyHash}(\mathsf{d})` - - :math:`\mathsf{nullifier_{addr}}`: A nullifier for a ZIP 304 fake note. [#zip-0304]_ - - :math:`\mathsf{zkproof_{addr}}`: A Sapling spend proof. + - Any $(\mathsf{d, pk_d})$ such that + $\mathsf{pk_d} = [\mathsf{ivk}] \mathsf{DiversifyHash}(\mathsf{d})$ + - $\mathsf{nullifier_{addr}}$: A nullifier for a ZIP 304 fake note. [#zip-0304]_ + - $\mathsf{zkproof_{addr}}$: A Sapling spend proof. - - :math:`\mathsf{spendAuthSig}` + - $\mathsf{spendAuthSig}$ -- :math:`\mathsf{saplingOutputs}`: A sequence of the Sapling Outputs that we are disclosing - :math:`[0..\mathsf{length}(\mathsf{tx.shieldedOutputs})]` +- $\mathsf{saplingOutputs}$: A sequence of the Sapling Outputs that we are disclosing + $[0..\mathsf{length}(\mathsf{tx.shieldedOutputs})]$ - - :math:`\mathsf{index}`: An index into :math:`\mathsf{tx.shieldedOutputs}`. - - :math:`\mathsf{ock}`: The outgoing cipher key that allows this output to be recovered. + - $\mathsf{index}$: An index into $\mathsf{tx.shieldedOutputs}$. + - $\mathsf{ock}$: The outgoing cipher key that allows this output to be recovered. [#protocol-saplingencrypt]_ TODO: Add support for Orchard. @@ -230,17 +230,17 @@ The inputs to a payment disclosure are: - The transaction. - The SLIP-44 [#slip-0044]_ coin type. -- The message :math:`msg` to be included (which may be empty). -- A sequence of :math:`(\mathsf{outputIndex}, \mathsf{ock})` tuples (which may be empty). +- The message $msg$ to be included (which may be empty). +- A sequence of $(\mathsf{outputIndex}, \mathsf{ock})$ tuples (which may be empty). - A sequence of Sapling spend tuples (which may be empty) containing: - A Sapling spend index. - - Its corresponding expanded spending key :math:`(\mathsf{ask}, \mathsf{nsk}, \mathsf{ovk})`. - - [Optional] An associated payment address :math:`(\mathsf{d}, \mathsf{pk_d})`. + - Its corresponding expanded spending key $(\mathsf{ask}, \mathsf{nsk}, \mathsf{ovk})$. + - [Optional] An associated payment address $(\mathsf{d}, \mathsf{pk_d})$. - A sequence of transparent input tuples (which may be empty) containing: - - :math:`\mathsf{index}`: An index into :math:`\mathsf{tx.vin}`. + - $\mathsf{index}$: An index into $\mathsf{tx.vin}$. - The inputs to a BIP 322 signature (excluding `message_data`). The caller MUST provide at least one input tuple of any type (either a Sapling spend tuple @@ -251,14 +251,14 @@ The payment disclosure is created as follows: - For each Sapling spend index: - Create a Sapling spend proof for the note that was spent in - :math:`\mathsf{tx.shieldedSpends[index]}`, using the same anchor, to obtain - :math:`(\mathsf{cv}, \mathsf{rk}, \mathsf{zkproof_{spend}})` as well as the random - :math:`\alpha` that was generated internally. + $\mathsf{tx.shieldedSpends[index]}$, using the same anchor, to obtain + $(\mathsf{cv}, \mathsf{rk}, \mathsf{zkproof_{spend}})$ as well as the random + $\alpha$ that was generated internally. - [Optional] If an associated payment address was provided for this spend index, create - a ZIP 304 signature proof for that payment address, [#zip-0304]_ using :math:`\alpha` - and :math:`\mathsf{rk}` from the previous step. We obtain - :math:`(\mathsf{nullifier_{addr}}, \mathsf{zkproof_{addr}})` from this step. + a ZIP 304 signature proof for that payment address, [#zip-0304]_ using $\alpha$ + and $\mathsf{rk}$ from the previous step. We obtain + $(\mathsf{nullifier_{addr}}, \mathsf{zkproof_{addr}})$ from this step. - For each transparent input index: @@ -266,18 +266,18 @@ The payment disclosure is created as follows: - Construct an unsigned payment disclosure from the disclosed Sapling outputs, and the above data for the Sapling spends and transparent inputs. Define the encoding of this as - :math:`unsignedPaymentDisclosure`. + $unsignedPaymentDisclosure$. - For each Sapling spend index: - - Let :math:`\mathsf{rsk} = \mathsf{SpendAuthSig.RandomizePrivate}(\alpha, \mathsf{ask})`. + - Let $\mathsf{rsk} = \mathsf{SpendAuthSig.RandomizePrivate}(\alpha, \mathsf{ask})$. - - Let :math:`coinType` be the 4-byte little-endian encoding of the SLIP 44 coin type in its + - Let $coinType$ be the 4-byte little-endian encoding of the SLIP 44 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{"ZIP311Signed"}\,||\,coinType, unsignedPaymentDisclosure)`. + - Let $digest = \mathsf{BLAKE2b}\text{-}\mathsf{256}(\texttt{“ZIP311Signed”}\,||\,coinType, unsignedPaymentDisclosure)$. - - Let :math:`spendAuthSig = \mathsf{SpendAuthSig.Sign}(\mathsf{rsk}, digest)`. + - Let $spendAuthSig = \mathsf{SpendAuthSig.Sign}(\mathsf{rsk}, digest)$. - For each transparent input index: @@ -289,76 +289,76 @@ The payment disclosure is created as follows: Verifying a payment disclosure ------------------------------ -Given a payment disclosure :math:`\mathsf{pd}`, a transaction :math:`\mathsf{tx}`, and the -`height` of the block in which :math:`\mathsf{tx}` was mined (which we assume was verified +Given a payment disclosure $\mathsf{pd}$, a transaction $\mathsf{tx}$, and the +`height` of the block in which $\mathsf{tx}$ was mined (which we assume was verified by the caller), the verifier proceeds as follows: - Perform the following structural correctness checks, returning false if any check fails: - - :math:`\mathsf{pd.txid} = \mathsf{tx.txid}()` + - $\mathsf{pd.txid} = \mathsf{tx.txid}()$ - Sequence length correctness: - - :math:`\mathsf{length}(\mathsf{pd.saplingOutputs}) \leq \mathsf{length}(\mathsf{tx.shieldedOutputs})` - - :math:`\mathsf{length}(\mathsf{pd.saplingSpends}) \leq \mathsf{length}(\mathsf{tx.shieldedSpends})` - - :math:`\mathsf{length}(\mathsf{pd.transparentInputs}) \leq \mathsf{length}(\mathsf{tx.vin})` + - $\mathsf{length}(\mathsf{pd.saplingOutputs}) \leq \mathsf{length}(\mathsf{tx.shieldedOutputs})$ + - $\mathsf{length}(\mathsf{pd.saplingSpends}) \leq \mathsf{length}(\mathsf{tx.shieldedSpends})$ + - $\mathsf{length}(\mathsf{pd.transparentInputs}) \leq \mathsf{length}(\mathsf{tx.vin})$ - Index uniqueness: - - For every :math:`\mathsf{output}` in :math:`\mathsf{pd.saplingOutputs}`, - :math:`\mathsf{output.index}` only occurs once. - - For every :math:`\mathsf{spend}` in :math:`\mathsf{pd.saplingSpends}`, - :math:`\mathsf{spend.index}` only occurs once. - - For every :math:`\mathsf{input}` in :math:`\mathsf{pd.transparentInputs}`, - :math:`\mathsf{input.index}` only occurs once. + - For every $\mathsf{output}$ in $\mathsf{pd.saplingOutputs}$, + $\mathsf{output.index}$ only occurs once. + - For every $\mathsf{spend}$ in $\mathsf{pd.saplingSpends}$, + $\mathsf{spend.index}$ only occurs once. + - For every $\mathsf{input}$ in $\mathsf{pd.transparentInputs}$, + $\mathsf{input.index}$ only occurs once. - Index correctness: - - For every :math:`\mathsf{output}` in :math:`\mathsf{pd.saplingOutputs}`, - :math:`\mathsf{output.index} < \mathsf{length}(\mathsf{tx.shieldedOutputs})` - - For every :math:`\mathsf{spend}` in :math:`\mathsf{pd.saplingSpends}`, - :math:`\mathsf{spend.index} < \mathsf{length}(\mathsf{tx.shieldedSpends})` - - For every :math:`\mathsf{input}` in :math:`\mathsf{pd.transparentInputs}`, - :math:`\mathsf{input.index} < \mathsf{length}(\mathsf{tx.vin})` + - For every $\mathsf{output}$ in $\mathsf{pd.saplingOutputs}$, + $\mathsf{output.index} < \mathsf{length}(\mathsf{tx.shieldedOutputs})$ + - For every $\mathsf{spend}$ in $\mathsf{pd.saplingSpends}$, + $\mathsf{spend.index} < \mathsf{length}(\mathsf{tx.shieldedSpends})$ + - For every $\mathsf{input}$ in $\mathsf{pd.transparentInputs}$, + $\mathsf{input.index} < \mathsf{length}(\mathsf{tx.vin})$ - - :math:`\mathsf{length}(\mathsf{pd.saplingSpends}) + \mathsf{length}(\mathsf{pd.transparentInputs}) > 0` + - $\mathsf{length}(\mathsf{pd.saplingSpends}) + \mathsf{length}(\mathsf{pd.transparentInputs}) > 0$ -- Let :math:`unsignedPaymentDisclosure` be the encoding of the payment disclosure without +- Let $unsignedPaymentDisclosure$ be the encoding of the payment disclosure without signatures. -- Let :math:`coinType` be the 4-byte little-endian encoding of the coin type in its index +- Let $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{"ZIP311Signed"}\,||\,coinType, unsignedPaymentDisclosure)`. +- Let $digest = \mathsf{BLAKE2b}\text{-}\mathsf{256}(\texttt{“ZIP311Signed”}\,||\,coinType, unsignedPaymentDisclosure)$. -- For every :math:`\mathsf{spend}` in :math:`\mathsf{pd.saplingSpends}`: +- For every $\mathsf{spend}$ in $\mathsf{pd.saplingSpends}$: - - If :math:`\mathsf{SpendAuthSig.Verify}(\mathsf{spend.rk}, digest, \mathsf{spend.spendAuthSig}) = 0`, return false. + - If $\mathsf{SpendAuthSig.Verify}(\mathsf{spend.rk}, digest, \mathsf{spend.spendAuthSig}) = 0$, return false. - - [Optional] If a payment address proof :math:`\mathsf{addrProof}` is present in - :math:`\mathsf{spend}`, verify :math:`(\mathsf{addrProof.nullifier_{addr}}, \mathsf{spend.rk}, \mathsf{addrProof.zkproof_{addr}})` as a ZIP 304 proof - for :math:`(\mathsf{addrProof.d}, \mathsf{addrProof.pk_d})` [#zip-0304]_. If verification fails, return + - [Optional] If a payment address proof $\mathsf{addrProof}$ is present in + $\mathsf{spend}$, verify $(\mathsf{addrProof.nullifier_{addr}}, \mathsf{spend.rk}, \mathsf{addrProof.zkproof_{addr}})$ as a ZIP 304 proof + for $(\mathsf{addrProof.d}, \mathsf{addrProof.pk_d})$ [#zip-0304]_. If verification fails, return false. - - Decode and verify :math:`\mathsf{zkproof_{spend}}` as a Sapling spend proof + - Decode and verify $\mathsf{zkproof_{spend}}$ as a Sapling spend proof [#protocol-spendstatement]_ with primary input: - - :math:`\mathsf{tx.shieldedSpends[spend.index].rt}` - - :math:`\mathsf{spend.cv}` - - :math:`\mathsf{tx.shieldedSpends[spend.index].nf}` - - :math:`\mathsf{spend.rk}` + - $\mathsf{tx.shieldedSpends[spend.index].rt}$ + - $\mathsf{spend.cv}$ + - $\mathsf{tx.shieldedSpends[spend.index].nf}$ + - $\mathsf{spend.rk}$ If verification fails, return false. -- For every :math:`\mathsf{input}` in :math:`\mathsf{pd.transparentInputs}`: +- For every $\mathsf{input}$ in $\mathsf{pd.transparentInputs}$: - TODO: BIP 322 verification. -- For every :math:`\mathsf{output}` in :math:`\mathsf{pd.saplingOutputs}`: +- For every $\mathsf{output}$ in $\mathsf{pd.saplingOutputs}$: - - Recover the Sapling note in :math:`\mathsf{tx.shieldedOutputs}[\mathsf{output.index}]` + - Recover the Sapling note in $\mathsf{tx.shieldedOutputs}[\mathsf{output.index}]$ via the process specified in [#protocol-saplingdecryptovk]_ with inputs - :math:`(height, \mathsf{output.ock})`. If recovery returns :math:`\bot`, return false. + $(height, \mathsf{output.ock})$. If recovery returns $\bot$, return false. - Return true. @@ -377,10 +377,10 @@ should convey the various kinds of validity information: Rationale ========= -If a sender elects, at transaction creation time, to use an :math:`\mathsf{ovk}` of -:math:`\bot` for a specific Sapling output, then they are unable to subsequently create a +If a sender elects, at transaction creation time, to use an $\mathsf{ovk}$ of +$\bot$ for a specific Sapling output, then they are unable to subsequently create a payment disclosure that discloses that output. This maintains the semantics of -:math:`\mathsf{ovk}`, in that the sender explicitly chose to lose the capability to +$\mathsf{ovk}$, in that the sender explicitly chose to lose the capability to recover that output. Payment disclosures that prove Sapling spend authority are not required to reveal a diff --git a/zips/zip-0312.rst b/zips/zip-0312.rst index 0033cba50..05c4619f5 100644 --- a/zips/zip-0312.rst +++ b/zips/zip-0312.rst @@ -87,7 +87,7 @@ shielded transaction: as an auxiliary (secret) input, among others. When employing re-randomizable FROST as specified in this ZIP, the goal is to -split the spend authorization private key :math:`\mathsf{ask}` among multiple +split the spend authorization private key $\mathsf{ask}$ among multiple possible signers. This means that the proof generation will still be performed by a single participant, likely the one that created the transaction in the first place. Note that this user already controls the privacy of the transaction since @@ -130,8 +130,8 @@ The types Scalar, Element, and G are defined in [#frost-primeordergroup]_, as well as the notation for elliptic-curve arithmetic, which uses the additive notation. Note that this notation differs from that used in the Zcash Protocol Specification. For example, ``G.ScalarMult(P, k)`` is used for scalar -multiplication, where the protocol spec would use :math:`[k] P` with the group -implied by :math:`P`. +multiplication, where the protocol spec would use $[k] P$ with the group +implied by $P$. An additional per-ciphersuite hash function is used, denote ``HR(m)``, which receives an arbitrary-sized byte string and returns a Scalar. It is defined @@ -143,12 +143,12 @@ Key Generation While key generation is out of scope for this ZIP and the FROST spec [#FROST]_, it needs to be consistent with FROST, see [#frost-tdkg]_ for guidance. The spend -authorization private key :math:`\mathsf{ask}` [#protocol-spendauthsig]_ is the +authorization private key $\mathsf{ask}$ [#protocol-spendauthsig]_ is the particular key that must be used in the context of this ZIP. Note that the -:math:`\mathsf{ask}` is usually derived from the spending key -:math:`\mathsf{sk}`, though that is not required. Not doing so allows using +$\mathsf{ask}$ is usually derived from the spending key +$\mathsf{sk}$, though that is not required. Not doing so allows using distributed key generation, since the key it generates is unpredictable. Note -however that not deriving :math:`\mathsf{ask}` from :math:`\mathsf{sk}` prevents +however that not deriving $\mathsf{ask}$ from $\mathsf{sk}$ prevents using seed phrases to recover the original secret (which may be something desirable in the context of FROST). @@ -263,16 +263,16 @@ This ciphersuite uses Jubjub for the Group and BLAKE2b-512 for the Hash function meant to produce signatures indistinguishable from RedJubjub Sapling Spend Authorization Signatures as specified in [#protocol-concretespendauthsig]_. -- Group: Jubjub [#protocol-jubjub]_ with base point :math:`\mathcal{G}^{\mathsf{Sapling}}` +- Group: Jubjub [#protocol-jubjub]_ with base point $\mathcal{G}^{\mathsf{Sapling}}$ as defined in [#protocol-concretespendauthsig]_. - - Order: :math:`r_\mathbb{J}` as defined in [#protocol-jubjub]_. + - Order: $r_\mathbb{J}$ as defined in [#protocol-jubjub]_. - Identity: as defined in [#protocol-jubjub]_. - RandomScalar(): Implemented by returning a uniformly random Scalar in the range \[0, ``G.Order()`` - 1\]. Refer to {{frost-randomscalar}} for implementation guidance. - - SerializeElement(P): Implemented as :math:`\mathsf{repr}_\mathbb{J}(P)` as defined in [#protocol-jubjub]_ - - DeserializeElement(P): Implemented as :math:`\mathsf{abst}_\mathbb{J}(P)` as defined in [#protocol-jubjub]_, - returning an error if :math:`\bot` is returned. Additionally, this function + - SerializeElement(P): Implemented as $\mathsf{repr}_\mathbb{J}(P)$ as defined in [#protocol-jubjub]_ + - DeserializeElement(P): Implemented as $\mathsf{abst}_\mathbb{J}(P)$ as defined in [#protocol-jubjub]_, + returning an error if $\bot$ is returned. Additionally, this function validates that the resulting element is not the group identity element, returning an error if the check fails. - SerializeScalar: Implemented by outputting the little-endian 32-byte encoding @@ -290,8 +290,8 @@ Authorization Signatures as specified in [#protocol-concretespendauthsig]_. - H2(m): Implemented by computing BLAKE2b-512("Zcash_RedJubjubH", m), interpreting the 64 bytes as a little-endian integer, and reducing the resulting integer modulo ``G.Order()``. - (This is equivalent to :math:`\mathsf{H}^\circledast(m)`, as defined by - the :math:`\mathsf{RedJubjub}` scheme instantiated in [#protocol-concretereddsa]_.) + (This is equivalent to $\mathsf{H}^\circledast(m)$, as defined by + the $\mathsf{RedJubjub}$ scheme instantiated in [#protocol-concretereddsa]_.) - H3(m): Implemented by computing BLAKE2b-512("FROST_RedJubjubN", m), interpreting the 64 bytes as a little-endian integer, and reducing the resulting integer modulo ``G.Order()``. @@ -312,16 +312,16 @@ This ciphersuite uses Pallas for the Group and BLAKE2b-512 for the Hash function meant to produce signatures indistinguishable from RedPallas Orchard Spend Authorization Signatures as specified in [#protocol-concretespendauthsig]_. -- Group: Pallas [#protocol-pallasandvesta]_ with base point :math:`\mathcal{G}^{\mathsf{Orchard}}` +- Group: Pallas [#protocol-pallasandvesta]_ with base point $\mathcal{G}^{\mathsf{Orchard}}$ as defined in [#protocol-concretespendauthsig]_. - - Order: :math:`r_\mathbb{P}` as defined in [#protocol-pallasandvesta]_. + - Order: $r_\mathbb{P}$ as defined in [#protocol-pallasandvesta]_. - Identity: as defined in [#protocol-pallasandvesta]_. - RandomScalar(): Implemented by returning a uniformly random Scalar in the range \[0, ``G.Order()`` - 1\]. Refer to {{frost-randomscalar}} for implementation guidance. - - SerializeElement(P): Implemented as :math:`\mathsf{repr}_\mathbb{P}(P)` as defined in [#protocol-pallasandvesta]_. - - DeserializeElement(P): Implemented as :math:`\mathsf{abst}_\mathbb{P}(P)` as defined in [#protocol-pallasandvesta]_, - failing if :math:`\bot` is returned. Additionally, this function validates that the resulting + - SerializeElement(P): Implemented as $\mathsf{repr}_\mathbb{P}(P)$ as defined in [#protocol-pallasandvesta]_. + - DeserializeElement(P): Implemented as $\mathsf{abst}_\mathbb{P}(P)$ as defined in [#protocol-pallasandvesta]_, + failing if $\bot$ is returned. Additionally, this function validates that the resulting element is not the group identity element, returning an error if the check fails. - SerializeScalar: Implemented by outputting the little-endian 32-byte encoding of the Scalar value. @@ -338,8 +338,8 @@ Authorization Signatures as specified in [#protocol-concretespendauthsig]_. - H2(m): Implemented by computing BLAKE2b-512("Zcash_RedPallasH", m), interpreting the 64 bytes as a little-endian integer, and reducing the resulting integer modulo ``G.Order()``. - (This is equivalent to :math:`\mathsf{H}^\circledast(m)`, as defined by - the :math:`\mathsf{RedPallas}` scheme instantiated in [#protocol-concretereddsa]_.) + (This is equivalent to $\mathsf{H}^\circledast(m)$, as defined by + the $\mathsf{RedPallas}$ scheme instantiated in [#protocol-concretereddsa]_.) - H3(m): Implemented by computing BLAKE2b-512("FROST_RedPallasN", m), interpreting the 64 bytes as a little-endian integer, and reducing the resulting integer modulo ``G.Order()``. @@ -361,22 +361,22 @@ since there is no widespread standard for Schnorr signatures, it must be ensured that the signatures generated by the FROST variant specified in this ZIP can be verified successfully by a Zcash implementation following its specification. In practice this entails making sure that the generated signature can be verified -by the :math:`\mathsf{RedDSA.Validate}` function specified in +by the $\mathsf{RedDSA.Validate}$ function specified in [#protocol-concretereddsa]_: - The FROST signature, when split into R and S in the first step of - :math:`\mathsf{RedDSA.Validate}`, must yield the values expected by the + $\mathsf{RedDSA.Validate}$, must yield the values expected by the function. This is ensured by defining SerializeElement and SerializeScalar in each ciphersuite to yield those values. - The challenge c used during FROST signing must be equal to the challenge c - computed during :math:`\mathsf{RedDSA.Validate}`. This requires defining the - ciphersuite H2 function as the :math:`\mathsf{H}^\circledast(m)` Zcash + computed during $\mathsf{RedDSA.Validate}$. This requires defining the + ciphersuite H2 function as the $\mathsf{H}^\circledast(m)$ Zcash function in the ciphersuites, and making sure its input will be the same. Fortunately FROST and Zcash use the same input order (R, public key, message) so we just need to make sure that SerializeElement (used to compute the encoded public key before passing to the hash function) matches what - :math:`\mathsf{RedDSA.Validate}` expects; which is possible since both `R` and + $\mathsf{RedDSA.Validate}$ expects; which is possible since both `R` and `vk` (the public key) are encoded in the same way as in Zcash. - Note that ``r`` (and thus ``R``) will not be generated as specified in RedDSA.Sign. @@ -385,7 +385,7 @@ by the :math:`\mathsf{RedDSA.Validate}` function specified in uniformly at random, which is true for FROST. - The above will ensure that the verification equation in - :math:`\mathsf{RedDSA.Validate}` will pass, since FROST ensures the exact same + $\mathsf{RedDSA.Validate}$ will pass, since FROST ensures the exact same equation will be valid as described in [#frost-primeorderverify]_. The second step is adding the re-randomization functionality so that each FROST @@ -403,8 +403,8 @@ signing generates a re-randomized signature: so we can only look into the second term of each top-level addition, i.e. ``c * sk`` must be equal to ``sum(lambda_i * c * sk_i)`` for each participant ``i``. Under re-randomization these become ``c * (sk + randomizer)`` (see - :math:`\mathsf{RedDSA.RandomizedPrivate}`, which refers to the randomizer as - :math:`\alpha`) and ``sum(lambda_i * c * (sk_i + randomizer))``. The latter + $\mathsf{RedDSA.RandomizedPrivate}$, which refers to the randomizer as + $\alpha$) and ``sum(lambda_i * c * (sk_i + randomizer))``. The latter can be rewritten as ``c * (sum(lambda_i * sk_i) + randomizer * sum(lambda_i)``. Since ``sum(lambda_i * sk_i) == sk`` per the Shamir secret sharing mechanism used by FROST, and since ``sum(lambda_i) == 1`` @@ -414,10 +414,10 @@ signing generates a re-randomized signature: [#protocol-concretereddsa]_ to ensure that re-randomized keys are uniformly distributed and signatures are unlinkable. This is also true; observe that ``randomizer_generate`` generates randomizer uniformly at random as required - by :math:`\mathsf{RedDSA.GenRandom}`; and signature generation is compatible - with :math:`\mathsf{RedDSA.RandomizedPrivate}`, - :math:`\mathsf{RedDSA.RandomizedPublic}`, :math:`\mathsf{RedDSA.Sign}` and - :math:`\mathsf{RedDSA.Validate}` as explained in the previous item. + by $\mathsf{RedDSA.GenRandom}$; and signature generation is compatible + with $\mathsf{RedDSA.RandomizedPrivate}$, + $\mathsf{RedDSA.RandomizedPublic}$, $\mathsf{RedDSA.Sign}$ and + $\mathsf{RedDSA.Validate}$ as explained in the previous item. The security of Re-Randomized FROST with respect to the security assumptions of regular FROST is shown in [#frost-rerandomized]_. diff --git a/zips/zip-0316.rst b/zips/zip-0316.rst index 9cbc1ba43..973735b2c 100644 --- a/zips/zip-0316.rst +++ b/zips/zip-0316.rst @@ -364,14 +364,14 @@ for distinct types. That is, the set may optionally contain one Receiver of each of the Receiver Types in the following fixed Priority List: -* Typecode :math:`\mathtt{0x03}` — an Orchard raw address as defined +* Typecode $\mathtt{0x03}$ — an Orchard raw address as defined in [#protocol-orchardpaymentaddrencoding]_; -* Typecode :math:`\mathtt{0x02}` — a Sapling raw address as defined +* Typecode $\mathtt{0x02}$ — a Sapling raw address as defined in [#protocol-saplingpaymentaddrencoding]_; -* Typecode :math:`\mathtt{0x01}` — a Transparent P2SH address, *or* - Typecode :math:`\mathtt{0x00}` — a Transparent P2PKH address. +* Typecode $\mathtt{0x01}$ — a Transparent P2SH address, *or* + Typecode $\mathtt{0x00}$ — a Transparent P2PKH address. If, and only if, the user of a Producer or Consumer wallet explicitly opts into an experiment as described in `Experimental Usage`_, the @@ -392,33 +392,33 @@ Orchard Receiver and possibly other Receivers, it MUST send to the Orchard Receiver. The raw encoding of a Unified Address is a concatenation of -:math:`(\mathtt{typecode}, \mathtt{length}, \mathtt{addr})` encodings +$(\mathtt{typecode}, \mathtt{length}, \mathtt{addr})$ encodings of the constituent Receivers, in ascending order of Typecode: -* :math:`\mathtt{typecode} : \mathtt{compactSize}` — the Typecode from the +* $\mathtt{typecode} : \mathtt{compactSize}$ — the Typecode from the above Priority List; -* :math:`\mathtt{length} : \mathtt{compactSize}` — the length in bytes of - :math:`\mathtt{addr};` +* $\mathtt{length} : \mathtt{compactSize}$ — the length in bytes of + $\mathtt{addr};$ -* :math:`\mathtt{addr} : \mathtt{byte[length]}` — the Receiver Encoding. +* $\mathtt{addr} : \mathtt{byte[length]}$ — the Receiver Encoding. -The values of the :math:`\mathtt{typecode}` and :math:`\mathtt{length}` -fields MUST be less than or equal to :math:`\mathtt{0x2000000}.` +The values of the $\mathtt{typecode}$ and $\mathtt{length}$ +fields MUST be less than or equal to $\mathtt{0x2000000}.$ (The limitation on the total length of encodings described below imposes -a smaller limit for :math:`\mathtt{length}` in practice.) +a smaller limit for $\mathtt{length}$ in practice.) A Receiver Encoding is the raw encoding of a Shielded Payment Address, -or the :math:`160\!`-bit script hash of a P2SH address [#P2SH]_, or the -:math:`160\!`-bit validating key hash of a P2PKH address [#P2PKH]_. +or the $160$-bit script hash of a P2SH address [#P2SH]_, or the +$160$-bit validating key hash of a P2PKH address [#P2PKH]_. Let ``padding`` be the Human-Readable Part of the Unified Address in US-ASCII, padded to 16 bytes with zero bytes. We append ``padding`` to -the concatenated encodings, and then apply the :math:`\mathsf{F4Jumble}` +the concatenated encodings, and then apply the $\mathsf{F4Jumble}$ algorithm as described in `Jumbling`_. (In order for the limitation on -the :math:`\mathsf{F4Jumble}` input size to be met, the total length of -encodings MUST be at most :math:`\ell^\mathsf{MAX}_M - 16` bytes, where -:math:`\ell^\mathsf{MAX}_M` is defined in `Jumbling`_.) +the $\mathsf{F4Jumble}$ input size to be met, the total length of +encodings MUST be at most $\ell^\mathsf{MAX}_M - 16$ bytes, where +$\ell^\mathsf{MAX}_M$ is defined in `Jumbling`_.) The output is then encoded with Bech32m [#bip-0350]_, ignoring any length restrictions. This is chosen over Bech32 in order to better handle variable-length inputs. @@ -427,7 +427,7 @@ To decode a Unified Address Encoding, a Consumer MUST use the following procedure: * Decode using Bech32m, rejecting any address with an incorrect checksum. -* Apply :math:`\mathsf{F4Jumble}^{-1}` (this can also reject if the input +* Apply $\mathsf{F4Jumble}^{-1}$ (this can also reject if the input is not in the correct range of lengths). * Let ``padding`` be the Human-Readable Part, padded to 16 bytes as for encoding. If the result ends in ``padding``, remove these 16 bytes; @@ -461,40 +461,40 @@ future, and these will not necessarily use the same Typecode as the corresponding Unified Address. The following FVK or IVK Encodings are used in place of the -:math:`\mathtt{addr}` field: +$\mathtt{addr}$ field: -* An Orchard FVK or IVK Encoding, with Typecode :math:`\mathtt{0x03},` is +* An Orchard FVK or IVK Encoding, with Typecode $\mathtt{0x03},$ is the raw encoding of the Orchard Full Viewing Key or Orchard Incoming Viewing Key respectively. -* A Sapling FVK Encoding, with Typecode :math:`\mathtt{0x02},` is the - encoding of :math:`(\mathsf{ak}, \mathsf{nk}, \mathsf{ovk}, \mathsf{dk})` - given by :math:`\mathsf{EncodeExtFVKParts}(\mathsf{ak}, \mathsf{nk}, \mathsf{ovk}, \mathsf{dk})`, - where :math:`\mathsf{EncodeExtFVKParts}` is defined in [#zip-0032-sapling-helper-functions]_. +* A Sapling FVK Encoding, with Typecode $\mathtt{0x02},$ is the + encoding of $(\mathsf{ak}, \mathsf{nk}, \mathsf{ovk}, \mathsf{dk})$ + given by $\mathsf{EncodeExtFVKParts}(\mathsf{ak}, \mathsf{nk}, \mathsf{ovk}, \mathsf{dk})$, + where $\mathsf{EncodeExtFVKParts}$ is defined in [#zip-0032-sapling-helper-functions]_. This SHOULD be derived from the Extended Full Viewing Key at the Account level of the ZIP 32 hierarchy. -* A Sapling IVK Encoding, also with Typecode :math:`\mathtt{0x02},` - is an encoding of :math:`(\mathsf{dk}, \mathsf{ivk})` given by - :math:`\mathsf{dk}\,||\,\mathsf{I2LEOSP}_{256}(\mathsf{ivk}).` +* A Sapling IVK Encoding, also with Typecode $\mathtt{0x02},$ + is an encoding of $(\mathsf{dk}, \mathsf{ivk})$ given by + $\mathsf{dk}\,||\,\mathsf{I2LEOSP}_{256}(\mathsf{ivk}).$ * 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 :math:`\mathtt{0x01}` + diversified in an unlinkable way). The Typecode $\mathtt{0x01}$ MUST NOT be included in a UFVK or UIVK by Producers, and MUST be treated as unrecognised by Consumers. * For Transparent P2PKH Addresses that are derived according to BIP 32 [#bip-0032]_ and BIP 44 [#bip-0044]_, the FVK and IVK Encodings have - Typecode :math:`\mathtt{0x00}.` Both of these are encodings of the - chain code and public key :math:`(\mathsf{c}, \mathsf{pk})` given by - :math:`\mathsf{c}\,||\,\mathsf{ser_P}(\mathsf{pk})`. (This is the + Typecode $\mathtt{0x00}.$ Both of these are encodings of the + chain code and public key $(\mathsf{c}, \mathsf{pk})$ given by + $\mathsf{c}\,||\,\mathsf{ser_P}(\mathsf{pk})$. (This is the same as the last 65 bytes of the extended public key format defined in section “Serialization format” of BIP 32 [#bip-0032-serialization-format]_.) However, the FVK uses the key at the Account level, i.e. at path - :math:`m / 44' / coin\_type' / account'`, while the IVK uses the + $m / 44' / coin\_type' / account'$, while the IVK uses the external (non-change) child key at the Change level, i.e. at path - :math:`m / 44' / coin\_type' / account' / 0`. + $m / 44' / coin\_type' / account' / 0$. The Human-Readable Part is as specified for a Unified Viewing Key in `Revisions`_. @@ -525,12 +525,13 @@ Requirements for both Unified Addresses and Unified Viewing Keys ---------------------------------------------------------------- * A `Revision 0`_ Unified Address or Unified Viewing Key MUST contain - at least one shielded Item (Typecodes :math:`\mathtt{0x02}` and - :math:`\mathtt{0x03}`). This requirement is dropped for `Revision 1`_ - UA/UVKs. + at least one shielded Item (Typecodes $\mathtt{0x02}$ and + $\mathtt{0x03}$). This requirement is dropped for `Revision 1`_ + UA/UVKs; however, a `Revision 1`_ UA/UVK MUST contain at least one + non-Metadata Item. -* The :math:`\mathtt{typecode}` and :math:`\mathtt{length}` fields are - encoded as :math:`\mathtt{compactSize}.` [#Bitcoin-CompactSize]_ +* The $\mathtt{typecode}$ and $\mathtt{length}$ fields are + encoded as $\mathtt{compactSize}.$ [#Bitcoin-CompactSize]_ (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.) @@ -553,8 +554,7 @@ Requirements for both Unified Addresses and Unified Viewing Keys * 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. + P2PKH Transparent Addresses, or that contain only Metadata Items. * Consumers MUST reject Unified Addresses/Viewing Keys in which *any* constituent Item does not meet the validation requirements of its @@ -643,8 +643,8 @@ be introduced either by a modification to this ZIP or by a new ZIP, in accordance with the ZIP Process [#zip-0000]_. For experimentation prior to proposing a ZIP, experimental types MAY -be added using the reserved Typecodes :math:`\mathtt{0xFFFA}` to -:math:`\mathtt{0xFFFF}` inclusive. This provides for six simultaneous +be added using the reserved Typecodes $\mathtt{0xFFFA}$ to +$\mathtt{0xFFFF}$ 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 @@ -659,7 +659,7 @@ to give access only to view incoming payments (as opposed to change). Metadata Items -------------- -Typecodes :math:`\mathtt{0xC0}` to :math:`\mathtt{0xFC}` inclusive +Typecodes $\mathtt{0xC0}$ to $\mathtt{0xFC}$ 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). @@ -667,7 +667,7 @@ the UA/UVK (for example, by specifying an expiration date). .. _`MUST-understand Typecodes`: As of `Revision 1`_ of this ZIP, the subset of Metadata Typecodes in -the range :math:`\mathtt{0xE0}` to :math:`\mathtt{0xFC}` inclusive are +the range $\mathtt{0xE0}$ to $\mathtt{0xFC}$ inclusive are designated as "MUST-understand": if a Consumer is unable to recognise the meaning of a Metadata Item with a Typecode in this range, then it MUST regard the entire UA/UVK as unsupported and not process it further. @@ -708,21 +708,21 @@ such implementations. Address Expiration Metadata --------------------------- -As of `Revision 1`_, Typecodes :math:`\mathtt{0xE0}` and :math:`\mathtt{0xE1}` +As of `Revision 1`_, Typecodes $\mathtt{0xE0}$ and $\mathtt{0xE1}$ are reserved for optional address expiry metadata. A producer MAY choose to generate Unified Addresses containing either or both of the following Metadata Item Types, or none. -The value of a :math:`\mathtt{0xE0}` item MUST be an unsigned 32-bit integer in +The value of a $\mathtt{0xE0}$ item MUST be an unsigned 32-bit integer in little-endian order specifying the Address Expiry Height, a block height of the Zcash chain associated with the UA/UVK. A Unified Address containing metadata -Typecode :math:`\mathtt{0xE0}` MUST be considered expired when the height of +Typecode $\mathtt{0xE0}$ MUST be considered expired when the height of the Zcash chain is greater than this value. -The value of a :math:`\mathtt{0xE1}` item MUST be an unsigned 64-bit integer in +The value of a $\mathtt{0xE1}$ item MUST be an unsigned 64-bit integer in little-endian order specifying a Unix Epoch Time, hereafter referred to as the Address Expiry Time. A Unified Address containing Metadata Typecode -:math:`\mathtt{0xE1}` MUST be considered expired when the current time is +$\mathtt{0xE1}$ MUST be considered expired when the current time is after the Address Expiry Time. A Sender that supports `Revision 1`_ of this specification MUST set @@ -732,7 +732,7 @@ sent to a Unified Address that defines an Address Expiry Height. If the Address Expiry Height, then the transaction MUST NOT be sent. If only an Address Expiry Time is specified, then the Sender SHOULD choose a value for ``nExpiryHeight`` such that the transaction will expire no more than 24 hours -after the current time. If both :math:`\mathtt{0xE0}` and :math:`\mathtt{0xE1}` +after the current time. If both $\mathtt{0xE0}$ and $\mathtt{0xE1}$ Metadata Items are present, then both restrictions apply. If a Sender sends to multiple Unified Addresses in the same transaction, then @@ -751,19 +751,19 @@ that although changes to metadata will result in a visually distinct address, such updated addresses will be directly linkable to the original addresses because they share the same Receivers. -When deriving a UIVK from a UFVK containing Typecodes :math:`\mathtt{0xE0}` -and/or :math:`\mathtt{0xE1}`, these Metadata Items MUST be retained unmodified +When deriving a UIVK from a UFVK containing Typecodes $\mathtt{0xE0}$ +and/or $\mathtt{0xE1}$, these Metadata Items MUST be retained unmodified in the derived UIVK. When deriving a Unified Address from a UFVK or UIVK containing a Metadata Item -having Typecode :math:`\mathtt{0xE0}`, the derived Unified Address MUST contain -a Metadata Item having Typecode :math:`\mathtt{0xE0}` such that the Address +having Typecode $\mathtt{0xE0}$, the derived Unified Address MUST contain +a Metadata Item having Typecode $\mathtt{0xE0}$ such that the Address Expiry Height of the resulting address is less than or equal to the Expiry Height of the viewing key. When deriving a Unified Address from a UFVK or UIVK containing a Metadata Item -having Typecode :math:`\mathtt{0xE1}`, the derived Unified Address MUST contain -a Metadata Item having Typecode :math:`\mathtt{0xE1}` such that the Address +having Typecode $\mathtt{0xE1}$, the derived Unified Address MUST contain +a Metadata Item having Typecode $\mathtt{0xE1}$ such that the Address Expiry Time of the resulting address is less than or equal to the Expiry Time of the viewing key. @@ -816,17 +816,17 @@ We desire the following properties for viewing authority of both shielded and transparent key trees: - A holder of an FVK can derive external and internal IVKs, and - external and internal :math:`\mathsf{ovk}` components. + external and internal $\mathsf{ovk}$ components. - A holder of the external IVK cannot derive the internal IVK, or - any of the :math:`\mathsf{ovk}` components. + any of the $\mathsf{ovk}$ components. -- A holder of the external :math:`\mathsf{ovk}` component cannot derive - the internal :math:`\mathsf{ovk}` component, or any of the IVKs. +- A holder of the external $\mathsf{ovk}$ component cannot derive + the internal $\mathsf{ovk}$ component, or any of the IVKs. For shielded keys, these properties are achieved by the one-wayness of -:math:`\mathsf{PRF^{expand}}` and of :math:`\mathsf{CRH^{ivk}}` or -:math:`\mathsf{Commit^{ivk}}` (for Sapling and Orchard respectively). +$\mathsf{PRF^{expand}}$ and of $\mathsf{CRH^{ivk}}$ or +$\mathsf{Commit^{ivk}}$ (for Sapling and Orchard respectively). Derivation of an internal shielded FVK from an external shielded FVK is specified in the "Sapling internal key derivation" [#zip-0032-sapling-internal-key-derivation]_ and @@ -834,15 +834,15 @@ is specified in the sections of ZIP 32. To satisfy the above properties for transparent (P2PKH) keys, we derive -the external and internal :math:`\mathsf{ovk}` components from the -transparent FVK :math:`(\mathsf{c}, \mathsf{pk})` (described in +the external and internal $\mathsf{ovk}$ components from the +transparent FVK $(\mathsf{c}, \mathsf{pk})$ (described in `Encoding of Unified Full/Incoming Viewing Keys`_) as follows: -- Let :math:`I_\mathsf{ovk} = \mathsf{PRF^{expand}}_{\mathsf{LEOS2BSP}_{256}(\mathsf{c})}\big([\mathtt{0xd0}] \,||\, \mathsf{ser_P}(\mathsf{pk})\big)` - where :math:`\mathsf{ser_P}(pk)` is :math:`33` bytes, as specified in [#bip-0032-serialization-format]_. -- Let :math:`\mathsf{ovk_{external}}` be the first :math:`32` bytes of - :math:`I_\mathsf{ovk}` and let :math:`\mathsf{ovk_{internal}}` be the - remaining :math:`32` bytes of :math:`I_\mathsf{ovk}`. +- Let $I_\mathsf{ovk} = \mathsf{PRF^{expand}}_{\mathsf{LEOS2BSP}_{256}(\mathsf{c})}\big([\mathtt{0xd0}] \,||\, \mathsf{ser_P}(\mathsf{pk})\big)$ + where $\mathsf{ser_P}(pk)$ is $33$ bytes, as specified in [#bip-0032-serialization-format]_. +- Let $\mathsf{ovk_{external}}$ be the first $32$ bytes of + $I_\mathsf{ovk}$ and let $\mathsf{ovk_{internal}}$ be the + remaining $32$ bytes of $I_\mathsf{ovk}$. Since an external P2PKH FVK encodes the chain code and public key at the Account level, we can derive both external and internal child keys from @@ -877,7 +877,7 @@ The following derivations are applied to each component FVK: specified in [#protocol-orchardkeycomponents]_. * For a Transparent P2PKH FVK, the corresponding Transparent P2PKH IVK - is obtained by deriving the child key with non-hardened index :math:`0` + is obtained by deriving the child key with non-hardened index $0$ as described in [#bip-0032-public-to-public]_. In each case, the Typecode remains the same as in the FVK. @@ -911,11 +911,23 @@ UIVK. That is, defined in ZIP 32 section “Sapling diversifier derivation” [#zip-0032-sapling-diversifier-derivation]_. -* A Transparent diversifier index MUST be in the range :math:`0` to - :math:`2^{31} - 1` inclusive. +* A Transparent diversifier index MUST be in the range $0$ to + $2^{31} - 1$ inclusive. * There are no additional constraints on an Orchard diversifier index. +Note: A diversifier index of 0 may not generate a valid Sapling +diversifier (with probability $1/2$). Some wallets (either prior +to the deployment of ZIP 316, in violation of the above requirement, +or because they do not include a Sapling component in their UAs) always +generate a Transparent P2PKH address at diversifier index 0. Therefore, +*all* Zcash wallets, whether or not they support Unified Addresses, +MUST assume that there may be transparent funds associated with +diversifier index 0 for each ZIP 32 account, even in cases where the +wallet implementation would not generate a Unified Address with that +index for a given account. This is necessary to ensure reliable recovery +of funds if key material is imported between wallets. + The following derivations are applied to each component IVK using the diversifier index: @@ -933,7 +945,7 @@ diversifier index: 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 - :math:`m / 44' / \mathit{coin\_type\kern0.05em'} / \mathit{account\kern0.1em'} / 0 / \mathit{diversifier\_index}.` + $m / 44' / \mathit{coin\_type\kern0.05em'} / \mathit{account\kern0.1em'} / 0 / \mathit{diversifier\_index}.$ In each case, the Typecode remains the same as in the IVK. @@ -985,7 +997,7 @@ most preferred Receiver Type (as given in `Encoding of Unified Addresses`_) of any funds sent in the transaction. If the sending Account has been determined, then the Sender -SHOULD use the external or internal :math:`\mathsf{ovk}` +SHOULD use the external or internal $\mathsf{ovk}$ (according to the type of transfer), as specified by the preferred sending protocol, of the full viewing key for that Account (i.e. at the ZIP 32 Account level). @@ -994,7 +1006,7 @@ 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 :math:`\mathsf{ovk}` (according to the +the external or internal $\mathsf{ovk}$ (according to the type of transfer) of the full viewing key for that address. @@ -1003,15 +1015,15 @@ Jumbling Security goal (**near second preimage resistance**): -* An adversary is given :math:`q` Unified Addresses/Viewing Keys, generated +* An adversary is given $q$ Unified Addresses/Viewing Keys, generated honestly. * The attack goal is to produce a “partially colliding” valid Unified Address/Viewing Key that: a) has a string encoding matching that of *one of* the input Addresses/Viewing Keys on some subset of characters (for concreteness, - consider the first :math:`n` and last :math:`m` characters, up to some - bound on :math:`n+m`); + consider the first $n$ and last $m$ characters, up to some + bound on $n+m$); b) is controlled by the adversary (for concreteness, the adversary knows *at least one* of the private keys of the constituent Addresses). @@ -1030,20 +1042,20 @@ Discussion There is a generic brute force attack against near second preimage resistance. The adversary generates UAs / UVKs at random with known keys, until one has an -encoding that partially collides with one of the :math:`q` targets. It may be +encoding that partially collides with one of the $q$ targets. It may be possible to improve on this attack by making use of properties of checksums, etc. The generic attack puts an upper bound on the achievable security: if it takes -work :math:`w` to produce and verify a UA/UVK, and the size of the character -set is :math:`c,` then the generic attack costs :math:`\sim \frac{w \cdot +work $w$ to produce and verify a UA/UVK, and the size of the character +set is $c,$ then the generic attack costs :math:`\sim \frac{w \cdot c^{n+m}}{q}.` There is also a generic brute force attack against nonmalleability. The adversary modifies the target UA/UVK slightly and computes the corresponding decoding, then repeats until the decoding is valid and also useful to the adversary (e.g. it would lead to the Sender using a Transparent Address). -With :math:`w` defined as above, the cost is :math:`w/p` where :math:`p` is +With $w$ defined as above, the cost is $w/p$ where $p$ is the probability that a random decoding is of the required form. Solution @@ -1052,41 +1064,41 @@ Solution We use an unkeyed 4-round Feistel construction to approximate a random permutation. (As explained below, 3 rounds would not be sufficient.) -Let :math:`H_i` be a hash personalized by :math:`i,` with maximum output -length :math:`\ell_H` bytes. Let :math:`G_i` be a XOF (a hash function with -extendable output length) based on :math:`H,` personalized by :math:`i.` +Let $H_i$ be a hash personalized by $i,$ with maximum output +length $\ell_H$ bytes. Let $G_i$ be a XOF (a hash function with +extendable output length) based on $H,$ personalized by $i.$ -Define :math:`\ell^\mathsf{MAX}_M = (2^{16} + 1) \cdot \ell_H.` +Define $\ell^\mathsf{MAX}_M = (2^{16} + 1) \cdot \ell_H.$ For the instantiation using BLAKE2b defined below, -:math:`\ell^\mathsf{MAX}_M = 4194368.` +$\ell^\mathsf{MAX}_M = 4194368.$ -Given input :math:`M` of length :math:`\ell_M` bytes such that -:math:`48 \leq \ell_M \leq \ell^\mathsf{MAX}_M,` define -:math:`\mathsf{F4Jumble}(M)` by: +Given input $M$ of length $\ell_M$ bytes such that +$38 \leq \ell_M \leq \ell^\mathsf{MAX}_M,$ define +$\mathsf{F4Jumble}(M)$ by: -* let :math:`\ell_L = \mathsf{min}(\ell_H, \mathsf{floor}(\ell_M/2))` -* let :math:`\ell_R = \ell_M - \ell_L` -* split :math:`M` into :math:`a` of length :math:`\ell_L` bytes and :math:`b` of length :math:`\ell_R` bytes -* let :math:`x = b \oplus G_0(a)` -* let :math:`y = a \oplus H_0(x)` -* let :math:`d = x \oplus G_1(y)` -* let :math:`c = y \oplus H_1(d)` -* return :math:`c \,||\, d.` +* let $\ell_L = \mathsf{min}(\ell_H, \mathsf{floor}(\ell_M/2))$ +* let $\ell_R = \ell_M - \ell_L$ +* split $M$ into $a$ of length $\ell_L$ bytes and $b$ of length $\ell_R$ bytes +* let $x = b \oplus G_0(a)$ +* let $y = a \oplus H_0(x)$ +* let $d = x \oplus G_1(y)$ +* let $c = y \oplus H_1(d)$ +* return $c \,||\, d.$ -The inverse function :math:`\mathsf{F4Jumble}^{-1}` is obtained in the usual -way for a Feistel construction, by observing that :math:`r = p \oplus q` implies :math:`p = r \oplus q.` +The inverse function $\mathsf{F4Jumble}^{-1}$ is obtained in the usual +way for a Feistel construction, by observing that $r = p \oplus q$ implies $p = r \oplus q.$ The first argument to BLAKE2b below is the personalization. -We instantiate :math:`H_i(u)` by -:math:`\mathsf{BLAKE2b‐}(8\ell_L)(\texttt{“UA_F4Jumble_H”} \,||\,` -:math:`[i, 0, 0], u),` with :math:`\ell_H = 64.` +We instantiate $H_i(u)$ by +$\mathsf{BLAKE2b‐}(8\ell_L)(\texttt{“UA\_F4Jumble\_H”} \,||\,$ +$[i, 0, 0], u),$ with $\ell_H = 64.$ -We instantiate :math:`G_i(u)` as the first :math:`\ell_R` bytes of the +We instantiate $G_i(u)$ as the first $\ell_R$ bytes of the concatenation of -:math:`[\mathsf{BLAKE2b‐}512(\texttt{“UA_F4Jumble_G”} \,||\, [i] \,||\,` -:math:`\mathsf{I2LEOSP}_{16}(j), u) \text{ for } j \text{ from}` -:math:`0 \text{ up to } \mathsf{ceiling}(\ell_R/\ell_H)-1].` +$[\mathsf{BLAKE2b‐}512(\texttt{“UA\_F4Jumble\_G”} \,||\, [i] \,||\,$ +$\mathsf{I2LEOSP}_{16}(j), u) \text{ for } j \text{ from}$ +$0 \text{ up to } \mathsf{ceiling}(\ell_R/\ell_H)-1].$ .. figure:: ../rendered/assets/images/zip-0316-f4.png :width: 372px @@ -1095,8 +1107,8 @@ concatenation of Diagram of 4-round unkeyed Feistel construction -(In practice the lengths :math:`\ell_L` and :math:`\ell_R` will be roughly -the same until :math:`\ell_M` is larger than :math:`128` bytes.) +(In practice the lengths $\ell_L$ and $\ell_R$ will be roughly +the same until $\ell_M$ is larger than $128$ bytes.) Usage for Unified Addresses, UFVKs, and UIVKs ''''''''''''''''''''''''''''''''''''''''''''' @@ -1104,12 +1116,12 @@ Usage for Unified Addresses, UFVKs, and UIVKs In order to prevent the generic attack against nonmalleability, there needs to be some redundancy in the encoding. Therefore, the Producer of a Unified Address, UFVK, or UIVK appends the HRP, padded to 16 bytes with -zero bytes, to the raw encoding, then applies :math:`\mathsf{F4Jumble}` +zero bytes, to the raw encoding, then applies $\mathsf{F4Jumble}$ before encoding the result with Bech32m. The Consumer rejects any Bech32m-decoded byte sequence that is less than -38 bytes or greater than :math:`\ell^\mathsf{MAX}_M` bytes; otherwise it -applies :math:`\mathsf{F4Jumble}^{-1}.` It rejects any result that does +38 bytes or greater than $\ell^\mathsf{MAX}_M$ bytes; otherwise it +applies $\mathsf{F4Jumble}^{-1}.$ It rejects any result that does not end in the expected 16-byte padding, before stripping these 16 bytes and parsing the result. @@ -1121,7 +1133,7 @@ Rationale for length restrictions
                  Click to show/hide -A minimum input length to :math:`\mathsf{F4Jumble}^{-1}` of 38 bytes +A minimum input length to $\mathsf{F4Jumble}^{-1}$ of 38 bytes allows for the minimum size of a UA/UVK Item encoding to be 22 bytes including the typecode and length, taking into account 16 bytes of padding. This allows for a UA containing only a Transparent P2PKH Receiver: @@ -1132,15 +1144,15 @@ This allows for a UA containing only a Transparent P2PKH Receiver: * 1-byte encoding of length * 20-byte transparent address hash -:math:`\ell^\mathsf{MAX}_M` bytes is the largest input/output size -supported by :math:`\mathsf{F4Jumble}.` +$\ell^\mathsf{MAX}_M$ bytes is the largest input/output size +supported by $\mathsf{F4Jumble}.$ Allowing only a Transparent P2PKH Receiver is consistent with dropping the requirement to have at least one shielded Item in Revision 1 UA/UVKs (`see rationale <#rationale-for-dropping-the-at-least-one-shielded-item-restriction>`_). Note that Revision 0 of this ZIP specified a minimum input length to -:math:`\mathsf{F4Jumble}^{-1}` of 48 bytes. Since there were no sets +$\mathsf{F4Jumble}^{-1}$ of 48 bytes. Since there were no sets of UA/UVK Item Encodings valid in Revision 0 to which a byte sequence (after removal of the 16-byte padding) of length between 22 and 31 bytes inclusive could be parsed, the difference between the 38 and 48-byte @@ -1166,31 +1178,31 @@ A 3-round unkeyed Feistel, as shown, is not sufficient: Diagram of 3-round unkeyed Feistel construction Suppose that an adversary has a target input/output pair -:math:`(a \,||\, b, c \,||\, d),` and that the input to :math:`H_0` is -:math:`x.` By fixing :math:`x,` we can obtain another pair -:math:`((a \oplus t) \,||\, b', (c \oplus t) \,||\, d')` such that -:math:`a \oplus t` is close to :math:`a` and :math:`c \oplus t` is close -to :math:`c.` -(:math:`b'` and :math:`d'` will not be close to :math:`b` and :math:`d,` +$(a \,||\, b, c \,||\, d),$ and that the input to $H_0$ is +$x.$ By fixing $x,$ we can obtain another pair +$((a \oplus t) \,||\, b', (c \oplus t) \,||\, d')$ such that +$a \oplus t$ is close to $a$ and $c \oplus t$ is close +to $c.$ +($\!b'$ and $d'$ will not be close to $b$ and $d,$ but that isn't necessarily required for a valid attack.) -A 4-round Feistel thwarts this and similar attacks. Defining :math:`x` and -:math:`y` as the intermediate values in the first diagram above: +A 4-round Feistel thwarts this and similar attacks. Defining $x$ and +$y$ as the intermediate values in the first diagram above: -* if :math:`(x', y')` are fixed to the same values as :math:`(x, y),` then - :math:`(a', b', c', d') = (a, b, c, d);` +* if $(x', y')$ are fixed to the same values as $(x, y),$ then + $(a', b', c', d') = (a, b, c, d);$ -* if :math:`x' = x` but :math:`y' \neq y,` then the adversary is able to - introduce a controlled :math:`\oplus\!`-difference - :math:`a \oplus a' = y \oplus y',` but the other three pieces - :math:`(b, c, d)` are all randomized, which is sufficient; +* if $x' = x$ but $y' \neq y,$ then the adversary is able to + introduce a controlled $\oplus$-difference + $a \oplus a' = y \oplus y',$ but the other three pieces + $(b, c, d)$ are all randomized, which is sufficient; -* if :math:`y' = y` but :math:`x' \neq x,` then the adversary is able to - introduce a controlled :math:`\oplus\!`-difference - :math:`d \oplus d' = x \oplus x',` but the other three pieces - :math:`(a, b, c)` are all randomized, which is sufficient; +* if $y' = y$ but $x' \neq x,$ then the adversary is able to + introduce a controlled $\oplus$-difference + $d \oplus d' = x \oplus x',$ but the other three pieces + $(a, b, c)$ are all randomized, which is sufficient; -* if :math:`x' \neq x` and :math:`y' \neq y,` all four pieces are +* if $x' \neq x$ and $y' \neq y,$ all four pieces are randomized. Note that the size of each piece is at least 19 bytes. @@ -1208,36 +1220,36 @@ attacks, or attacks that confuse addresses with viewing keys. Efficiency '''''''''' -The cost is dominated by 4 BLAKE2b compressions for :math:`\ell_M \leq 128` +The cost is dominated by 4 BLAKE2b compressions for $\ell_M \leq 128$ bytes. A UA containing a Transparent Address, a Sapling Address, and an -Orchard Address, would have :math:`\ell_M = 128` bytes. The restriction +Orchard Address, would have $\ell_M = 128$ 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. For longer UAs (when other Receiver Types are added) or UVKs, the cost -increases to 6 BLAKE2b compressions for :math:`128 < \ell_M \leq 192,` and -10 BLAKE2b compressions for :math:`192 < \ell_M \leq 256,` for example. The +increases to 6 BLAKE2b compressions for $128 < \ell_M \leq 192,$ and +10 BLAKE2b compressions for $192 < \ell_M \leq 256,$ for example. The maximum cost for which the algorithm is defined would be 196608 BLAKE2b -compressions at :math:`\ell_M = \ell^\mathsf{MAX}_M` bytes. +compressions at $\ell_M = \ell^\mathsf{MAX}_M$ bytes. -A naĂŻve implementation of the :math:`\mathsf{F4Jumble}^{-1}` function would -require roughly :math:`\ell_M` bytes plus the size of a BLAKE2b hash state. -However, it is possible to reduce this by streaming the :math:`d` part of +A naĂŻve implementation of the $\mathsf{F4Jumble}^{-1}$ function would +require roughly $\ell_M$ bytes plus the size of a BLAKE2b hash state. +However, it is possible to reduce this by streaming the $d$ part of the jumbled encoding three times from a less memory-constrained device. It -is essential that the streamed value of :math:`d` is the same on each pass, +is essential that the streamed value of $d$ is the same on each pass, which can be verified using a Message Authentication Code (with key held only by the Consumer) or collision-resistant hash function. After the first -pass of :math:`d`, the implementation is able to compute :math:`y;` after -the second pass it is able to compute :math:`a;` and the third allows it to -compute and incrementally parse :math:`b.` The maximum memory usage during +pass of $d$, the implementation is able to compute $y;$ after +the second pass it is able to compute $a;$ and the third allows it to +compute and incrementally parse $b.$ The maximum memory usage during this process would be 128 bytes plus two BLAKE2b hash states. -Since this streaming implementation of :math:`\mathsf{F4Jumble}^{-1}` is +Since this streaming implementation of $\mathsf{F4Jumble}^{-1}$ is quite complicated, we do not require all Consumers to support streaming. If a Consumer implementation cannot support UAs / UVKs up to the maximum length, -it MUST nevertheless support UAs / UVKs with :math:`\ell_M` of at least -:math:`256` bytes. Note that this effectively defines two conformance levels +it MUST nevertheless support UAs / UVKs with $\ell_M$ of at least +$256$ bytes. Note that this effectively defines two conformance levels to this specification. A full implementation will support UAs / UVKs up to the maximum length. diff --git a/zips/zip-0317.rst b/zips/zip-0317.rst index b57b8a9a1..d60facef5 100644 --- a/zips/zip-0317.rst +++ b/zips/zip-0317.rst @@ -90,10 +90,10 @@ Notation
                  -Let :math:`\mathsf{min}(a, b)` be the lesser of :math:`a` and :math:`b\!`. |br| -Let :math:`\mathsf{max}(a, b)` be the greater of :math:`a` and :math:`b\!`. |br| -Let :math:`\mathsf{floor}(x)` be the largest integer :math:`\leq x\!`. |br| -Let :math:`\mathsf{ceiling}(x)` be the smallest integer :math:`\geq x\!`. +Let $\mathsf{min}(a, b)$ be the lesser of $a$ and $b$. |br| +Let $\mathsf{max}(a, b)$ be the greater of $a$ and $b$. |br| +Let $\mathsf{floor}(x)$ be the largest integer $\leq x$. |br| +Let $\mathsf{ceiling}(x)$ be the smallest integer $\geq x$. Fee calculation --------------- @@ -161,7 +161,7 @@ impact on the network, without discriminating between different protocols (Orchard, Sapling, or transparent). The impact on the network depends on the numbers of inputs and outputs. -A previous proposal used :math:`inputs + outputs` instead of logical actions. +A previous proposal used $inputs + outputs$ instead of logical actions. This would have disadvantaged Orchard transactions, as a result of an Orchard Action combining an input and an output. The effect of this combining is that Orchard requires padding of either inputs or outputs @@ -193,7 +193,7 @@ Grace Actions transaction builder. * Without a grace window, an input with value below the marginal fee would never be worth including in the resulting transaction. - With a grace window, an input with value below :math:`marginal\_fee` + With a grace window, an input with value below $marginal\_fee$ *is* worth including, if a second input is available that covers both the primary output amount and the conventional transaction fee. @@ -205,18 +205,18 @@ transaction that permits both an output to a recipient, and a change output. However, as stated above, `zcashd` and the mobile SDK transaction builder will pad the number of inputs to at least 2. -Let :math:`min\_actions` be the minimum number of logical actions +Let $min\_actions$ be the minimum number of logical actions that can be used to execute economically relevant transactions that -produce change. Due to the aforementioned padding, :math:`min\_actions = 2`. +produce change. Due to the aforementioned padding, $min\_actions = 2$. -Having a grace window size greater than :math:`min\_actions` would +Having a grace window size greater than $min\_actions$ would increase the cost to create such a minimal transaction. If the cost we believe that users will tolerate for a minimal transaction -is :math:`B`, then possible choices of :math:`marginal\_fee` are -bounded above by :math:`B / \max(min\_actions, grace\_actions)`. -Therefore, the optimal choice of :math:`grace\_actions` to maximize +is $B$, then possible choices of $marginal\_fee$ are +bounded above by $B / \max(min\_actions, grace\_actions)$. +Therefore, the optimal choice of $grace\_actions$ to maximize the per-logical-action cost of denial-of-service attacks for a given -:math:`B`, is :math:`grace\_actions = min\_actions = 2`. This also +$B$, is $grace\_actions = min\_actions = 2$. This also ensures that a denial-of-service adversary does not gain a significant per-logical-action cost advantage by using transactions with a smaller or larger number of logical actions. @@ -227,16 +227,16 @@ Transparent Contribution The specified formula calculates the contribution of transparent inputs and outputs based on their total size relative to a typical input or output. Another considered approach was to calculate this contribution -simply as :math:`\mathsf{max}(transparent\_inputs, transparent\_outputs)`. +simply as $\mathsf{max}(transparent\_inputs, transparent\_outputs)$. However, this would allow a denial-of-service adversary to create transactions with transparent components containing arbitrarily large scripts. -The chosen values for :math:`p2pkh\_standard\_input\_size` and -:math:`p2pkh\_standard\_output\_size` are based on the maximum encoded +The chosen values for $p2pkh\_standard\_input\_size$ and +$p2pkh\_standard\_output\_size$ are based on the maximum encoded length for P2PKH inputs and outputs, as follows: -* :math:`p2pkh\_standard\_input\_size` +* $p2pkh\_standard\_input\_size$ * outpoint: 36 bytes * script: 110 bytes @@ -245,7 +245,7 @@ length for P2PKH inputs and outputs, as follows: * sequence: 4 bytes -* :math:`p2pkh\_standard\_output\_size` +* $p2pkh\_standard\_output\_size$ * value: 8 bytes * script: 26 bytes @@ -278,7 +278,7 @@ normally relay transactions are expected to do so for transactions that pay at least the conventional fee as specified in this ZIP, unless there are other reasons not to do so for robustness or denial-of-service mitigation. -If a transaction has more than :math:`block\_unpaid\_action\_limit` "unpaid actions" +If a transaction has more than $block\_unpaid\_action\_limit$ "unpaid actions" as defined by the `Recommended algorithm for block template construction`_, it will never be mined by that algorithm. Nodes MAY drop these transactions, or transactions with more unpaid actions than a configurable limit (see the @@ -288,7 +288,7 @@ Mempool size limiting --------------------- zcashd and zebrad limit the size of the mempool as described in [#zip-0401]_. -This specifies a :math:`low\_fee\_penalty` that is added to the "eviction weight" +This specifies a $low\_fee\_penalty$ that is added to the "eviction weight" if the transaction pays a fee less than the conventional transaction fee. This threshold is modified to use the new conventional fee formula. @@ -302,47 +302,47 @@ following section is planned to be implemented by `zcashd` and `zebrad`. Recommended algorithm for block template construction ''''''''''''''''''''''''''''''''''''''''''''''''''''' -Define constants :math:`weight\_ratio\_cap = 4` and -:math:`block\_unpaid\_action\_limit = 50\!`. +Define constants $weight\_ratio\_cap = 4$ and +$block\_unpaid\_action\_limit = 50$. -Let :math:`conventional\_fee(tx)` be the conventional fee for transaction -:math:`tx` calculated according to the section `Fee calculation`_. +Let $conventional\_fee(tx)$ be the conventional fee for transaction +$tx$ calculated according to the section `Fee calculation`_. -Let :math:`unpaid\_actions(tx) = \begin{cases}\mathsf{max}\!\left(0,\, \mathsf{max}(grace\_actions,\, tx.\!logical\_actions) - \mathsf{floor}\!\left(\frac{tx.fee}{marginal\_fee}\right)\right),&\textsf{if }tx\textsf{ is a non-coinbase transaction} \\ 0,&\textsf{if }tx\textsf{ is a coinbase transaction.}\end{cases}` +Let $unpaid\_actions(tx) = \begin{cases}\mathsf{max}\!\left(0,\, \mathsf{max}(grace\_actions,\, tx.\!logical\_actions) - \mathsf{floor}\!\left(\frac{tx.fee}{marginal\_fee}\right)\right),&\textsf{if }tx\textsf{ is a non-coinbase transaction} \\ 0,&\textsf{if }tx\textsf{ is a coinbase transaction.}\end{cases}$ -Let :math:`block\_unpaid\_actions(block) = \sum_{tx \,\in\, block}\, unpaid\_actions(tx)`. +Let $block\_unpaid\_actions(block) = \sum_{tx \,\in\, block}\, unpaid\_actions(tx)$. The following algorithm is RECOMMENDED for constructing a block template from a set of transactions in a node's mempool: -1. Set the block template :math:`T` to include a placeholder for the +1. Set the block template $T$ to include a placeholder for the coinbase transaction (see Note below). -2. For each transaction :math:`tx` in the mempool, calculate - :math:`tx.\!weight\_ratio = \mathsf{min}\!\left(\frac{\mathsf{max}(1,\, tx.fee)}{conventional\_fee(tx)},\, weight\_ratio\_cap\right)\!` +2. For each transaction $tx$ in the mempool, calculate + $tx.\!weight\_ratio = \mathsf{min}\!\left(\frac{\mathsf{max}(1,\, tx.fee)}{conventional\_fee(tx)},\, weight\_ratio\_cap\right)$ and add the transaction to the set of candidate transactions. 3. Repeat while there is any candidate transaction that pays at least the conventional fee: a. Pick one of those transactions at random with probability in direct - proportion to its :math:`weight\_ratio\!`, and remove it from the set of - candidate transactions. Let :math:`B` be the block template :math:`T` + proportion to its $weight\_ratio$, and remove it from the set of + candidate transactions. Let $B$ be the block template $T$ with this transaction included. - b. If :math:`B` would be within the block size limit and block sigop - limit [#sigop-limit]_, set :math:`T := B\!`. + b. If $B$ would be within the block size limit and block sigop + limit [#sigop-limit]_, set $T := B$. 4. Repeat while there is any candidate transaction: a. Pick one of those transactions at random with probability in direct - proportion to its :math:`weight\_ratio\!`, and remove it from the set of - candidate transactions. Let :math:`B` be the block template :math:`T` + proportion to its $weight\_ratio$, and remove it from the set of + candidate transactions. Let $B$ be the block template $T$ with this transaction included. - b. If :math:`B` would be within the block size limit and block sigop - limit [#sigop-limit]_ and :math:`block\_unpaid\_actions(B) \leq block\_unpaid\_action\_limit\!`, - set :math:`T := B\!`. + b. If $B$ would be within the block size limit and block sigop + limit [#sigop-limit]_ and $block\_unpaid\_actions(B) \leq block\_unpaid\_action\_limit$, + set $T := B$. -5. Return :math:`T\!`. +5. Return $T$. Note: In step 1, the final coinbase transaction cannot be included at this stage because it depends on the fees paid by other transactions. In practice, @@ -360,40 +360,40 @@ this block template algorithm more quickly while still giving transactions created by such wallets a reasonable chance of being mined, we allow a limited number of "unpaid" logical actions in each block. Roughly speaking, if a transaction falls short of paying the conventional transaction fee by -:math:`k` times the marginal fee, we count that as :math:`k` unpaid logical +$k$ times the marginal fee, we count that as $k$ unpaid logical actions. Regardless of how full the mempool is (according to the ZIP 401 [#zip-0401]_ cost limiting), and regardless of what strategy a denial-of-service adversary may use, the number of unpaid logical actions in each block is always limited -to at most :math:`block\_unpaid\_action\_limit\!`. +to at most $block\_unpaid\_action\_limit$. The weighting in step 2 does not create a situation where the adversary gains a significant advantage over other users by paying more than the conventional fee, for two reasons: 1. The weight ratio cap limits the relative probability of picking a given - transaction to be at most :math:`weight\_ratio\_cap` times greater than a + transaction to be at most $weight\_ratio\_cap$ times greater than a transaction that pays exactly the conventional fee. -2. Compare the case where the adversary pays :math:`c` times the conventional +2. Compare the case where the adversary pays $c$ times the conventional fee for one transaction, to that where they pay the conventional fee for - :math:`c` transactions. In the former case they are more likely to get *each* + $c$ transactions. In the former case they are more likely to get *each* transaction into the block relative to competing transactions from other users, *but* those transactions take up less block space, all else (e.g. choice of input or output types) being equal. This is not what the attacker wants; they get a transaction into the block only at the expense of leaving more block space for the other users' transactions. -The rationale for choosing :math:`weight\_ratio\_cap = 4` is as a compromise +The rationale for choosing $weight\_ratio\_cap = 4$ is as a compromise between not allowing any prioritization of transactions relative to those that pay the conventional fee, and allowing arbitrary prioritization based on ability to pay. -Calculating :math:`tx.\!weight\_ratio` in terms of :math:`\mathsf{max}(1,\, tx.\!fee)` -rather than just :math:`tx.\!fee` avoids needing to define "with probability in direct -proportion to its :math:`weight\_ratio\!`" for the case where all remaining candidate -transactions would have :math:`weight\_ratio = 0\!`. +Calculating $tx.\!weight\_ratio$ in terms of $\mathsf{max}(1,\, tx.\!fee)$ +rather than just $tx.\!fee$ avoids needing to define "with probability in direct +proportion to its $weight\_ratio$" for the case where all remaining candidate +transactions would have $weight\_ratio = 0$. Incentive compatibility for miners '''''''''''''''''''''''''''''''''' @@ -440,7 +440,7 @@ Deployment ========== Wallets SHOULD deploy these changes immediately. Nodes SHOULD deploy the -change to the :math:`low\_fee\_penalty` threshold described in +change to the $low\_fee\_penalty$ threshold described in `Mempool size limiting`_ immediately. Nodes supporting block template construction SHOULD deploy the new @@ -474,7 +474,7 @@ in: * https://github.com/zcash/zcash/pull/6527 (fee computation) * https://github.com/zcash/zcash/pull/6564 (block template construction) -The value used for :math:`block\_unpaid\_action\_limit` by `zcashd` +The value used for $block\_unpaid\_action\_limit$ by `zcashd` can be overridden using the ``-blockunpaidactionlimit`` configuration parameter. @@ -511,7 +511,7 @@ block template construction`_ in: * https://github.com/ZcashFoundation/zebra/pull/5776 (algorithm update) `zebra` v1.0.0-rc.2 had implemented an earlier version of this algorithm. -The value used for :math:`block\_unpaid\_action\_limit` in `zebra` is not +The value used for $block\_unpaid\_action\_limit$ in `zebra` is not configurable. `zebra` v1.0.0-rc.2 implemented the change to `Mempool size limiting`_ in: @@ -539,16 +539,16 @@ below are roughly half of what they would be under the current formula. Possible alternatives for the parameters: -* :math:`marginal\_fee = 250` in @nuttycom's proposal. -* :math:`marginal\_fee = 1000` adapted from @madars' proposal [#madars-1]_. -* :math:`marginal\_fee = 2500` in @daira's proposal. -* :math:`marginal\_fee = 1000` for Shielded, Shielding and De-shielding - transactions, and :math:`marginal\_fee = 10000` for Transparent transactions +* $marginal\_fee = 250$ in @nuttycom's proposal. +* $marginal\_fee = 1000$ adapted from @madars' proposal [#madars-1]_. +* $marginal\_fee = 2500$ in @daira's proposal. +* $marginal\_fee = 1000$ for Shielded, Shielding and De-shielding + transactions, and $marginal\_fee = 10000$ for Transparent transactions adapted from @nighthawk24's proposal. (In @madars' and @nighthawk24's original proposals, there was an additional -:math:`base\_fee` parameter that caused the relationship between fee and number -of inputs/outputs to be non-proportional above the :math:`grace\_actions` +$base\_fee$ parameter that caused the relationship between fee and number +of inputs/outputs to be non-proportional above the $grace\_actions$ threshold. This is no longer expressible with the formula specified above.) diff --git a/zips/zip-0320.rst b/zips/zip-0320.rst index 19d4e4968..141f24cbf 100644 --- a/zips/zip-0320.rst +++ b/zips/zip-0320.rst @@ -128,14 +128,14 @@ following steps: 1. Decode the address to a byte sequence using the Base58Check decoding algorithm [#Base58Check]_. 2. If the length of the resulting byte sequence is not 22 bytes or if its two-byte - address prefix is not :math:`[\mathtt{0x1C}, \mathtt{0xB8}]`, return an error. + address prefix is not $[\mathtt{0x1C}, \mathtt{0xB8}]$, return an error. Otherwise, let the **validating key hash** be the remaining 20 bytes of the sequence after removing the two-byte address prefix. 3. Reencode the 20-byte **validating key hash** using the Bech32m encoding defined in [#bip-0350]_ with the human-readable prefix (HRP) ``"tex"``. For Testnet addresses, the required lead bytes of a P2PKH address in step 2 are -:math:`[\mathtt{0x1D}, \mathtt{0x25}]`, and the ``"textest"`` HRP is used when +$[\mathtt{0x1D}, \mathtt{0x25}]$, and the ``"textest"`` HRP is used when reencoding in step 3. A TEX address can be parsed by reversing this encoding, i.e.: diff --git a/zips/zip-0324.rst b/zips/zip-0324.rst index 93f861e56..babc95416 100644 --- a/zips/zip-0324.rst +++ b/zips/zip-0324.rst @@ -386,7 +386,7 @@ In the above description, we explicitly list the notes involved in the payment ( Instead, we can have the nodes be implicitly identified by the spending key (or similar) included in the URI. This can make URI shorter, thus less scary and less likely to run into length limits (consider SMS). The following alternatives are feasible: -:math:`\hspace{0.9em}`\0. Explicitly list the note commitments within the URI. +$\hspace{0.9em}$\0. Explicitly list the note commitments within the URI. 1. Include only the spending key(s) in the URI, and have the recipient scan the blockchain using the existing mechanism (trial decryption of the encrypted memo field). This is very slow, and risks denial-of-service attacks. Would be faster in the nominal case if the scanning is done backwards (newest block first), or if told by the sender when the transactions were mined; but scanning the whole chain for nonexistent transactions (perhaps induced by a DoS) would still take very long. diff --git a/zips/zip-0401.rst b/zips/zip-0401.rst index e319996a8..c47f18f8e 100644 --- a/zips/zip-0401.rst +++ b/zips/zip-0401.rst @@ -165,7 +165,7 @@ as mempool limiting is concerned) to increasing the fee above the conventional fee value, it creates no pressure toward escalating fees. For transactions with a memory size up to 10000 bytes, this penalty makes a transaction that pays less than the conventional fee five times as likely to be chosen for -eviction (because :math:`10000 + 40000 = 50000 = 10000 \times 5`). +eviction (because $10000 + 40000 = 50000 = 10000 \times 5$). The fee penalty is not included in the cost that determines whether the mempool is considered full. This ensures that a DoS attacker does not have an incentive diff --git a/zips/zip-1015.rst b/zips/zip-1015.rst index 059441908..b94dc5830 100644 --- a/zips/zip-1015.rst +++ b/zips/zip-1015.rst @@ -1,7 +1,7 @@ :: ZIP: 1015 - Title: Block Reward Allocation for Non-Direct Development Funding + Title: Block Subsidy Allocation for Non-Direct Development Funding Owners: Jason McGee @Peacemonger (Zcash Forum) Kris Nuttycombe @@ -68,7 +68,7 @@ Starting at Zcash's second halving in November 2024, under pre-existing consensus rules 100% of the block subsidies would be allocated to miners, and no further funds would be automatically allocated to any other entities. Consequently, unless the community takes action to approve new -block-reward-based funding, existing teams dedicated to development or outreach +block-subsidy-based funding, existing teams dedicated to development or outreach or furthering charitable, educational, or scientific purposes would likely need to seek other sources of funding; failure to obtain such funding would likely impair their ability to continue serving the Zcash ecosystem. Setting aside a diff --git a/zips/zip-2001.rst b/zips/zip-2001.rst index 5c588261e..487eac25c 100644 --- a/zips/zip-2001.rst +++ b/zips/zip-2001.rst @@ -56,7 +56,7 @@ Requirements ============ The Zcash protocol will maintain a new Deferred chain pool value balance -:math:`\mathsf{ChainValuePoolBalance^{Deferred}}` for the deferred funding pool, +$\mathsf{ChainValuePoolBalance^{Deferred}}$ for the deferred funding pool, in much the same fashion as it maintains chain pool value balances for the transparent, Sprout, Sapling, and Orchard pools. @@ -67,8 +67,8 @@ that a funding stream may deposit funds into the deferred pool. Specification ============= -Modifications to ZIP 207 [#zip-0207]_ -------------------------------------- +Changes to ZIP 207 [#zip-0207]_ +------------------------------- The following paragraph is added to the section **Motivation**: @@ -84,33 +84,33 @@ In the section **Funding streams** [#zip-0207-funding-streams]_, instead of: it will be modified to read: - Each element of :math:`\mathsf{fs.Recipients}` MUST represent either a transparent + Each element of $\mathsf{fs.Recipients}$ MUST represent either a transparent P2SH address as specified in [#protocol-transparentaddrencoding]_, or a Sapling shielded payment address as specified in [#protocol-saplingpaymentaddrencoding]_, - or the identifier :math:`\mathsf{DEFERRED}\_\mathsf{POOL}\!`. + or the identifier $\mathsf{DEFERRED\_POOL}$. After the section **Funding streams**, a new section is added with the heading "Deferred Development Fund Chain Value Pool Balance" and the following contents: Full node implementations MUST track an additional - :math:`\mathsf{ChainValuePoolBalance^{Deferred}}` chain value pool balance, + $\mathsf{ChainValuePoolBalance^{Deferred}}$ chain value pool balance, in addition to the Sprout, Sapling, and Orchard chain value pool balances. - Define :math:`\mathsf{totalDeferredOutput}(\mathsf{height}) := \sum_{\mathsf{fs} \in \mathsf{DeferredFundingStreams}(\mathsf{height})} \mathsf{fs.Value}(\mathsf{height})` - where :math:`\mathsf{DeferredFundingStreams}(\mathsf{height})` is the set of - funding streams with recipient identifier :math:`\mathsf{DEFERRED}\_\mathsf{POOL}` - in the block at height :math:`\mathsf{height}\!`. + Define $\mathsf{totalDeferredOutput}(\mathsf{height}) := \sum_{\mathsf{fs} \in \mathsf{DeferredFundingStreams}(\mathsf{height})} \mathsf{fs.Value}(\mathsf{height})$ + where $\mathsf{DeferredFundingStreams}(\mathsf{height})$ is the set of + funding streams with recipient identifier $\mathsf{DEFERRED\_POOL}$ + in the block at height $\mathsf{height}$. - The :math:`\mathsf{ChainValuePoolBalance^{Deferred}}` chain value pool balance + The $\mathsf{ChainValuePoolBalance^{Deferred}}$ chain value pool balance for a given block chain is the sum of the values of payments to - :math:`\mathsf{DEFERRED}\_\mathsf{POOL}` for transactions in the block chain. + $\mathsf{DEFERRED\_POOL}$ for transactions in the block chain. - Equivalently, :math:`\mathsf{ChainValuePoolBalance^{Deferred}}` for a block - chain up to and including height :math:`\mathsf{height}` is given by - :math:`\sum_{\mathsf{h} = 0}^{\mathsf{height}} \mathsf{totalDeferredOutput}(\mathsf{h})\!`. + Equivalently, $\mathsf{ChainValuePoolBalance^{Deferred}}$ for a block + chain up to and including height $\mathsf{height}$ is given by + $\sum_{\mathsf{h} = 0}^{\mathsf{height}} \mathsf{totalDeferredOutput}(\mathsf{h})$. - Note: :math:`\mathsf{totalDeferredOutput}(\mathsf{h})` is necessarily - zero for heights :math:`\mathsf{h}` prior to NU6 activation. + Note: $\mathsf{totalDeferredOutput}(\mathsf{h})$ is necessarily + zero for heights $\mathsf{h}$ prior to NU6 activation. In the section **Consensus rules** [#zip-0207-consensus-rules]_, instead of: @@ -120,26 +120,26 @@ In the section **Consensus rules** [#zip-0207-consensus-rules]_, instead of: it will be modified to read: - - In each block with coinbase transaction :math:`\mathsf{cb}` at block height - :math:`\mathsf{height}`, for each funding stream :math:`\mathsf{fs}` + - In each block with coinbase transaction $\mathsf{cb}$ at block height + $\mathsf{height}$, for each funding stream $\mathsf{fs}$ active at that block height with a recipient identifier other than - :math:`\mathsf{DEFERRED}\_\mathsf{POOL}` given by - :math:`\mathsf{fs.Recipient}(\mathsf{height})\!`, - :math:`\mathsf{cb}` MUST contain at least one output that pays - :math:`\mathsf{fs.Value}(\mathsf{height})` zatoshi in the prescribed way + $\mathsf{DEFERRED\_POOL}$ given by + $\mathsf{fs.Recipient}(\mathsf{height})$, + $\mathsf{cb}$ MUST contain at least one output that pays + $\mathsf{fs.Value}(\mathsf{height})$ zatoshi in the prescribed way to the address represented by that recipient identifier. - - :math:`\mathsf{fs.Recipient}(\mathsf{height})` is defined as - :math:`\mathsf{fs.Recipients_{\,fs.RecipientIndex}}(\mathsf{height})\!`. + - $\mathsf{fs.Recipient}(\mathsf{height})$ is defined as + $\mathsf{fs.Recipients_{\,fs.RecipientIndex}}(\mathsf{height})$. After the list of post-Canopy consensus rules, the following paragraphs are added: - These rules are reproduced in [#protocol-fundingstreams]. + These rules are reproduced in [#protocol-fundingstreams]_. - The effect of the definition of :math:`\mathsf{ChainValuePoolBalance^{Deferred}}` - above is that payments to the :math:`\mathsf{DEFERRED}\_\mathsf{POOL}` cause - :math:`\mathsf{FundingStream[FUND].Value}(\mathsf{height})` to be added to - :math:`\mathsf{ChainValuePoolBalance^{Deferred}}` for the block chain including + The effect of the definition of $\mathsf{ChainValuePoolBalance^{Deferred}}$ + above is that payments to the $\mathsf{DEFERRED\_POOL}$ cause + $\mathsf{FundingStream[FUND].Value}(\mathsf{height})$ to be added to + $\mathsf{ChainValuePoolBalance^{Deferred}}$ for the block chain including that block. In the section **Deployment** [#zip-0207-deployment]_, the following sentence is @@ -147,29 +147,27 @@ added: Changes to support deferred funding streams are to be deployed with NU6. [#zip-0253]_ - - -Modifications to the protocol specification +Changes to the Zcash Protocol Specification ------------------------------------------- In section **4.17 Chain Value Pool Balances** [#protocol-chainvaluepoolbalances]_ (which is new in version 2024.5.1 of the protocol specification), include the following: - Define :math:`\mathsf{totalDeferredOutput}` as in [#protocol-subsidies]_. + Define $\mathsf{totalDeferredOutput}$ as in [#protocol-subsidies]_. Then, consistent with [#zip-0207]_, the deferred development fund chain value pool - balance for a block chain up to and including height :math:`\mathsf{height}` is given by - :math:`\mathsf{ChainValuePoolBalance^{Deferred}}(\mathsf{height}) := \sum_{\mathsf{h} = 0}^{\mathsf{height}} \mathsf{totalDeferredOutput}(\mathsf{h})\!`. + balance for a block chain up to and including height $\mathsf{height}$ is given by + $\mathsf{ChainValuePoolBalance^{Deferred}}(\mathsf{height}) := \sum_{\mathsf{h} = 0}^{\mathsf{height}} \mathsf{totalDeferredOutput}(\mathsf{h})$. Non-normative notes: - * :math:`\mathsf{totalDeferredOutput}(\mathsf{h})` is necessarily zero for heights - :math:`\mathsf{h}` prior to NU6 activation. + * $\mathsf{totalDeferredOutput}(\mathsf{h})$ is necessarily zero for heights + $\mathsf{h}$ prior to NU6 activation. * Currently there is no way to withdraw from the deferred development fund chain value pool, so there is no possibility of it going negative. Therefore, no consensus rule to prevent that eventuality is needed at this time. - The *total issued supply* of a block chain at block height :math:`\mathsf{height}` + The *total issued supply* of a block chain at block height $\mathsf{height}$ is given by the function: .. math:: @@ -185,24 +183,24 @@ In section **4.17 Chain Value Pool Balances** [#protocol-chainvaluepoolbalances] In section **7.1.2 Transaction Consensus Rules** [#protocol-txnconsensus]_, instead of: The total value in zatoshi of transparent outputs from a coinbase transaction, - minus :math:`\mathsf{v^{balanceSapling}}\!`, minus :math:`\mathsf{v^{balanceOrchard}}\!`, + minus $\mathsf{v^{balanceSapling}}$, minus $\mathsf{v^{balanceOrchard}}$, MUST NOT be greater than the value in zatoshi of the block subsidy plus the transaction fees paid by transactions in this block. it will be modified to read: - For the block at block height :math:`\mathsf{height}`: + For the block at block height $\mathsf{height}$: - define the "total output value" of its coinbase transaction to be the total value - in zatoshi of its transparent outputs, minus :math:`\mathsf{v^{balanceSapling}}\!`, - minus :math:`\mathsf{v^{balanceOrchard}}\!`, plus :math:`\mathsf{totalDeferredOutput}(\mathsf{height})\!`; + in zatoshi of its transparent outputs, minus $\mathsf{v^{balanceSapling}}$, + minus $\mathsf{v^{balanceOrchard}}$, plus $\mathsf{totalDeferredOutput}(\mathsf{height})$; - define the "total input value" of its coinbase transaction to be the value in zatoshi of the block subsidy, plus the transaction fees paid by transactions in the block. The total output value of a coinbase transaction MUST NOT be greater than its total input value. -where :math:`\mathsf{totalDeferredOutput}(\mathsf{height})` is defined consistently +where $\mathsf{totalDeferredOutput}(\mathsf{height})$ is defined consistently with ZIP 207. Note: this ZIP and ZIP 236 both make changes to the above rule. Their combined effect diff --git a/zips/zip-2002.rst b/zips/zip-2002.rst index f05c4ee31..3ef1b33b0 100644 --- a/zips/zip-2002.rst +++ b/zips/zip-2002.rst @@ -16,17 +16,17 @@ Terminology =========== -The key word "MUST" in this document is to be interpreted as described in BCP 14 [#BCP14]_ -when, and only when, it appears in all capitals. +The key word "MUST" in this document is to be interpreted as described in BCP 14 +[#BCP14]_ when, and only when, it appears in all capitals. The term "network upgrade" in this document is to be interpreted as described in ZIP 200. [#zip-0200]_ -The terms "Testnet" and "Mainnet" are to be interpreted as described in section -3.12 of the Zcash Protocol Specification. [#protocol-networks]_ +The character § is used when referring to sections of the Zcash Protocol +Specification. [#protocol]_ -The character § is used when referring to sections of the Zcash Protocol Specification -[#protocol]_. +The terms "Mainnet" and "Testnet" are to be interpreted as described in +§ 3.12 ‘Mainnet and Testnet’. [#protocol-networks]_ Abstract @@ -59,18 +59,20 @@ inputs to the transaction. Requirements ============ -There must not be any potentially error-prone calculations needed to compute the -fee for a given transaction. That is, the fee must be obvious from the encoding -of the transaction. +Parties that see a transaction, even in isolation, reliably know its fee. +That is, the fee must be explicit in the encoding of the transaction, +and no potentially error-prone calculations or additional chain data are +needed to compute it. Specification ============= -Transaction Format ------------------- +Changes to ZIP 230 [#zip-0230]_ +------------------------------- -The following field is added to the v6 transaction format [#zip-0230-transaction-format]_. +The following field is appended to the Common Transaction Fields of the v6 +transaction format after ``nExpiryHeight`` [#zip-0230-transaction-format]_: +-------+---------+------------+------------------------------------------------------+ | Bytes | Name | Data Type | Description | @@ -78,10 +80,12 @@ The following field is added to the v6 transaction format [#zip-0230-transaction | 8 | ``fee`` | ``uint64`` | The fee to be paid by this transaction, in zatoshis. | +-------+---------+------------+------------------------------------------------------+ -Consensus Rules ---------------- +Note: If both this ZIP and ZIP 233 are selected for inclusion in the same +Network Upgrade, then the ambiguity in ordering of the fields added by these +ZIPs would need to be resolved. -The following changes are to be made to the Zcash Protocol Specification [#protocol]_. +Changes to the Zcash Protocol Specification +------------------------------------------- In § 3.4 ‘Transactions and Treestates’ [#protocol-transactions]_ (last modified by ZIP 236 [#zip-0236]_), add the following consensus rule and note: @@ -95,29 +99,23 @@ ZIP 236 [#zip-0236]_), add the following consensus rule and note: In § 7.1 ‘Transaction Encoding and Consensus’ [#protocol-txnconsensus]_, add: - [NU7 onward] ``fee`` MUST be in the range :math:`\{ 0 .. \mathsf{MAX\_MONEY} \}`. + [NU7 onward] ``fee`` MUST be in the range $\{ 0 .. \mathsf{MAX\_MONEY} \}$. -Signature Hash --------------- -The transaction signature hashing algorithm defined in ZIP 244 is to be modified -for v6 transactions as follows: +Modifications relative to ZIP 244 [#zip-0244]_ +---------------------------------------------- -Section T.1: `header_digest` [#zip-0244-header-digest]_ is specified in -`draft-txv6-sighash` [#draft-txv6-sighash]_ to read: +Relative to the sighash algorithm defined in ZIP 244, the sighash algorithm +that applies to v6 transactions differs by appending the ``fee`` field to +the Common Transaction Fields that are the input to the digest in +T.1: header_digest [#zip-0244-header-digest]_:: + + T.1f: fee (8-byte little-endian fee amount) + +Note: If both this ZIP and ZIP 233 are selected for inclusion in the same +Network Upgrade, then the ambiguity in ordering of the fields added by these +ZIPs would need to be resolved. - A BLAKE2b-256 hash of the following values :: - - T.1a: version (4-byte little-endian version identifier including ``fOverwintered`` flag) - T.1b: version_group_id (4-byte little-endian version group identifier) - T.1c: consensus_branch_id (4-byte little-endian consensus branch id) - T.1d: lock_time (4-byte little-endian ``nLockTime`` value) - T.1e: expiry_height (4-byte little-endian block height) - T.1f: fee (8-byte little-endian fee value) - - The personalization field of this hash is set to:: - - "ZTxIdHeadersHash" Applicability ------------- @@ -129,7 +127,7 @@ Deployment ========== This ZIP is proposed to be deployed with the next transaction version change, -which is assumed to be v6. +which is assumed to be v6. [#zip-0230]_ Reference implementation @@ -148,7 +146,9 @@ References .. [#protocol-txnconsensus] `Zcash Protocol Specification, Version 2024.5.1 [NU6]. Section 7.1.2: Transaction Consensus Rules `_ .. [#bitcointalk-fee-error] `Bitcoin Forum post by @Voiceeeeee, March 8, 2017. "PLEASE HELP.. I sent a transaction with a 2.5 BTC transaction fee" `_ .. [#zip-0200] `ZIP 200: Network Upgrade Mechanism `_ -.. [#zip-0230-transaction-format] `ZIP 230: Version 6 Transaction Format `_ +.. [#zip-0230] `ZIP 230: Version 6 Transaction Format `_ +.. [#zip-0230-transaction-format] `ZIP 230: Version 6 Transaction Format. Specification: Transaction Format `_ .. [#zip-0236] `ZIP 236: Blocks should balance exactly `_ +.. [#zip-0244] `ZIP 244: Transaction Identifier Non-Malleability `_ .. [#zip-0244-header-digest] `ZIP 244: Transaction Identifier Non-Malleability. Section T.1: Header Digest `_ .. [#draft-txv6-sighash] `ZIP draft: Version 6 Transaction Signature Validation `_ diff --git a/zips/zip-2003.rst b/zips/zip-2003.rst index f5a3a404c..9101ea32b 100644 --- a/zips/zip-2003.rst +++ b/zips/zip-2003.rst @@ -13,17 +13,17 @@ Terminology =========== -The key word "MUST" in this document is to be interpreted as described in BCP 14 [#BCP14]_ -when, and only when, it appears in all capitals. +The key word "MUST" in this document is to be interpreted as described in BCP 14 +[#BCP14]_ when, and only when, it appears in all capitals. The term "network upgrade" in this document is to be interpreted as described in ZIP 200. [#zip-0200]_ -The terms "Testnet" and "Mainnet" are to be interpreted as described in section -3.12 of the Zcash Protocol Specification. [#protocol-networks]_ +The character § is used when referring to sections of the Zcash Protocol +Specification. [#protocol]_ -The character § is used when referring to sections of the Zcash Protocol Specification -[#protocol]_. +The terms "Mainnet" and "Testnet" are to be interpreted as described in +§ 3.12 ‘Mainnet and Testnet’. [#protocol-networks]_ Abstract @@ -103,10 +103,9 @@ Interaction with the proposed Network Sustainability Mechanism -------------------------------------------------------------- For clarity, the Sprout chain value pool balance as of activation of this ZIP -remains issued. If the Network Sustainability Mechanism ZIPs that affect -issuance ([#draft-zip-0233]_ and [#draft-zip-0234]_) are activated, then the -Sprout chain value pool balance is, therefore, not considered part of the -“Money Reserve” as a consequence of activating this ZIP. +remains issued. If the Network Sustainability Mechanism ZIPs that affect issuance +([#zip-0233]_ and [#zip-0234]_) are also activated, then this ZIP would not cause +the Sprout chain value pool to be considered part of the “Money Reserve”. Deployment @@ -141,6 +140,6 @@ References .. [#zip-0200] `ZIP 200: Network Upgrade Mechanism `_ .. [#zip-0209] `ZIP 209: Prohibit Negative Shielded Chain Value Pool Balances `_ .. [#zip-0225] `ZIP 225: Version 5 Transaction Format `_ -.. [#draft-zip-0233] `Draft ZIP 233: Network Sustainability Mechanism: Burning `_ -.. [#draft-zip-0234] `Draft ZIP 234: Network Sustainability Mechanism: Issuance Smoothing `_ +.. [#zip-0233] `ZIP 233: Network Sustainability Mechanism: Burning `_ +.. [#zip-0234] `ZIP 234: Network Sustainability Mechanism: Issuance Smoothing `_ .. [#cultivating-sapling] `Cultivating Sapling: Faster zk-SNARKs. Sean Bowe, September 13, 2017. `_ diff --git a/zips/zip-2004.rst b/zips/zip-2004.rst index 08286b589..7f09e1482 100644 --- a/zips/zip-2004.rst +++ b/zips/zip-2004.rst @@ -20,11 +20,11 @@ The key word "MUST" in this document is to be interpreted as described in BCP 14 The term "network upgrade" in this document is to be interpreted as described in ZIP 200. [#zip-0200]_ -The terms "Testnet" and "Mainnet" are to be interpreted as described in section -3.12 of the Zcash Protocol Specification. [#protocol-networks]_ +The character § is used when referring to sections of the Zcash Protocol +Specification. [#protocol]_ -The character § is used when referring to sections of the Zcash Protocol Specification -[#protocol]_. +The terms "Mainnet" and "Testnet" are to be interpreted as described in +§ 3.12 ‘Mainnet and Testnet’. [#protocol-networks]_ Abstract @@ -77,44 +77,44 @@ independent of note encryption. Specification ============= -Changes to the protocol specification -------------------------------------- +Changes to the Zcash Protocol Specification +------------------------------------------- -In § 5.4.3 'Symmetric Encryption', rename :math:`Sym` to :math:`NoteSym` and +In § 5.4.3 'Symmetric Encryption', rename $Sym$ to $NoteSym$ and add the following text: - Let :math:`\mathsf{NullSym.}\mathbf{K} := \mathbb{B}^{[256]}`, - :math:`\mathsf{NullSym.}\mathbf{P} := \mathbb{B^Y}^{\mathbb{N}}`, and - :math:`\mathsf{NullSym.}\mathbf{C} := \mathbb{B^Y}^{\mathbb{N}}`. + Let $\mathsf{NullSym.}\mathbf{K} := \mathbb{B}^{[256]}$, + $\mathsf{NullSym.}\mathbf{P} := \mathbb{B^Y}^{\mathbb{N}}$, and + $\mathsf{NullSym.}\mathbf{C} := \mathbb{B^Y}^{\mathbb{N}}$. - Let :math:`\mathsf{NullSym.Encrypt_K}(\mathsf{P}) := \mathsf{P} || [0x00]^{16}`. + Let $\mathsf{NullSym.Encrypt_K}(\mathsf{P}) := \mathsf{P} \,||\, [0x00]^{16}$. - Define :math:`\mathsf{NullSym.Decrypt_K}(\mathsf{C})` as follows: + Define $\mathsf{NullSym.Decrypt_K}(\mathsf{C})$ as follows: - * If the last 16 bytes of :math:`\mathsf{C}` are not :math:`[0x00]^{16}`, - return :math:`\bot`. Otherwise discard those 16 bytes and return the - remaining prefix of :math:`\mathsf{C}`. + * If the last 16 bytes of $\mathsf{C}$ are not $[0x00]^{16}$, + return $\bot$. Otherwise discard those 16 bytes and return the + remaining prefix of $\mathsf{C}$. - Note: These definitions intentionally ignore the key; :math:`\mathsf{NullSym}` + Note: These definitions intentionally ignore the key; $\mathsf{NullSym}$ is not a secure authenticated encryption scheme. It MUST be used only for notes in shielded coinbase outputs, which are intended to be visible as cleartext. In § 4.20 'In-band secret distribution (Sapling and Orchard)', change: - let :math:`\mathsf{Sym}` be the encryption scheme instantiated in + let $\mathsf{Sym}$ be the encryption scheme instantiated in § 5.4.3 'Symmetric Encryption'. to - let :math:`\mathsf{NoteSym}` and :math:`\mathsf{NullSym}` be as + let $\mathsf{NoteSym}$ and $\mathsf{NullSym}$ be as instantiated in § 5.4.3 'Symmetric Encryption'. - [Pre-NU7] let :math:`\mathsf{Sym}` be :math:`\mathsf{NoteSym}`. + [Pre-NU7] let $\mathsf{Sym}$ be $\mathsf{NoteSym}$. [NU7 onward] if the note to be decrypted is in an output of a version 6 - or later coinbase transaction, let :math:`\mathsf{Sym}` be - :math:`\mathsf{NullSym}`, otherwise let it be :math:`\mathsf{NoteSym}`. + or later coinbase transaction, let $\mathsf{Sym}$ be + $\mathsf{NullSym}$, otherwise let it be $\mathsf{NoteSym}$. These changes apply identically to Mainnet and Testnet. @@ -125,7 +125,7 @@ Deployment ========== This ZIP is proposed to be deployed with the next transaction version change, -which is assumed to be v6. +which is assumed to be v6. [#zip-0230]_ Reference implementation @@ -150,3 +150,4 @@ References .. [#zip-0200] `ZIP 200: Network Upgrade Mechanism `_ .. [#zip-0212] `ZIP 212: Allow Recipient to Derive Ephemeral Secret from Note Plaintext `_ .. [#zip-0213] `ZIP 213: Shielded Coinbase `_ +.. [#zip-0230] `ZIP 230: Version 6 Transaction Format `_ diff --git a/zips/zip-guide-markdown.md b/zips/zip-guide-markdown.md index 4cc0091cb..e3e5294ef 100644 --- a/zips/zip-guide-markdown.md +++ b/zips/zip-guide-markdown.md @@ -142,10 +142,13 @@ ZIPs are different from RFCs in the following ways: ## Using mathematical notation -Embedded LaTeX $x + y$ is allowed and encouraged in ZIPs. The syntax for inline -math is "`:math:`latex code``" in reStructuredText or "`$latex code$`" in -Markdown. The rendered HTML will use KaTeX [^katex], which only supports a subset -of LaTeX, so you will need to double-check that the rendering is as intended. +Embedded $\LaTeX$, e.g. $x + y$, is allowed and encouraged in ZIPs. The syntax for +inline math is "\$latex code\$" in either Markdown or (as a +non-standard extension) reStructuredText. This syntax does not work in tables for +reStructuredText; in that case use ":math:\`latex code\`" instead. + +The rendered HTML will use KaTeX [^katex], which only supports a subset of $\LaTeX$, +so you will need to double-check that the rendering is as intended. In general the conventions in the Zcash protocol specification SHOULD be followed. If you find this difficult, don't worry too much about it in initial drafts; the @@ -174,11 +177,17 @@ or "SHOULD" conformance requirement is more appropriate. ## Valid markup This is optional before publishing a PR, but to check whether a document is valid -reStructuredText or Markdown, first install `rst2html5` and `pandoc`. E.g. on -Debian-based distros:: - - sudo apt install python3-pip pandoc perl sed - pip3 install docutils==0.19 rst2html5 +reStructuredText or Markdown, first install `docutils` and `rst2html5`, and +build ``MultiMarkdown-6``. E.g. on Debian-based distros:: + + sudo apt install python3-pip perl sed cmake + pip3 install 'docutils==0.21.2' 'rst2html5==2.0.1' + git clone -b develop https://github.com/Electric-Coin-Company/MultiMarkdown-6 + cd MultiMarkdown-6 + make release + cd build + make + sudo make install Then, with `draft-myzip.rst` or `draft-myzip.md` in the root directory of a clone of this repo, run:: diff --git a/zips/zip-guide.rst b/zips/zip-guide.rst index 048594048..cba38add9 100644 --- a/zips/zip-guide.rst +++ b/zips/zip-guide.rst @@ -151,11 +151,13 @@ ZIPs are different from RFCs in the following ways: Using mathematical notation --------------------------- -Embedded :math:`\LaTeX` is allowed and encouraged in ZIPs. The syntax for inline -math is "``:math:`latex code```" in reStructuredText or "``$latex code$``" in -Markdown. The rendered HTML will use KaTeX [#katex]_, which only supports a subset -of :math:`\LaTeX\!`, so you will need to double-check that the rendering is as -intended. +Embedded $\LaTeX$, e.g. $x + y$, is allowed and encouraged in ZIPs. The syntax for +inline math is "``\$latex code\$``" in either Markdown or (as a non-standard +extension) reStructuredText. This syntax does not work in tables for +reStructuredText; in that case use "``:math:`latex code```" instead. + +The rendered HTML will use KaTeX [#katex]_, which only supports a subset of +$\LaTeX$, so you will need to double-check that the rendering is as intended. In general the conventions in the Zcash protocol specification SHOULD be followed. If you find this difficult, don't worry too much about it in initial drafts; the @@ -184,11 +186,17 @@ Valid markup ------------ This is optional before publishing a PR, but to check whether a document is valid -reStructuredText or Markdown, first install ``rst2html5`` and ``pandoc``. E.g. on -Debian-based distros:: - - sudo apt install python3-pip pandoc perl sed - pip3 install docutils==0.19 rst2html5 +reStructuredText or Markdown, first install ``docutils`` and ``rst2html5``, and +build ``MultiMarkdown-6``. E.g. on Debian-based distros:: + + sudo apt install python3-pip perl sed cmake + pip3 install 'docutils==0.21.2' 'rst2html5==2.0.1' + git clone -b develop https://github.com/Electric-Coin-Company/MultiMarkdown-6 + cd MultiMarkdown-6 + make release + cd build + make + sudo make install Then, with ``draft-myzip.rst`` or ``draft-myzip.md`` in the root directory of a clone of this repo, run::