diff --git a/.github/actions/render/action.yml b/.github/actions/render/action.yml index 2f58d4860..4cb2983ef 100644 --- a/.github/actions/render/action.yml +++ b/.github/actions/render/action.yml @@ -1,7 +1,29 @@ -name: Render ZIPs and Zcash Protocol Specification -description: GitHub Action to compile ZIPs and Zcash Protocol Specification LaTeX documents -author: Deirdre Connolly +name: Render All +description: GitHub Action to compile ZIPs and the protocol specification. +author: Deirdre Connolly and Daira-Emma Hopwood runs: - using: docker - # Runs `make all` or something like it - image: ../../../Dockerfile + using: composite + steps: + - uses: DeterminateSystems/nix-installer-action@c5a866b6ab867e88becbed4467b93592bce69f8a # v21 + + - name: Restore Nix store cache + id: nix-cache + uses: actions/cache@0057852bfaa89a56745cba8c7296529d2fc39830 # v4 + with: + path: /tmp/nix-closure + key: nix-devshell-${{ runner.os }}-${{ hashFiles('flake.lock', 'flake.nix') }} + + - name: Import cached Nix store paths + if: steps.nix-cache.outputs.cache-hit == 'true' + shell: bash + run: nix-store --import < /tmp/nix-closure/store.nar + + - shell: bash + run: nix develop --profile /tmp/dev-profile --command make all + + - name: Export Nix store for caching + if: steps.nix-cache.outputs.cache-hit != 'true' + shell: bash + run: | + mkdir -p /tmp/nix-closure + nix-store --export $(nix-store -qR /tmp/dev-profile) > /tmp/nix-closure/store.nar diff --git a/.github/workflows/deploy.yml b/.github/workflows/deploy.yml deleted file mode 100644 index 75b2c1a6a..000000000 --- a/.github/workflows/deploy.yml +++ /dev/null @@ -1,42 +0,0 @@ -# Simple workflow for deploying static content to GitHub Pages -name: Deploy pre-rendered static content to Pages - -on: - # Runs on pushes targeting the default branch - push: - branches: ["main"] - - # Allows you to run this workflow manually from the Actions tab - workflow_dispatch: - -# Sets permissions of the GITHUB_TOKEN to allow deployment to GitHub Pages -permissions: - contents: read - pages: write - id-token: write - -# Allow only one concurrent deployment, skipping runs queued between the run in-progress and latest queued. -# However, do NOT cancel in-progress runs as we want to allow these production deployments to complete. -concurrency: - group: "pages" - cancel-in-progress: false - -jobs: - # Single deploy job since we're just deploying - deploy: - environment: - name: github-pages - url: ${{ steps.deployment.outputs.page_url }} - runs-on: ubuntu-latest - steps: - - name: Checkout - uses: actions/checkout@v4 - - name: Setup Pages - uses: actions/configure-pages@v5 - - name: Upload artifact - uses: actions/upload-pages-artifact@v3 - with: - path: 'rendered' - - name: Deploy to GitHub Pages - id: deployment - uses: actions/deploy-pages@v4 diff --git a/.github/workflows/publish.yaml b/.github/workflows/publish.yaml new file mode 100644 index 000000000..aa1f935c0 --- /dev/null +++ b/.github/workflows/publish.yaml @@ -0,0 +1,87 @@ +name: Deploy Rendered Site + +on: + push: + branches: [ main ] + +env: + CARGO_TERM_COLOR: always + +# Sets permissions of the GITHUB_TOKEN to allow deployment to GitHub Pages +permissions: + contents: write + pages: write + id-token: write + +# Allow only one concurrent deployment, skipping runs queued between the run +# in-progress and latest queued. However, do NOT cancel in-progress runs as we +# want to allow these production deployments to complete. +concurrency: + group: "pages" + cancel-in-progress: false + +jobs: + render-and-deploy: + runs-on: ubuntu-latest + + steps: + - name: Generate app token + id: app-token + uses: actions/create-github-app-token@bcd2ba49218906704ab6c1aa796996da409d3eb1 # v3.2.0 + with: + client-id: ${{ secrets.APP_ID }} + private-key: ${{ secrets.APP_PRIVATE_KEY }} + + - name: Checkout repository + uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6.0.2 + with: + ref: publish + fetch-depth: 0 + token: ${{ steps.app-token.outputs.token }} + + - name: Verify nonexistence of `base_ref` + shell: bash + run: | + if [ -e base_ref ]; then exit 1; fi + + - name: Set base ref + run: | + git show --format=%H --no-notes --no-patch 'HEAD' -- |tee base_ref + if ! ( grep -E '^[0-9a-f]{40}$' base_ref ); then exit 1; fi + + - name: Setup Pages + uses: actions/configure-pages@45bfe0192ca1faeb007ade9deae92b16b8254a0d # v6.0.0 + + - name: Merge `main` to the `publish` branch + run: | + set -x + git config --global user.name 'github_actions' + git config --global user.email 'actions@github.com' + version="$(git describe --tags --abbrev=6 origin/main |sed 's/-1-g.*//')" + # Merge preferring the version in main. + git merge -s recursive -Xtheirs origin/main --commit -m 'Auto-deploy: merging "main" branch' + # Apply a tag to the merge commit, otherwise the uses of `git describe` in `protocol/Makefile` + # won't find it. Any existing tag of the same name will be overwritten. + git tag -f "${version}-auto" + + - name: Compile ZIPs and Zcash Protocol Specification + uses: ./.github/actions/render + + - name: Set `.gitignore` to not ignore `rendered/` + # This needs to be afer rendering so that it is not considered to make the tree dirty. + run: sed -i 's@^rendered/$@@' .gitignore + + - name: Commit and push to `publish` branch + uses: EndBug/add-and-commit@290ea2c423ad77ca9c62ae0f5b224379612c0321 # v10.0.0 + with: + add: 'rendered' + default_author: github_actions + + - name: Upload artifact + uses: actions/upload-pages-artifact@fc324d3547104276b827a68afc52ff2a11cc49c9 # v5.0.0 + with: + path: 'rendered' + + - name: Deploy to GitHub Pages + id: deployment + uses: actions/deploy-pages@cd2ce8fcbc39b97be8ca5fce6e763baed58fa128 # v5.0.0 diff --git a/.github/workflows/render.yml b/.github/workflows/render.yml index 11fbb8ccc..ca936488b 100644 --- a/.github/workflows/render.yml +++ b/.github/workflows/render.yml @@ -1,25 +1,60 @@ -name: Build tex and rst +name: Check Renderability -on: - workflow_dispatch: - push: - branches: - - main +on: + pull_request: jobs: - render: runs-on: ubuntu-latest steps: - name: Checkout repository - uses: actions/checkout@v4.1.7 - with: - token: ${{ secrets.CI_TOKEN }} + uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6.0.2 + with: + fetch-depth: 3 - - name: Compile ZIPs and Zcash Protocol Specification - uses: ./.github/actions/render + - name: Verify nonexistence of `rendered` and `base_ref` + shell: bash + run: | + if [ -e rendered ]; then exit 1; fi + if [ -e base_ref ]; then exit 1; fi - - uses: EndBug/add-and-commit@v9.1.4 + - name: Install Nix + uses: DeterminateSystems/nix-installer-action@ef8a148080ab6020fd15196c2084a2eea5ff2d25 # v22 + + - name: Restore Nix store cache + id: nix-cache + uses: actions/cache@27d5ce7f107fe9357f9df03efb73ab90386fccae # v5.0.5 with: - add: 'protocol/*.pdf *.html' - default_author: github_actions + path: /tmp/nix-closure + key: nix-devshell-${{ runner.os }}-${{ hashFiles('flake.lock', 'flake.nix') }} + + - name: Import cached Nix store paths + if: steps.nix-cache.outputs.cache-hit == 'true' + run: nix-store --import < /tmp/nix-closure/store.nar + + - name: Compile ZIPs + run: nix develop --profile /tmp/dev-profile --command make all-zips + + - name: Set base ref + run: | + git show --format=%H --no-notes --no-patch "HEAD~1" -- |tee base_ref + if ! ( grep -E '^[0-9a-f]{40}$' base_ref ); then exit 1; fi + + - name: Compile Protocol Specification + run: nix develop --profile /tmp/dev-profile --command make all + + - name: Export Nix store for caching + if: steps.nix-cache.outputs.cache-hit != 'true' + run: | + # Free up some space before creating the (possibly very large) store tarball. + df + dpkg-query -Wf '${Installed-Size}\t${Package}\n' | sort -rn 2>/dev/null | head -30 + docker system prune --all --force || /bin/true + sudo apt-get -y remove --purge \ + '^docker.*' '^microsoft-edge.*' azure-cli '^google-cloud-cli.*' '^google-chrome.*' \ + firefox java-common '^llvm-.*' '^libllvm.*' '^libclang-.*' '^mysql-.*' powershell snapd + sudo apt-get -y autoremove --purge + dpkg-query -Wf '${Installed-Size}\t${Package}\n' | sort -rn 2>/dev/null | head -30 + df + mkdir -p /tmp/nix-closure + nix-store --export $(nix-store -qR /tmp/dev-profile) > /tmp/nix-closure/store.nar diff --git a/.github/workflows/report_updatecheck.yml b/.github/workflows/report_updatecheck.yml new file mode 100644 index 000000000..b03435115 --- /dev/null +++ b/.github/workflows/report_updatecheck.yml @@ -0,0 +1,49 @@ +name: Status of dependency check +on: + workflow_run: + workflows: ["Check dependencies of rendered ZIPs"] + types: [completed] + +permissions: + actions: read # Needed to list artifacts + checks: write # Needed to post the status + +jobs: + post_status: + runs-on: ubuntu-latest + steps: + - uses: actions/github-script@v9 + with: + script: | + const runId = context.payload.workflow_run.id; + let conclusion = context.payload.workflow_run.conclusion; + let title = 'Dependencies are incorrect or could not be checked'; + + if (conclusion === 'success') { + // Check if the "neutral-signal" artifact exists. + const artifacts = await github.rest.actions.listWorkflowRunArtifacts({ + owner: context.repo.owner, + repo: context.repo.repo, + run_id: runId, + }); + + if (artifacts.data.artifacts.some(a => a.name === 'neutral-signal')) { + conclusion = 'neutral'; + title = 'Dependencies are correct but not up-to-date'; + } else { + title = 'Dependencies are correct and up-to-date'; + } + } + + await github.rest.checks.create({ + owner: context.repo.owner, + repo: context.repo.repo, + name: 'Dependency check result', + head_sha: context.payload.workflow_run.head_sha, + status: 'completed', + conclusion, + output: { + title, + summary: "See 'View details' on 'Check dependencies of rendered ZIPs' for more information." + } + }); diff --git a/.github/workflows/updatecheck.yml b/.github/workflows/updatecheck.yml new file mode 100644 index 000000000..08d4b05e2 --- /dev/null +++ b/.github/workflows/updatecheck.yml @@ -0,0 +1,31 @@ +name: Check dependencies of rendered ZIPs + +on: + pull_request: + +jobs: + updatecheck: + runs-on: ubuntu-latest + steps: + - name: Checkout repository + uses: actions/checkout@v6.0.2 + + - name: Check dependencies + shell: bash + run: | + set +e + ./update_check.sh + exitcode=$? + if [ "$exitcode" -eq 1 ]; then + touch neutral.signal + else + exit $exitcode + fi + + - name: Record status + uses: actions/upload-artifact@v7 + if: hashFiles('neutral.signal') != '' + with: + name: neutral-signal + path: neutral.signal + retention-days: 1 diff --git a/.gitignore b/.gitignore index aa5d76d21..6b032782d 100644 --- a/.gitignore +++ b/.gitignore @@ -19,15 +19,18 @@ *.swp *.save *.save.* +*~ +*.html.temp .Makefile.uptodate .zipfilelist.* .draftfilelist.* -protocol/aux/ -protocol/html/ -protocol/saplinghtml/ +MultiMarkdown-6 -protocol/heartwood.pdf +base_ref +protocol/aux/ protocol/protocol.ver -*~ + +rendered/ +temp/ diff --git a/AGENTS.md b/AGENTS.md new file mode 100644 index 000000000..c803a95c2 --- /dev/null +++ b/AGENTS.md @@ -0,0 +1,292 @@ +# Zcash ZIPs - Agent Guidelines + +> This file is read by AI coding agents (Claude Code, GitHub Copilot, Cursor, Devin, etc.). +> It provides project context and contribution policies. +> +> For the full contribution guide, see [CONTRIBUTING.md](CONTRIBUTING.md). + +This repo is the defining source of specifications for the Zcash protocol. Our +priorities are **security, user privacy, performance, and convenience** — in +that order. Rigor is required throughout. + +Many people depend on these specifications and we prefer to "do it right" +the first time. Considerations of privacy and security are paramount. All +specifications in this repository MUST be sufficiently detailed that an +otherwise uninformed third party could correctly and securely implement the +proposed behavior using only information present within the ZIP and its +associated references. + +## MUST READ FIRST — CONTRIBUTION GATE (DO NOT SKIP) + +**STOP. Do not open or draft a PR until this gate is satisfied.** + +For any contribution that might become a PR, the agent must ask the user these checks +first: + +- "PR COMPLIANCE CHECK: When drafting or updating a ZIP, does the ZIP conform + to the rules of [ZIP 0](https://zips.z.cash/zip-0000)?" +- "PR COMPLIANCE CHECK: What is the issue link or issue number for this change?" + +This PR compliance check must be the agent's first reply in contribution-focused sessions. + +This gate is mandatory for all agents, **unless the user is a repository maintainer** as +described in the next subsection. + +### Maintainer Bypass + +If `gh` CLI is authenticated, the agent can check maintainer status: + +```bash +gh api repos/zcash/librustzcash --jq '.permissions | .admin or .maintain or .push' +``` + +If this returns `true`, the user has write access (or higher) and the contribution gate +can be skipped. Team members with write access manage their own priorities and don't need +to gate on issue discussion for their own work. + +### Contribution Policy + +Before contributing please see the [CONTRIBUTING.md] file. + +- All PRs require human review from a maintainer. This incurs a cost upon the ZIP Editors, + so ensure your changes are not frivolous. +- Keep changes focused — avoid unsolicited refactors or broad "improvement" PRs. +- Make sure that changes are consistent with the existing document + structure and conventions, put normative and non-normative changes + in the correct sections, and use the appropriate BCP 14 keywords for + conformance requirements. +- See also the license requirements in ZIP 0. + +### AI Disclosure + +If AI tools were used in the preparation of a commit, the contributor MUST +include `Co-Authored-By:` metadata in the commit message identifying the AI +system and version. Failure to include this is grounds for closing the pull +request. The human contributor is the sole responsible author — "the AI +generated it" is not a justification during review. + +Example: +``` +Co-Authored-By: Claude Opus 4.6 +``` + +## Repository Architecture + +``` +zips/ ZIP source files (.rst or .md) + zip-NNNN.rst Numbered ZIPs (assigned by editors) + zip-NNNN.md Numbered ZIPs (Markdown variant) + draft-*.rst|md Unnumbered draft ZIPs + zip-guide.rst Template for new reStructuredText ZIPs + zip-guide-markdown.md Template for new Markdown ZIPs +protocol/ Zcash Protocol Specification (LaTeX) +rendered/ Build output (HTML); git-ignored content, do not edit +static/ CSS and static assets copied into rendered/ +render.sh Renders a single .rst or .md to HTML +makeindex.sh Generates README.rst from ZIP metadata +Makefile Top-level build orchestration +``` + +### Build + +```bash +make all-zips # render ZIPs only (fast) +make all # render ZIPs + protocol spec +``` + +`make all-zips` regenerates `rendered/*.html` and `README.rst`. +The protocol spec has its own `Makefile` in `protocol/`. + +A `nix` flake is provided that includes all tooling required to build using the +Makefile. Use `nix develop -c` to render ZIPs and specifications using the +canonical tool set. + +### File Naming + +- Drafts: `zips/draft--.rst` (or `.md`). Do NOT assign a ZIP number. +- Numbered ZIPs: `zips/zip-NNNN.rst` (or `.md`). Numbers assigned by ZIP Editors only. +- Auxiliary files (diagrams, etc.) for a ZIP go in `zips/zip-NNNN/` or alongside the + ZIP with a `zip-NNNN-` prefix. + +## Key Rules from ZIP 0 + +ZIP 0 (`zips/zip-0000.rst`) governs the full ZIP process. Agents MUST +treat it as authoritative. The following is a summary of the rules most +relevant to contributions; consult ZIP 0 for the complete specification. + +### ZIP Syntax + +ZIPs are written in either Markdown or reStructuredText. For new ZIPs, +ask your user which format they would prefer, defaulting to Markdown; +for existing ZIPs, preserve the current format. In either case, any +mathematical or algorithmic content SHOULD be written in the +[KaTeX subset](https://katex.org/docs/support_table) of LaTeX, enclosed +in `$` symbols (this is a supported extension for reStructuredText ZIPs, +except in tables). + +The Markdown variant is +[MultiMarkdown](https://markedapp.com/help/MultiMarkdown_v5_Spec.html). +Use the `[^name]` format for citations in Markdown (as if they are +footnotes) and add a corresponding entry in the References section. See +`zips/zip-guide-markdown.md` for more information about conventions and +syntax. + +For reStructuredText ZIPs, see `zips/zip-guide.rst` for conventions and +syntax. + +For new content, wrap lines at roughly 80 to 100 characters, matching +the existing wrapping width of the document. Do not rewrap existing +content unless it is changing anyway. Embedded LaTeX, hyperlinks, and +tables can exceed the usual wrapping width. + +### ZIP Structure (required sections) + +Every ZIP SHOULD contain these sections in order: + +1. **Preamble** — RFC 822-style header block. Required fields: + `ZIP`, `Title`, `Owners`, `Status`, `Category`, `Created`, `License`. +2. **Terminology** — define non-obvious terms. +3. **Abstract** — ~200-word self-contained summary including privacy implications. +4. **Motivation** — why the existing protocol is inadequate. +5. **Privacy Implications** — present if the ZIP affects user privacy. +6. **Requirements** — high-level goals; MUST NOT contain conformance requirements. +7. **Specification** — detailed technical spec; must allow independent interoperable + implementations. +8. **Rationale** — design alternatives considered, community concerns addressed. + An alternative to including a top-level Rationale section is to add rationale + subsections immediately following the content they provide a rationale for. + Their content should normally be "folded" as described in `zip-guide`. +9. **Reference implementation** — required before status reaches Implemented/Final. +10. **References** — a list of other documents referred to by the ZIP. + +Section and subsection headings MUST be unique within the document (for +example, use "Rationale for ..." as headings of rationale subsections). + +The Specification section is normative (except for rationale subsections), +and SHOULD use BCP 14 conformance keywords where applicable. Other sections +SHOULD NOT use BCP 14 conformance keywords, except to define them in the +Terminology section. + +**Important**: The goals set in the Requirements section should be as +complete as practically possible for the intended purpose of the ZIP, and +the specification should meet those goals. + +### Preamble Format + +reStructuredText ZIPs begin with `::` then a blank line, then the header +block indented by 2 spaces. Markdown ZIPs begin with `---` YAML front matter. +Use `zips/zip-guide.rst` or `zips/zip-template.md` as a starting template. + +### Status Values + +Draft | Proposed | Implemented | Final | Active | Withdrawn | Rejected | Obsolete | Reserved + +Only Owners may change between Draft and Withdrawn. All other transitions +require ZIP Editor consensus. A ZIP with security or privacy implications +MUST NOT become Released (Proposed/Active/Implemented/Final) without +independent security review. + +### Categories + +Consensus | Standards | Process | Consensus Process | Informational | +Network | RPC | Wallet | Ecosystem + +Consensus ZIPs MUST have a Deployment section before reaching Proposed status. + +### Licensing + +Every ZIP MUST specify at least one approved license. `MIT` is recommended. + +### BCP 14 Keywords + +The keywords MUST, MUST NOT, SHOULD, SHOULD NOT, MAY, RECOMMENDED, +OPTIONAL, and REQUIRED carry their BCP 14 meanings **only when in ALL CAPS**. +If any of these keywords are used, the ZIP MUST include a boilerplate +definition of them at the start of the Terminology section: + +``` +The key words (list of the keywords actually used) in this document are to +be interpreted as described in BCP 14 [^BCP14] when, and only when, they +appear in all capitals. +``` + +(use `[#BCP14]` for reStructuredText), and a reference to BCP 14 in the +References section. + +### Common Rejection Reasons + +- Insufficient or unclear motivation +- Missing or inadequate privacy analysis +- Security risks insufficiently addressed +- Disregard for formatting rules or ZIP 0 conformance requirements +- Duplicates existing effort without justification +- Too unfocused or broad + +### Zcash Protocol Specification + +The Zcash **consensus protocol** is defined by the Zcash Protocol Specification +together with ZIPs in the Consensus category. New specifications of things that +are not enforced in consensus SHOULD be kept out of the protocol specification +(there may be present exceptions to this). + +All values referred to in the protocol specification, or proposed updates to +the consensus protocol, MUST be typed. The types define implicit consensus +rules, i.e. producers and consumers of values MUST ensure that they are of the +specified type. + +The protocol specification is split into Abstract and Concrete sections. See +the start of the "Abstract Protocol" section for the intended purpose of this +split, which should be adhered to in any new content. + +The usual process for updating the protocol specification is to first write an +"Update ZIP" (which will be assigned a number in the 2xxx series by the ZIP +Editors). This ZIP should describe the precise changes needed to the protocol +specification and other ZIPs, along with their motivation and rationale. The +ZIP Editors will then apply these changes at the appropriate time, usually when +the Update ZIP transitions to Proposed status. + +Since ZIPs do not currently support user-defined macros, the use of the KaTeX +subset of LaTeX in ZIPs, including Update ZIPs, SHOULD be whatever is needed +to render the content correctly — e.g. explicit use of formatting macros such +as `\mathsf` to match the typographical conventions in the protocol +specification. + +The information in the rest of this section will therefore only typically be +needed when making editorial corrections or refactorings to the protocol +specification that do not need separate review as a ZIP, or by tools used by +the ZIP Editors when they apply changes from an Update ZIP. + +The Zcash Protocol Specification is written in LaTeX (`protocol/protocol.tex`), +with a `biblatex` bibliography (`protocol/zcash.bib`). It extensively uses +macros for terms that are to appear in the index or for defined notation, +and you should try to follow existing usage in this respect. + +The relevant macros referring to particular protocol upgrades (`\nusixone`, +etc.) SHOULD be used to mark the content of specifications to be deployed +in those upgrades. + +Explicit consensus rules SHOULD be expressed using the `\consensusrule` +macro or `{consensusrules}` environment. + +The `\pnote` macro or `{pnotes}` environment is used for normative notes, +and the `\nnote` macro or `{nnotes}` environment is used for non-normative, +explanatory notes or rationale. + +Substantive changes to the protocol specification MUST have a corresponding +Change History entry. If there is no "open" entry (with an undated use of +`\historyentry`) at the top of the Change History section, add one. + +New subsections, etc. MUST use the corresponding macro (`\lsubsection`, +`\lsubsubsection`, etc.) with a unique label argument. Use `\introsection` +before subsections and `\introlist` before lists to avoid page breaks at +undesirable points near the start of the subsection or list. + +## Changelog and Commit Discipline + +- Commits must be discrete semantic changes — no WIP commits in final PR history. +- Use `git revise` to maintain clean history within a PR. +- Commit messages: short title (<120 chars), body with motivation for the change. + +## CI Checks (all must pass) + +- `nix develop -c make all` diff --git a/Dockerfile b/Dockerfile index 48fd6085e..4a35880ae 100644 --- a/Dockerfile +++ b/Dockerfile @@ -1,11 +1,11 @@ -FROM debian:latest +FROM debian:bullseye RUN apt-get update RUN apt-get install -y \ - gawk \ perl \ sed \ git \ + cmake \ python3 \ python3-pip \ pandoc \ @@ -17,10 +17,21 @@ RUN apt-get install -y \ texlive-plain-generic \ texlive-bibtex-extra -RUN rm /usr/lib/python3.11/EXTERNALLY-MANAGED -RUN pip install rst2html5 +RUN rm -f /usr/lib/python3.11/EXTERNALLY-MANAGED +RUN pip install 'docutils==0.21.2' 'rst2html5==2.0.1' + +# Use a fork so that we're running pinned code. The Makefile for +# MultiMarkdown-6 expects the `master` branch to exist for delta computation, +# so we also add that branch locally, even though it's otherwise unused. +RUN git clone -b develop https://github.com/Electric-Coin-Company/MultiMarkdown-6 && \ + cd MultiMarkdown-6 && \ + git branch master origin/master && \ + make release && cd build && make && make install ENV PATH=${PATH}:/root/.local/bin WORKDIR "/zips" -ENTRYPOINT ["make", "all"] + +# By default this will run "make all-docker", but passing an argument will override the make target. +ENTRYPOINT ["make"] +CMD ["all-docker"] diff --git a/Makefile b/Makefile index 67edd0845..748426efe 100644 --- a/Makefile +++ b/Makefile @@ -1,6 +1,8 @@ -# Dependencies: see zip-guide.rst and protocol/README.rst +# Dependencies: see zips/zip-guide.rst and protocol/README.rst -.PHONY: all-zips all tag-release protocol all-protocol discard +MARKDOWN_OPTION?=--mmd + +.PHONY: all-zips all-docker all tag-release protocol all-protocol discard all-zips: .Makefile.uptodate echo "$(patsubst zips/%,%,$(sort $(wildcard zips/zip-*.rst) $(wildcard zips/zip-*.md)))" >.zipfilelist.new diff .zipfilelist.current .zipfilelist.new || cp -f .zipfilelist.new .zipfilelist.current @@ -8,57 +10,59 @@ all-zips: .Makefile.uptodate echo "$(patsubst zips/%,%,$(sort $(wildcard zips/draft-*.rst) $(wildcard zips/draft-*.md)))" >.draftfilelist.new diff .draftfilelist.current .draftfilelist.new || cp -f .draftfilelist.new .draftfilelist.current rm -f .draftfilelist.new + mkdir -p rendered + cp -r static/* rendered/ $(MAKE) README.rst $(MAKE) rendered/index.html $(addprefix rendered/,$(addsuffix .html,$(basename $(patsubst zips/%,%,$(sort $(wildcard zips/*.rst) $(wildcard zips/*.md)))))) -all: all-zips all-protocol +all-docker: + git config --global --add safe.directory "$(shell pwd)" + $(MAKE) all -tag-release: - $(MAKE) -C protocol tag-release +all: all-zips all-protocol protocol: $(MAKE) -C protocol protocol +protocol-dark: + $(MAKE) -C protocol protocol-dark + all-protocol: $(MAKE) -C protocol all +all-specs: all-zips + $(MAKE) -C protocol all-specs + discard: - git checkout -- 'rendered/*.html' 'README.rst' 'rendered/protocol/*.pdf' + rm -r rendered + git checkout -- 'README.rst' -.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 render.sh + ./render.sh --rst $< $@ -rendered/index.html: README.rst edithtml.sh - $(PROCESSRST) +rendered/%.html: zips/%.rst render.sh + ./render.sh --rst $< $@ -rendered/%.html: zips/%.rst edithtml.sh - $(PROCESSRST) - -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 -.PHONY: linkcheck clean all-clean +.PHONY: linkcheck updatecheck clean all-clean linkcheck: all ./links_and_dests.py --check $(filter-out $(wildcard rendered/draft-*.html),$(wildcard rendered/*.html)) $(filter-out rendered/protocol/sprout.pdf,$(wildcard rendered/protocol/*.pdf)) +updatecheck: + ./update_check.sh + clean: rm -f .zipfilelist.* README.rst rendered/index.html $(addprefix rendered/,$(addsuffix .html,$(basename $(patsubst zips/%,%,$(sort $(wildcard zips/*.rst) $(wildcard zips/*.md)))))) + rm -rf temp all-clean: $(MAKE) clean diff --git a/README.rst b/README.rst index 79183863e..7a7b373e9 100644 --- a/README.rst +++ b/README.rst @@ -20,13 +20,16 @@ and documenting / addressing dissenting opinions. Anyone can write a ZIP! We encourage community contributions and decentralization of work on the Zcash protocol. If you’d like to bounce ideas off people before formally -writing a ZIP, we encourage it! Visit the `ZcashCommunity Discord chat `__ +writing a ZIP, we encourage it! +Visit the `Zcash Community Forum `__ to talk about your idea. Participation in the Zcash project is subject to a `Code of Conduct `__. -The Zcash protocol is documented in its `Protocol Specification `__. +The Zcash protocol is documented in its +`Protocol Specification `__ +`(dark mode version) `__. To start contributing, first read `ZIP 0 `__ which documents the ZIP process. Then clone `this repo `__ from GitHub, and start adding @@ -40,6 +43,47 @@ and double-check the generated ``rendered/draft-*.html`` file before filing a Pu See `here `__ for the project dependencies. +Settled Mainnet Network Upgrade +------------------------------- + +The most recent [settled](https://zips.z.cash/protocol/protocol.pdf#blockchain) Network Upgrade +on Mainnet is NU6.1, which activated at Mainnet block height 3146400 on November 24, 2025, at +19:56 UTC. + +NU6.1 is described in `ZIP 255: Deployment of the NU6.1 Network Upgrade `__. +It deployed the following ZIPs: + +- `ZIP 1016: Community and Coinholder Funding Model `__ +- `ZIP 271: Deferred Dev Fund Lockbox Disbursement `__ + + +NU7 Candidate ZIPs +------------------ + +The following ZIPs are under consideration for deployment in NU7: + +- `ZIP 218: 25-second Block Target Spacing `__ +- `ZIP 226: Transfer and Burn of Zcash Shielded Assets `__ +- `ZIP 227: Issuance of Zcash Shielded Assets `__ +- `ZIP 230: Version 6 Transaction Format `__ +- `ZIP 231: Memo Bundles `__ +- `ZIP 233: Network Sustainability Mechanism: Removing Funds From Circulation `__ +- `ZIP 234: Network Sustainability Mechanism: Issuance Smoothing `__ +- `ZIP 235: Network Sustainability Mechanism: Remove 60% of Transaction Fees From Circulation `__ +- `ZIP 246: Digests for the Version 6 Transaction Format `__ +- `ZIP 2002: Explicit Fees `__ +- `ZIP 2003: Disallow version 4 transactions `__ + +In addition, `ZIP 317: Proportional Transfer Fee Mechanism `__ +may be updated. + +This list is only provided here for easy reference; no decision has been made +on whether to include each of these ZIPs. + +`draft-arya-deploy-nu7: Deployment of the NU7 Network Upgrade `__ +will define which ZIPs are included in NU7. + + License ------- @@ -66,36 +110,41 @@ Released ZIPs 203 Transaction Expiry Final 205 Deployment of the Sapling Network Upgrade Final 206 Deployment of the Blossom Network Upgrade Final - 207 Funding Streams Final + 207 Funding Streams [Revision 0: Canopy, Revision 1: NU6] Final 208 Shorter Block Target Spacing Final 209 Prohibit Negative Shielded Chain Value Pool Balances Final 211 Disabling Addition of New Value to the Sprout Chain Value Pool Final 212 Allow Recipient to Derive Ephemeral Secret from Note Plaintext Final 213 Shielded Coinbase Final - 214 Consensus rules for a Zcash Development Fund Revision 0: Final, Revision 1: Draft + 214 Consensus rules for a Zcash Development Fund [Revision 0: Canopy, Revision 1: NU6] Final, [Revision 2: NU6.1] Proposed 215 Explicitly Defining and Modifying Ed25519 Validation Rules Final 216 Require Canonical Jubjub Point Encodings Final 221 FlyClient - Consensus-Layer Changes Final 224 Orchard Shielded Protocol Final 225 Version 5 Transaction Format Final + 236 Blocks should balance exactly Final 239 Relay of Version 5 Transactions Final 243 Transaction Signature Validation for Sapling Final 244 Transaction Identifier Non-Malleability Final 250 Deployment of the Heartwood Network Upgrade Final 251 Deployment of the Canopy Network Upgrade Final 252 Deployment of the NU5 Network Upgrade Final - 253 Deployment of the NU6 Network Upgrade Proposed + 253 Deployment of the NU6 Network Upgrade Final + 255 Deployment of the NU6.1 Network Upgrade Proposed + 271 Dev Fund Extension and One-Time Disbursement Proposed 300 Cross-chain Atomic Transactions Proposed - 301 Zcash Stratum Protocol Final - 308 Sprout to Sapling Migration Final - 316 Unified Addresses and Unified Viewing Keys Revision 0: Final, Revision 1: Proposed + 301 Zcash Stratum Protocol Active + 308 Sprout to Sapling Migration Active + 316 Unified Addresses and Unified Viewing Keys [Revision 0] Active, [Revision 1] Withdrawn, [Revision 2] Draft 317 Proportional Transfer Fee Mechanism Active - 320 Defining an Address Type to which funds can only be sent from Transparent Addresses Proposed - 321 Payment Request URIs Proposed + 320 Defining an Address Type to which funds can only be sent from Transparent Addresses Active + 321 Payment Request URIs Active 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 - 2001 Lockbox Funding Streams Proposed + 1015 Block Subsidy Allocation for Non-Direct Development Funding Final + 1016 Community and Coinholder Funding Model Proposed + 2001 Lockbox Funding Streams Final + 2005 Orchard Quantum Recoverability Proposed Draft ZIPs @@ -111,51 +160,61 @@ written. .. raw:: html - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
ZIP Title Status
1 Network Upgrade Policy and Scheduling Reserved
2 Design Considerations for Network Upgrades Reserved
68 Relative lock-time using consensus-enforced sequence numbers Draft
76 Transaction Signature Validation before Overwinter Reserved
112 CHECKSEQUENCEVERIFY Draft
113 Median Time Past as endpoint for lock-time calculations Draft
204 Zcash P2P Network Protocol Reserved
217 Aggregate Signatures Reserved
219 Disabling Addition of New Value to the Sapling Chain Value Pool Reserved
222 Transparent Zcash Extensions Draft
226 Transfer and Burn of Zcash Shielded Assets Draft
227 Issuance of Zcash Shielded Assets Draft
228 Asset Swaps for Zcash Shielded Assets Reserved
230 Version 6 Transaction Format Draft
231 Decouple Memos from Transaction Outputs Reserved
233 Establish the Zcash Sustainability Fund on the Protocol Level Draft
234 Smooth Out The Block Subsidy Issuance Draft
236 Blocks should balance exactly Draft
245 Transaction Identifier Digests & Signature Validation for Transparent Zcash Extensions Draft
302 Standardized Memo Field Format Draft
303 Sprout Payment Disclosure Reserved
304 Sapling Address Signatures Draft
305 Best Practices for Hardware Wallets supporting Sapling Reserved
306 Security Considerations for Anchor Selection Reserved
307 Light Client Protocol for Payment Detection Draft
309 Blind Off-chain Lightweight Transactions (BOLT) Reserved
310 Security Properties of Sapling Viewing Keys Draft
311 Zcash Payment Disclosures Draft
312 FROST for Spend Authorization Multisignatures Draft
314 Privacy upgrades to the Zcash light client protocol Reserved
315 Best Practices for Wallet Implementations Draft
318 Associated Payload Encryption Reserved
319 Options for Shielded Pool Retirement Reserved
322 Generic Signed Message Format Reserved
323 Specification of getblocktemplate for Zcash Reserved
324 URI-Encapsulated Payments Draft
332 Wallet Recovery from zcashd HD Seeds Reserved
339 Wallet Recovery Words Reserved
400 Wallet.dat format Draft
402 New Wallet Database Format Reserved
403 Verification Behaviour of zcashd Reserved
416 Support for Unified Addresses in zcashd Reserved
guide-markdown {Something Short and To the Point} Draft
guide {Something Short and To the Point} Draft
ZIP Title Status Discussions-To
1 Network Upgrade Policy and Scheduling Reserved zips#343
2 Design Considerations for Network Upgrades Reserved zips#362
48 Transparent Multisig Wallets Draft zips#1059
68 Relative lock-time using consensus-enforced sequence numbers Draft
76 Transaction Signature Validation before Overwinter Reserved zips#130
112 CHECKSEQUENCEVERIFY Draft
113 Median Time Past as endpoint for lock-time calculations Draft
129 Zcash Transparent Multisig Setup Reserved zips#1060
204 Zcash P2P Network Protocol Draft zips#352
217 Aggregate Signatures Reserved zips#1137
218 25-second Block Target Spacing Draft https://forum.zcashcommunity.com/t/proposal-lower-zcash-block-target-spacing-to-25s/54577
219 Disabling Addition of New Value to the Sapling Chain Value Pool Reserved zips#428
222 Transparent Zcash Extensions Draft zips#1231
226 Transfer and Burn of Zcash Shielded Assets Draft zips#618
227 Issuance of Zcash Shielded Assets Draft zips#618
228 Asset Swaps for Zcash Shielded Assets Reserved zips#776
231 Memo Bundles Draft zips#627
233 Network Sustainability Mechanism: Removing Funds From Circulation Draft zips#922
234 Network Sustainability Mechanism: Issuance Smoothing Draft zips#923
235 Remove 60% of Transaction Fees From Circulation Draft zips#924
240 Standard Transaction Rules Reserved zips#648
245 Transaction Identifier Digests & Signature Validation for Transparent Zcash Extensions Draft zips#384
246 Digests for the Version 6 Transaction Format Draft
260 Extending Block Messages with Additional Authentication Data Reserved zips#522
270 Key Rotation for Tracked Signing Keys Reserved zips#1047
302 Standardized Memo Field Format Draft zips#366
304 Sapling Address Signatures Draft zips#345
305 Best Practices for Hardware Wallets supporting Sapling Reserved zips#346
306 Security Considerations for Anchor Selection Reserved zips#351
307 Light Client Protocol for Payment Detection Draft
309 Blind Off-chain Lightweight Transactions (BOLT) Reserved zips#1138
310 Security Properties of Sapling Viewing Keys Draft
311 Zcash Payment Disclosures Draft zips#387
312 FROST for Spend Authorization Multisignatures Draft zips#382
314 Privacy upgrades to the Zcash light client protocol Reserved zips#434
315 Best Practices for Wallet Implementations Draft zips#447
319 Options for Shielded Pool Retirement Reserved zips#635
322 Generic Signed Message Format Reserved zips#429
323 Specification of getblocktemplate for Zcash Reserved zips#405
324 URI-Encapsulated Payments Draft zips#421
325 Account Metadata Keys Draft zips#1233
332 Wallet Recovery from zcashd HD Seeds Reserved zips#675
339 Wallet Recovery Words Reserved zips#364
350 Bech32m Reserved zips#484
400 Wallet.dat format Draft
402 New Wallet Database Format Reserved zips#365
403 Verification Behaviour of zcashd Reserved zips#404
416 Support for Unified Addresses in zcashd Reserved zips#503
2002 Explicit Fees Draft zips#803
2003 Disallow version 4 transactions Draft zips#825
2004 Remove the dependency of consensus on note encryption Draft zips#917
guide-markdown {Something Short and To the Point} Draft
guide {Something Short and To the Point} Draft
template {Template for new ZIPs} Draft
Drafts without assigned ZIP numbers @@ -169,10 +228,12 @@ be deleted. .. raw:: html - - - - + + + + + +
Title
Manufacturing Consent; Re-Establishing a Dev Fund for ECC, ZF, ZCG, Qedit, FPF, and ZecHub
Block Reward Allocation for Non-Direct Development Funding
Establishing a Hybrid Dev Fund for ZF, ZCG and a Dev Fund Reserve
Draft name Title Discussions-To
draft-arya-dairaemma-disable-addition-of-transparent-chain-value Disabling Addition of New Value to the Transparent Chain Value Pool zips#1115
draft-arya-deploy-nu7 Deployment of the NU7 Network Upgrade zips#839
draft-ecc-authenticated-reply-addrs Authenticated Reply Addresses zips#1230
draft-ecc-onchain-accountable-voting On-chain Accountable Voting
draft-str4d-orchard-balance-proof Air drops, Proof-of-Balance, and Stake-weighted Polling zips#1229
Withdrawn, Rejected, or Obsolete ZIPs @@ -186,6 +247,9 @@ Withdrawn, Rejected, or Obsolete ZIPs ZIP Title Status 210 Sapling Anchor Deduplication within Transactions Withdrawn 220 Zcash Shielded Assets Withdrawn + 230 Withdrawn Version 6 Transaction Format Withdrawn + 254 Deployment of the NU7 Network Upgrade (Withdrawn) Withdrawn + 303 Sprout Payment Disclosure Withdrawn 313 Reduce Conventional Transaction Fee to 1000 zatoshis Obsolete 1001 Keep the Block Distribution as Initially Defined — 90% to Miners Obsolete 1002 Opt-in Donation Feature Obsolete @@ -214,10 +278,12 @@ Index of ZIPs 1 Network Upgrade Policy and Scheduling Reserved 2 Design Considerations for Network Upgrades Reserved 32 Shielded Hierarchical Deterministic Wallets Final + 48 Transparent Multisig Wallets Draft 68 Relative lock-time using consensus-enforced sequence numbers Draft 76 Transaction Signature Validation before Overwinter Reserved 112 CHECKSEQUENCEVERIFY Draft 113 Median Time Past as endpoint for lock-time calculations Draft + 129 Zcash Transparent Multisig Setup Reserved 143 Transaction Signature Validation for Overwinter Final 155 addrv2 message Proposed 173 Bech32 Format Final @@ -225,20 +291,21 @@ Index of ZIPs 201 Network Peer Management for Overwinter Final 202 Version 3 Transaction Format for Overwinter Final 203 Transaction Expiry Final - 204 Zcash P2P Network Protocol Reserved + 204 Zcash P2P Network Protocol Draft 205 Deployment of the Sapling Network Upgrade Final 206 Deployment of the Blossom Network Upgrade Final - 207 Funding Streams Final + 207 Funding Streams [Revision 0: Canopy, Revision 1: NU6] Final 208 Shorter Block Target Spacing Final 209 Prohibit Negative Shielded Chain Value Pool Balances Final 210 Sapling Anchor Deduplication within Transactions Withdrawn 211 Disabling Addition of New Value to the Sprout Chain Value Pool Final 212 Allow Recipient to Derive Ephemeral Secret from Note Plaintext Final 213 Shielded Coinbase Final - 214 Consensus rules for a Zcash Development Fund Revision 0: Final, Revision 1: Draft + 214 Consensus rules for a Zcash Development Fund [Revision 0: Canopy, Revision 1: NU6] Final, [Revision 2: NU6.1] Proposed 215 Explicitly Defining and Modifying Ed25519 Validation Rules Final 216 Require Canonical Jubjub Point Encodings Final 217 Aggregate Signatures Reserved + 218 25-second Block Target Spacing Draft 219 Disabling Addition of New Value to the Sapling Chain Value Pool Reserved 220 Zcash Shielded Assets Withdrawn 221 FlyClient - Consensus-Layer Changes Final @@ -248,28 +315,36 @@ Index of ZIPs 226 Transfer and Burn of Zcash Shielded Assets Draft 227 Issuance of Zcash Shielded Assets Draft 228 Asset Swaps for Zcash Shielded Assets Reserved - 230 Version 6 Transaction Format Draft - 231 Decouple Memos from Transaction Outputs Reserved - 233 Establish the Zcash Sustainability Fund on the Protocol Level Draft - 234 Smooth Out The Block Subsidy Issuance Draft - 236 Blocks should balance exactly Draft + 230 Withdrawn Version 6 Transaction Format Withdrawn + 231 Memo Bundles Draft + 233 Network Sustainability Mechanism: Removing Funds From Circulation Draft + 234 Network Sustainability Mechanism: Issuance Smoothing Draft + 235 Remove 60% of Transaction Fees From Circulation Draft + 236 Blocks should balance exactly Final 239 Relay of Version 5 Transactions Final + 240 Standard Transaction Rules Reserved 243 Transaction Signature Validation for Sapling Final 244 Transaction Identifier Non-Malleability Final 245 Transaction Identifier Digests & Signature Validation for Transparent Zcash Extensions Draft + 246 Digests for the Version 6 Transaction Format Draft 250 Deployment of the Heartwood Network Upgrade Final 251 Deployment of the Canopy Network Upgrade Final 252 Deployment of the NU5 Network Upgrade Final - 253 Deployment of the NU6 Network Upgrade Proposed + 253 Deployment of the NU6 Network Upgrade Final + 254 Deployment of the NU7 Network Upgrade (Withdrawn) Withdrawn + 255 Deployment of the NU6.1 Network Upgrade Proposed + 260 Extending Block Messages with Additional Authentication Data Reserved + 270 Key Rotation for Tracked Signing Keys Reserved + 271 Dev Fund Extension and One-Time Disbursement Proposed 300 Cross-chain Atomic Transactions Proposed - 301 Zcash Stratum Protocol Final + 301 Zcash Stratum Protocol Active 302 Standardized Memo Field Format Draft - 303 Sprout Payment Disclosure Reserved + 303 Sprout Payment Disclosure Withdrawn 304 Sapling Address Signatures Draft 305 Best Practices for Hardware Wallets supporting Sapling Reserved 306 Security Considerations for Anchor Selection Reserved 307 Light Client Protocol for Payment Detection Draft - 308 Sprout to Sapling Migration Final + 308 Sprout to Sapling Migration Active 309 Blind Off-chain Lightweight Transactions (BOLT) Reserved 310 Security Properties of Sapling Viewing Keys Draft 311 Zcash Payment Disclosures Draft @@ -277,17 +352,18 @@ Index of ZIPs 313 Reduce Conventional Transaction Fee to 1000 zatoshis Obsolete 314 Privacy upgrades to the Zcash light client protocol Reserved 315 Best Practices for Wallet Implementations Draft - 316 Unified Addresses and Unified Viewing Keys Revision 0: Final, Revision 1: Proposed + 316 Unified Addresses and Unified Viewing Keys [Revision 0] Active, [Revision 1] Withdrawn, [Revision 2] Draft 317 Proportional Transfer Fee Mechanism Active - 318 Associated Payload Encryption Reserved 319 Options for Shielded Pool Retirement Reserved - 320 Defining an Address Type to which funds can only be sent from Transparent Addresses Proposed - 321 Payment Request URIs Proposed + 320 Defining an Address Type to which funds can only be sent from Transparent Addresses Active + 321 Payment Request URIs Active 322 Generic Signed Message Format Reserved 323 Specification of getblocktemplate for Zcash Reserved 324 URI-Encapsulated Payments Draft + 325 Account Metadata Keys Draft 332 Wallet Recovery from zcashd HD Seeds Reserved 339 Wallet Recovery Words Reserved + 350 Bech32m Reserved 400 Wallet.dat format Draft 401 Addressing Mempool Denial-of-Service Active 402 New Wallet Database Format Reserved @@ -307,8 +383,14 @@ 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 - 2001 Lockbox Funding Streams Proposed + 1015 Block Subsidy Allocation for Non-Direct Development Funding Final + 1016 Community and Coinholder Funding Model Proposed + 2001 Lockbox Funding Streams Final + 2002 Explicit Fees Draft + 2003 Disallow version 4 transactions Draft + 2004 Remove the dependency of consensus on note encryption Draft + 2005 Orchard Quantum Recoverability Proposed guide-markdown {Something Short and To the Point} Draft guide {Something Short and To the Point} Draft + template {Template for new ZIPs} Draft diff --git a/README.template b/README.template index 2c6f9219a..4f078629e 100644 --- a/README.template +++ b/README.template @@ -20,13 +20,16 @@ and documenting / addressing dissenting opinions. Anyone can write a ZIP! We encourage community contributions and decentralization of work on the Zcash protocol. If you’d like to bounce ideas off people before formally -writing a ZIP, we encourage it! Visit the `ZcashCommunity Discord chat `__ +writing a ZIP, we encourage it! +Visit the `Zcash Community Forum `__ to talk about your idea. Participation in the Zcash project is subject to a `Code of Conduct `__. -The Zcash protocol is documented in its `Protocol Specification `__. +The Zcash protocol is documented in its +`Protocol Specification `__ +`(dark mode version) `__. To start contributing, first read `ZIP 0 `__ which documents the ZIP process. Then clone `this repo `__ from GitHub, and start adding @@ -40,6 +43,47 @@ and double-check the generated ``rendered/draft-*.html`` file before filing a Pu See `here `__ for the project dependencies. +Settled Mainnet Network Upgrade +------------------------------- + +The most recent [settled](https://zips.z.cash/protocol/protocol.pdf#blockchain) Network Upgrade +on Mainnet is NU6.1, which activated at Mainnet block height 3146400 on November 24, 2025, at +19:56 UTC. + +NU6.1 is described in `ZIP 255: Deployment of the NU6.1 Network Upgrade `__. +It deployed the following ZIPs: + +- `ZIP 1016: Community and Coinholder Funding Model `__ +- `ZIP 271: Deferred Dev Fund Lockbox Disbursement `__ + + +NU7 Candidate ZIPs +------------------ + +The following ZIPs are under consideration for deployment in NU7: + +- `ZIP 218: 25-second Block Target Spacing `__ +- `ZIP 226: Transfer and Burn of Zcash Shielded Assets `__ +- `ZIP 227: Issuance of Zcash Shielded Assets `__ +- `ZIP 230: Version 6 Transaction Format `__ +- `ZIP 231: Memo Bundles `__ +- `ZIP 233: Network Sustainability Mechanism: Removing Funds From Circulation `__ +- `ZIP 234: Network Sustainability Mechanism: Issuance Smoothing `__ +- `ZIP 235: Network Sustainability Mechanism: Remove 60% of Transaction Fees From Circulation `__ +- `ZIP 246: Digests for the Version 6 Transaction Format `__ +- `ZIP 2002: Explicit Fees `__ +- `ZIP 2003: Disallow version 4 transactions `__ + +In addition, `ZIP 317: Proportional Transfer Fee Mechanism `__ +may be updated. + +This list is only provided here for easy reference; no decision has been made +on whether to include each of these ZIPs. + +`draft-arya-deploy-nu7: Deployment of the NU7 Network Upgrade `__ +will define which ZIPs are included in NU7. + + License ------- diff --git a/edithtml.sh b/edithtml.sh deleted file mode 100755 index 27c11943d..000000000 --- a/edithtml.sh +++ /dev/null @@ -1,46 +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|||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/flake.lock b/flake.lock new file mode 100644 index 000000000..9dd4af3af --- /dev/null +++ b/flake.lock @@ -0,0 +1,86 @@ +{ + "nodes": { + "flake-utils": { + "inputs": { + "systems": "systems" + }, + "locked": { + "lastModified": 1731533236, + "narHash": "sha256-l0KFg5HjrsfsO/JpG+r7fRrqm12kzFHyUHqHCVpMMbI=", + "owner": "numtide", + "repo": "flake-utils", + "rev": "11707dc2f618dd54ca8739b309ec4fc024de578b", + "type": "github" + }, + "original": { + "owner": "numtide", + "repo": "flake-utils", + "type": "github" + } + }, + "multimarkdown6": { + "inputs": { + "flake-utils": [ + "flake-utils" + ], + "nixpkgs": [ + "nixpkgs" + ] + }, + "locked": { + "lastModified": 1772132433, + "narHash": "sha256-ScYZ7ME1N1zI34iwdGIdshChqsdrOgS09aLbkIZ7Xjo=", + "owner": "zcash", + "repo": "MultiMarkdown-6", + "rev": "543434c9df78b6be9e8125ff19a5e6934dc8ba82", + "type": "github" + }, + "original": { + "owner": "zcash", + "repo": "MultiMarkdown-6", + "rev": "543434c9df78b6be9e8125ff19a5e6934dc8ba82", + "type": "github" + } + }, + "nixpkgs": { + "locked": { + "lastModified": 1768564909, + "narHash": "sha256-Kell/SpJYVkHWMvnhqJz/8DqQg2b6PguxVWOuadbHCc=", + "owner": "NixOS", + "repo": "nixpkgs", + "rev": "e4bae1bd10c9c57b2cf517953ab70060a828ee6f", + "type": "github" + }, + "original": { + "owner": "NixOS", + "ref": "nixos-unstable", + "repo": "nixpkgs", + "type": "github" + } + }, + "root": { + "inputs": { + "flake-utils": "flake-utils", + "multimarkdown6": "multimarkdown6", + "nixpkgs": "nixpkgs" + } + }, + "systems": { + "locked": { + "lastModified": 1681028828, + "narHash": "sha256-Vy1rq5AaRuLzOxct8nz4T6wlgyUR7zLU309k9mBC768=", + "owner": "nix-systems", + "repo": "default", + "rev": "da67096a3b9bf56a91d16901293e51ba5b49a27e", + "type": "github" + }, + "original": { + "owner": "nix-systems", + "repo": "default", + "type": "github" + } + } + }, + "root": "root", + "version": 7 +} diff --git a/flake.nix b/flake.nix new file mode 100644 index 000000000..14035b348 --- /dev/null +++ b/flake.nix @@ -0,0 +1,120 @@ +{ + description = "ZIP documentation rendering environment"; + + inputs = { + nixpkgs.url = "github:NixOS/nixpkgs/nixos-unstable"; + flake-utils.url = "github:numtide/flake-utils"; + multimarkdown6 = { + url = "github:zcash/MultiMarkdown-6/543434c9df78b6be9e8125ff19a5e6934dc8ba82"; + inputs.nixpkgs.follows = "nixpkgs"; + inputs.flake-utils.follows = "flake-utils"; + }; + }; + + outputs = + { + self, + nixpkgs, + flake-utils, + multimarkdown6, + }: + flake-utils.lib.eachDefaultSystem ( + system: + let + pkgs = nixpkgs.legacyPackages.${system}; + mmd = multimarkdown6.packages.${system}.default; + + # Pin docutils and rst2html5 to the versions specified in zip-guide.rst. + docutils = pkgs.python3Packages.docutils.overridePythonAttrs (old: rec { + version = "0.21.2"; + src = pkgs.fetchPypi { + pname = "docutils"; + inherit version; + hash = "sha256-OmsYcy7fGC2qPNEndbuzOM9WkUaPke7rEJ3v9uv6mG8="; + }; + }); + + # This is a separate PyPI package from docutils' built-in rst2html5; + # it provides its own HTML5 writer with different math handling. + rst2html5 = pkgs.python3Packages.buildPythonPackage rec { + pname = "rst2html5"; + version = "2.0.1"; + pyproject = true; + + src = pkgs.fetchPypi { + inherit pname version; + hash = "sha256-MJmYyF+rAo8vywGizNyIbbCvxDmCYueVoC6pxNDzKuk="; + }; + + build-system = [ pkgs.python3Packages.poetry-core ]; + + dependencies = [ + docutils + pkgs.python3Packages.genshi + pkgs.python3Packages.pygments + ]; + + # rst2html5_.py is a top-level module referenced by the entry point + # but poetry-core's include directive doesn't always install it. + postInstall = '' + cp rst2html5_.py $out/${pkgs.python3.sitePackages}/ + ''; + + # Tests require additional fixtures not included in the PyPI tarball + doCheck = false; + }; + in + { + devShells.default = pkgs.mkShell { + buildInputs = [ + # Core dependencies for render.sh + rst2html5 # rst2html5 2.0.1 (PyPI) + pkgs.python3Packages.pygments # syntax highlighting for code blocks + pkgs.pandoc # pandoc markdown renderer + mmd # multimarkdown renderer (zcash fork) + pkgs.perl # perl for text processing + + # Build system dependencies + pkgs.gnumake # make command for building + pkgs.git # required by Makefile for safe.directory + + # LaTeX dependencies for protocol PDF generation + (pkgs.texlive.combine { + inherit (pkgs.texlive) scheme-full; + }) + + # Python dependencies for links_and_dests.py + pkgs.python3 + pkgs.python3Packages.beautifulsoup4 + pkgs.python3Packages.html5lib + pkgs.python3Packages.certifi + + # Standard utilities (usually available, but ensuring they're present) + pkgs.coreutils + pkgs.bash + pkgs.gnused + pkgs.gnugrep + pkgs.diffutils + pkgs.findutils + ]; + + shellHook = '' + echo "ZIP documentation rendering environment" + echo "Available commands:" + echo " make - Build the entire project" + echo " rst2html5 - reStructuredText to HTML converter" + echo " pandoc - Universal document converter" + echo " multimarkdown - MultiMarkdown processor" + echo " latexmk - LaTeX build system for PDF generation" + echo " pdflatex - LaTeX engine for PDF generation" + echo "" + echo "Usage:" + echo " make all-zips - Build all ZIPs" + echo " make all - Build ZIPs and protocol docs" + echo " make linkcheck - Check links in generated HTML" + echo " ./render.sh --rst|--pandoc|--mmd " + ''; + }; + } + ); +} diff --git a/makeindex.sh b/makeindex.sh index 92c61ea58..a8dbf00d3 100755 --- a/makeindex.sh +++ b/makeindex.sh @@ -11,13 +11,13 @@ Released ZIPs ZIP Title Status EndOfHeader for zipfile in $(cat .zipfilelist.current); do - zipfile=zips/$zipfile - if grep -E '^\s*Status:\s*(Reserved|Draft|Withdrawn|Rejected|Obsolete)' $zipfile >/dev/null; then + zipfile="zips/$zipfile" + if grep -E '^\s*Status:\s*(Reserved|Draft|Withdrawn|Rejected|Obsolete)' "$zipfile" >/dev/null; then # Handled below. true else - echo Adding $zipfile to released index. >/dev/stderr - echo " `basename $(basename $zipfile .rst) .md | sed -E 's@zip-0{0,3}@@'` `grep '^\s*Title:' $zipfile | sed -E 's@\s*Title:\s*@@'` `grep '^\s*Status:' $zipfile | sed -E 's@\s*Status:\s*@@'`" + echo "Adding $zipfile to released index." >/dev/stderr + echo " $(basename $(basename $zipfile .rst) .md | sed -E 's@zip-0{0,3}@@') $(grep '^\s*Title:' $zipfile | sed -E 's@\s*Title:\s*@@') $(grep '^\s*Status:' $zipfile | sed -E 's@\s*Status:\s*@@')" fi done cat < - + EndOfDraftZipHeader + +discussion() { + discussion_url="$(grep '^\s*Discussions-To:\s*<' $1 | sed -E 's@^\s*Discussions-To:\s*<@@;s@>$@@')" + if [ -n "$discussion_url" ]; then + echo "$(echo $discussion_url | sed -E 's@^https://github.com/@@;s@^zcash/@@;s@/issues/@#@')" + else + echo "" + fi +} + for zipfile in $(cat .zipfilelist.current); do - zipfile=zips/$zipfile - if grep -E '^\s*Status:\s*Reserved' $zipfile >/dev/null; then - echo Adding $zipfile to draft index. >/dev/stderr - echo " " - elif grep -E '^\s*Status:\s*Draft' $zipfile >/dev/null; then - echo Adding $zipfile to draft index. >/dev/stderr - echo " " + zipfile="zips/$zipfile" + if grep -E '^\s*Status:\s*Reserved' "$zipfile" >/dev/null; then + echo "Adding $zipfile to draft index." >/dev/stderr + echo " " + elif grep -E '^\s*Status:\s*Draft' "$zipfile" >/dev/null; then + echo "Adding $zipfile to draft index." >/dev/stderr + echo " " fi done echo "
ZIP Title Status
ZIP Title Status Discussions-To
`basename $(basename $zipfile .rst) .md | sed -E 's@zip-0{0,3}@@'` `grep '^\s*Title:' $zipfile | sed -E 's@\s*Title:\s*@@'` `grep '^\s*Status:' $zipfile | sed -E 's@\s*Status:\s*@@'`
`basename $(basename $zipfile .rst) .md | sed -E 's@zip-0{0,3}@@'` `grep '^\s*Title:' $zipfile | sed -E 's@\s*Title:\s*@@'` `grep '^\s*Status:' $zipfile | sed -E 's@\s*Status:\s*@@'`
$(basename $(basename $zipfile .rst) .md | sed -E 's@zip-0{0,3}@@') $(grep '^\s*Title:' $zipfile | sed -E 's@\s*Title:\s*@@') $(grep '^\s*Status:' $zipfile | sed -E 's@\s*Status:\s*@@') $(discussion $zipfile)
$(basename $(basename $zipfile .rst) .md | sed -E 's@zip-0{0,3}@@') $(grep '^\s*Title:' $zipfile | sed -E 's@\s*Title:\s*@@') $(grep '^\s*Status:' $zipfile | sed -E 's@\s*Status:\s*@@') $(discussion $zipfile)
" @@ -65,12 +75,12 @@ be deleted. .. raw:: html - + EndOfDraftHeader for draftfile in $(cat .draftfilelist.current); do - draftfile=zips/$draftfile - echo Adding $draftfile to index of drafts. >/dev/stderr - echo " " + draftfile="zips/$draftfile" + echo "Adding $draftfile to index of drafts." >/dev/stderr + echo " " done echo "
Title
Draft name Title Discussions-To
`grep '^\s*Title:' $draftfile | sed -E 's@\s*Title:\s*@@'`
$(basename $(basename $draftfile .rst) .md) $(grep '^\s*Title:' $draftfile | sed -E 's@\s*Title:\s*@@') $(discussion $draftfile)
" fi diff --git a/protocol/Makefile b/protocol/Makefile index 885396c7e..b68974ed6 100644 --- a/protocol/Makefile +++ b/protocol/Makefile @@ -20,27 +20,40 @@ PDFDIR=../rendered/protocol # Use EXTRAOPT=-pvc for "continuous preview" mode. For example, "make auxblossom EXTRAOPT=-pvc". # In this case the updated .pdf will be in the aux/ directory. -.PHONY: all protocol all-specs tag-release discard +.PHONY: all protocol protocol-dark all-pdfs all-specs discard all: .Makefile.uptodate - $(MAKE) $(PDFDIR)/protocol.pdf $(PDFDIR)/nu5.pdf $(PDFDIR)/canopy.pdf $(PDFDIR)/heartwood.pdf $(PDFDIR)/blossom.pdf $(PDFDIR)/sapling.pdf + # Make `all-pdfs` in CI only if anything under `protocol/` has changed. For local builds + # this does not need to be conditional, since each PDF will only be built if its dependencies + # have changed. However, when checking renderability of a PR in CI the `rendered/` directory + # will not exist, so the PDFs would always be built from scratch. This is quite slow, so we + # want to avoid it for PRs that have not changed anything under `protocol/`. + # + # For a build from the CI workflow, the base ref hash should be written to `../base_ref`. + # If that file does not exist (the expected case locally), we make `all-pdfs` unconditionally. + # If it contains a hash (the expected case for CI), we make `all-pdfs` if + # `git diff --name-only` shows changes relative to that base ref under `protocol/`. + # Finally, just in case we have `../base_ref` locally, we make `all-pdfs` if any status + # entry under `protocol/` is dirty, i.e. if its second status character is not " " + # (see the documentation for "Porcelain Format Version 1" in `git status --help`). + # + # Note that in Makefiles, a dollar sign must be doubled to get a literal dollar sign in *any* + # context. Be very careful if refactoring this to ensure that the contents of `../base_ref` + # are only expanded if they are a hash. + if ( /bin/true ) || \ + ( ! [ -e ../base_ref ] ) || \ + ( git diff --name-only "$$(grep -E '^[0-9a-f]{40}$$' ../base_ref).." -- |grep '^protocol/' ) || \ + ( git status --porcelain=v1 |grep '^.[^ ] protocol/' ); then \ + $(MAKE) all-pdfs; fi protocol: $(PDFDIR)/protocol.pdf +protocol-dark: $(PDFDIR)/protocol-dark.pdf + +all-pdfs: .Makefile.uptodate + $(MAKE) $(PDFDIR)/protocol.pdf $(PDFDIR)/protocol-dark.pdf $(PDFDIR)/nu6.pdf $(PDFDIR)/nu5.pdf $(PDFDIR)/canopy.pdf $(PDFDIR)/heartwood.pdf $(PDFDIR)/blossom.pdf $(PDFDIR)/sapling.pdf + all-specs: .Makefile.uptodate - $(MAKE) nu6 nu5 canopy heartwood blossom sapling - -tag-release: -ifeq ($(shell git tag --points-at HEAD |wc -l),0) - echo "Set a tag at HEAD first." -else - $(eval TAG := $(shell git tag --points-at HEAD)) - git fetch origin - git merge-base --is-ancestor origin/main HEAD || (echo "The current branch is dirty and/or not up-to-date with origin's main branch."; false) - $(MAKE) clean all - git add $(PDFDIR)/*.pdf - git commit -m "Regenerate PDFs." $(PDFDIR)/*.pdf - git tag "v$(TAG)" -endif + $(MAKE) nu6_1 nu6_1-dark nu6 nu5 canopy heartwood blossom sapling discard: git checkout -- "$(PDFDIR)/*.pdf" @@ -64,12 +77,18 @@ $(PDFDIR)/canopy.pdf: protocol.tex zcash.bib jubjub.png key_components_sapling.p $(PDFDIR)/nu5.pdf: protocol.tex zcash.bib jubjub.png key_components_sapling.png key_components_orchard.png incremental_merkle.png $(MAKE) nu5 -$(PDFDIR)/protocol.pdf: protocol.tex zcash.bib jubjub.png key_components_sapling.png key_components_orchard.png incremental_merkle.png +$(PDFDIR)/nu6.pdf: protocol.tex zcash.bib jubjub.png key_components_sapling.png key_components_orchard.png incremental_merkle.png $(MAKE) nu6 +$(PDFDIR)/protocol.pdf: protocol.tex zcash.bib jubjub.png key_components_sapling.png key_components_orchard.png incremental_merkle.png + $(MAKE) nu6_1 + +$(PDFDIR)/protocol-dark.pdf: protocol.tex zcash.bib jubjub.png key_components_sapling.png key_components_orchard_dark.png incremental_merkle_dark.png + $(MAKE) nu6_1-dark + .PHONY: auxsapling sapling auxsapling: - printf '\\toggletrue{issapling}\n\\renewcommand{\\docversion}{Version %s [\\SaplingSpec]}' "$$(git describe --tags --abbrev=6)" |tee protocol.ver + printf '\\toggletrue{issapling}\n\\renewcommand{\\docversion}{Version %s [\\SaplingSpec]}\n' "$$(git describe --tags --abbrev=6 |sed 's/-1-g.*//;s/-auto//')" |tee protocol.ver mkdir -p aux rm -f aux/sapling.* cp mymakeindex.sh aux @@ -77,11 +96,12 @@ auxsapling: sapling: $(MAKE) auxsapling + mkdir -p $(PDFDIR) mv -f aux/sapling.pdf $(PDFDIR) .PHONY: auxblossom blossom auxblossom: - printf '\\toggletrue{isblossom}\n\\renewcommand{\\docversion}{Version %s [\\BlossomSpec]}' "$$(git describe --tags --abbrev=6)" |tee protocol.ver + printf '\\toggletrue{isblossom}\n\\renewcommand{\\docversion}{Version %s [\\BlossomSpec]}\n' "$$(git describe --tags --abbrev=6 |sed 's/-1-g.*//;s/-auto//')" |tee protocol.ver mkdir -p aux rm -f aux/blossom.* cp mymakeindex.sh aux @@ -89,11 +109,12 @@ auxblossom: blossom: $(MAKE) auxblossom + mkdir -p $(PDFDIR) mv -f aux/blossom.pdf $(PDFDIR) .PHONY: auxheartwood heartwood auxheartwood: - printf '\\toggletrue{isheartwood}\n\\renewcommand{\\docversion}{Version %s [\\HeartwoodSpec]}' "$$(git describe --tags --abbrev=6)" |tee protocol.ver + printf '\\toggletrue{isheartwood}\n\\renewcommand{\\docversion}{Version %s [\\HeartwoodSpec]}\n' "$$(git describe --tags --abbrev=6 |sed 's/-1-g.*//;s/-auto//')" |tee protocol.ver mkdir -p aux rm -f aux/heartwood.* cp mymakeindex.sh aux @@ -101,11 +122,12 @@ auxheartwood: heartwood: $(MAKE) auxheartwood + mkdir -p $(PDFDIR) mv -f aux/heartwood.pdf $(PDFDIR) .PHONY: auxcanopy canopy auxcanopy: - printf '\\toggletrue{iscanopy}\n\\renewcommand{\\docversion}{Version %s [\\CanopySpec]}' "$$(git describe --tags --abbrev=6)" |tee protocol.ver + printf '\\toggletrue{iscanopy}\n\\renewcommand{\\docversion}{Version %s [\\CanopySpec]}\n' "$$(git describe --tags --abbrev=6 |sed 's/-1-g.*//;s/-auto//')" |tee protocol.ver mkdir -p aux rm -f aux/canopy.* cp mymakeindex.sh aux @@ -113,11 +135,12 @@ auxcanopy: canopy: $(MAKE) auxcanopy + mkdir -p $(PDFDIR) mv -f aux/canopy.pdf $(PDFDIR) .PHONY: auxnu5 nu5 auxnu5: - printf '\\toggletrue{isnufive}\n\\renewcommand{\\docversion}{Version %s [\\NUFiveSpec]}' "$$(git describe --tags --abbrev=6)" |tee protocol.ver + printf '\\toggletrue{isnufive}\n\\renewcommand{\\docversion}{Version %s [\\NUFiveSpec]}\n' "$$(git describe --tags --abbrev=6 |sed 's/-1-g.*//;s/-auto//')" |tee protocol.ver mkdir -p aux rm -f aux/nu5.* cp mymakeindex.sh aux @@ -125,11 +148,12 @@ auxnu5: nu5: $(MAKE) auxnu5 + mkdir -p $(PDFDIR) mv -f aux/nu5.pdf $(PDFDIR) .PHONY: auxnu6 nu6 auxnu6: - printf '\\toggletrue{isnusix}\n\\renewcommand{\\docversion}{Version %s [\\NUSixSpec]}' "$$(git describe --tags --abbrev=6)" |tee protocol.ver + printf '\\toggletrue{isnusix}\n\\renewcommand{\\docversion}{Version %s [\\NUSixSpec]}\n' "$$(git describe --tags --abbrev=6 |sed 's/-1-g.*//;;s/-auto//')" |tee protocol.ver mkdir -p aux rm -f aux/nu6.* cp mymakeindex.sh aux @@ -137,8 +161,35 @@ auxnu6: nu6: $(MAKE) auxnu6 - mv -f aux/nu6.pdf $(PDFDIR)/protocol.pdf + mkdir -p $(PDFDIR) + mv -f aux/nu6.pdf $(PDFDIR) + +.PHONY: auxnu6_1 nu6_1 +auxnu6_1: + printf '\\toggletrue{isnusixone}\n\\renewcommand{\\docversion}{Version %s [\\NUSixOneSpec]}\n' "$$(git describe --tags --abbrev=6 |sed 's/-1-g.*//;s/-auto//')" |tee protocol.ver + mkdir -p aux + rm -f aux/nu6_1.* + cp mymakeindex.sh aux + $(LATEXMK) -jobname=nu6_1 -auxdir=aux -outdir=aux $(EXTRAOPT) protocol $(NOCRUFT) + +nu6_1: + $(MAKE) auxnu6_1 + mkdir -p $(PDFDIR) + mv -f aux/nu6_1.pdf $(PDFDIR)/protocol.pdf + +.PHONY: auxnu6_1-dark nu6_1-dark +auxnu6_1-dark: + printf '\\toggletrue{darkmode}\\toggletrue{isnusixone}\n\\renewcommand{\\docversion}{Version %s [\\NUSixOneSpec]}\n' "$$(git describe --tags --abbrev=6 |sed 's/-1-g.*//;s/-auto//')" |tee protocol.ver + mkdir -p aux + rm -f aux/nu6_1-dark.* + cp mymakeindex.sh aux + $(LATEXMK) -jobname=nu6_1-dark -auxdir=aux -outdir=aux $(EXTRAOPT) protocol $(NOCRUFT) + +nu6_1-dark: + $(MAKE) auxnu6_1-dark + mkdir -p $(PDFDIR) + mv -f aux/nu6_1-dark.pdf $(PDFDIR)/protocol-dark.pdf .PHONY: clean clean: - rm -f aux/* protocol.ver $(PDFDIR)/protocol.pdf $(PDFDIR)/nu5.pdf $(PDFDIR)/canopy.pdf $(PDFDIR)/heartwood.pdf $(PDFDIR)/blossom.pdf $(PDFDIR)/sapling.pdf + rm -f aux/* protocol.ver $(PDFDIR)/* 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/incremental_merkle_dark.png b/protocol/incremental_merkle_dark.png new file mode 100644 index 000000000..4c6a9d3f2 Binary files /dev/null and b/protocol/incremental_merkle_dark.png differ diff --git a/protocol/incremental_merkle_dark.svg b/protocol/incremental_merkle_dark.svg new file mode 100644 index 000000000..d1c7cc09c --- /dev/null +++ b/protocol/incremental_merkle_dark.svg @@ -0,0 +1,1725 @@ + +image/svg+xml + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + rt + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +? +? +cm +0 +cm +1 +cm +2 +cm +3 +cm +4 + diff --git a/protocol/key_components_orchard.png b/protocol/key_components_orchard.png index abf007513..be743e60b 100644 Binary files a/protocol/key_components_orchard.png and b/protocol/key_components_orchard.png differ diff --git a/protocol/key_components_orchard.svg b/protocol/key_components_orchard.svg index c9ca53a9c..78060e584 100644 --- a/protocol/key_components_orchard.svg +++ b/protocol/key_components_orchard.svg @@ -1,21 +1,21 @@ + inkscape:export-ydpi="180" + xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape" + xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd" + xmlns="http://www.w3.org/2000/svg" + xmlns:svg="http://www.w3.org/2000/svg" + xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#" + xmlns:cc="http://creativecommons.org/ns#" + xmlns:dc="http://purl.org/dc/elements/1.1/"> + inkscape:document-rotation="0" + inkscape:showpageshadow="2" + inkscape:pagecheckerboard="0" + inkscape:deskcolor="#d1d1d1" /> + + + @@ -2008,6 +2024,28 @@ y="633.52753" style="font-style:normal;font-variant:normal;font-weight:normal;font-stretch:normal;font-size:17.3333px;font-family:Sans;-inkscape-font-specification:Sans">index + + diff --git a/protocol/key_components_orchard_dark.png b/protocol/key_components_orchard_dark.png new file mode 100644 index 000000000..e758dbd6e Binary files /dev/null and b/protocol/key_components_orchard_dark.png differ diff --git a/protocol/key_components_orchard_dark.svg b/protocol/key_components_orchard_dark.svg new file mode 100644 index 000000000..239cf1f5f --- /dev/null +++ b/protocol/key_components_orchard_dark.svg @@ -0,0 +1,2263 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + image/svg+xml + + + + + + + + ivk + dk + + + + + ovk + + + + + a + pk + pk + enc + + + + + a + sk + + + + + a + pk + enc + sk + + + + d + pk + d + + + + + + ivk + + + + + ak + nk + + + + nsk + ak + + + + sk + + + + ask + nsk + + + ovk + + + d + pk + d + + + + + ovk + + + + + ask + + + + + sk + + + + ak + nk + rivk + + Paying key + Spending key + Shielded payment address + Receivingkey + Incomingviewing key + Transmissionkey + Diversifier + Shielded payment address + Fullviewing key + Incomingviewing key + Spending key + Proof author-izing key + Expandedspending key + Transmissionkey + Transmissionkey + Diversifier + Shielded payment address + Fullviewing key + Orchard + Spending key + Outgoingviewing key + Outgoingviewing key + Sapling + Sprout + index + Incomingviewing key + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/protocol/protocol.tex b/protocol/protocol.tex index dd5c473fe..76371e474 100644 --- a/protocol/protocol.tex +++ b/protocol/protocol.tex @@ -39,6 +39,7 @@ \usepackage[hang]{footmisc} \usepackage{xstring} \usepackage[dvipsnames]{xcolor} +\usepackage{pagecolor} \usepackage{etoolbox} \usepackage{subdepth} \usepackage{fix-cm} @@ -62,12 +63,52 @@ % Shortcut for \nohyphens from hyphenat. \newcommand{\nh}[1]{\nohyphens{#1}} +\hyphenation{describes} + % \nh doesn't work in the bibliography. % \makeatletter \newcommand*\nbh{\hbox{-}\nobreak\hskip\z@skip} \makeatother + +% Load version-specific properties from protocol.ver +\newcommand{\docversion}{Version unavailable (check protocol.ver)} +\newcommand{\SaplingSpec}{Overwinter+Sapling} +\newcommand{\BlossomSpec}{Overwinter+Sapling+Blossom} +\newcommand{\HeartwoodSpec}{Overwinter+Sapling+Blossom+Heartwood} +\newcommand{\CanopySpec}{Overwinter+Sapling+Blossom+Heartwood+Canopy} +\newcommand{\NUFiveSpec}{NU5} +\newcommand{\NUSixSpec}{NU6} +\newcommand{\NUSixOneSpec}{NU6.1} +\newtoggle{issapling} +\togglefalse{issapling} +\newtoggle{isblossom} +\togglefalse{isblossom} +\newtoggle{isheartwood} +\togglefalse{isheartwood} +\newtoggle{iscanopy} +\togglefalse{iscanopy} +\newtoggle{isnufive} +\togglefalse{isnufive} +\newtoggle{isnusix} +\togglefalse{isnusix} +\newtoggle{isnusixone} +\togglefalse{isnusixone} +\newtoggle{darkmode} +\togglefalse{darkmode} +\InputIfFileExists{protocol.ver}{}{} + +\iftoggle{darkmode}{ + \colorlet{crossrefblue}{MidnightBlue} + \colorlet{citationpurple}{red!60!blue!95} + \colorlet{linkred}{black!25!BrickRed} +}{ + \colorlet{crossrefblue}{MidnightBlue} + \colorlet{citationpurple}{Plum} + \colorlet{linkred}{BrickRed} +} + % The destlabel option creates "destination names" in the PDF, which allows % linking to sections in URL fragments when viewing the PDF in a web browser: % @@ -83,8 +124,9 @@ % To preserve destination names through Ghostscript processing, extractpdfmark % would need to be used as described at . % -\usepackage[unicode,bookmarksnumbered,bookmarksopen,allbordercolors=MidnightBlue, - citebordercolor=Plum,urlbordercolor=BrickRed,pdfa,destlabel]{hyperref} +\usepackage[unicode,bookmarksnumbered,bookmarksopen, + allbordercolors=crossrefblue,citebordercolor=citationpurple,urlbordercolor=linkred, + pdfa,destlabel]{hyperref} \usepackage[amsmath,amsthm,thmmarks,hyperref]{ntheorem} @@ -201,7 +243,7 @@ \renewcommand{\cftsubsubsecpagefont}{\pagenumfont} \renewcommand{\cftparapagefont}{\pagenumfont} -\hfuzz=3.5pt +\hfuzz=3.8pt \vfuzz=2pt \overfullrule=2cm @@ -295,7 +337,7 @@ \newcommand{\refprefix}{\readas{section}{\linkstrut\S\!\!}} \newcommand{\page}{\readas{page}{p.}\,} -\newcommand{\crossref}[1]{\raisebox{0ex}{\refprefix\autoref{#1}}\hspace{0.2em}\emph{`\nameref*{#1}\kern -0.05em'} on \page\pageref*{#1}} +\newcommand{\crossref}[1]{\raisebox{0ex}{\refprefix\autoref{#1}}\hspace{0.25em}\emph{`\nameref*{#1}\kern -0.05em'} on \page\pageref*{#1}} \newcommand{\shortcrossref}[1]{\raisebox{0ex}{\refprefix\autoref{#1}} on \page\pageref*{#1}} \newcommand{\theoremref}[1]{\raisebox{0ex}{\hyperref[#1]{Theorem \ref*{#1}\vphantom{,}}} on \page\pageref*{#1}} \newcommand{\lemmaref}[1]{\raisebox{0ex}{\hyperref[#1]{Lemma \ref*{#1}\vphantom{,}}} on \page\pageref*{#1}} @@ -392,13 +434,11 @@ % Using the astral plane character 𝕊 works, but triggers bugs in PDF readers 😛 \newcommand{\rS}{\texorpdfstring{$\ParamS{r}$}{rS}} -% -\DeclareFontFamily{U}{FdSymbolA}{} -\DeclareFontShape{U}{FdSymbolA}{m}{n}{ - <-> s*[.4] FdSymbolA-Regular -}{} -\DeclareSymbolFont{fdsymbol}{U}{FdSymbolA}{m}{n} -\DeclareMathSymbol{\smallcirc}{\mathord}{fdsymbol}{"60} +\newcommand{\smallcirc}{% + \begin{picture}(2,2) + \linethickness{0.4pt} + \put(1,1){\circle{1.2}} + \end{picture}} \makeatletter \newcommand{\hollowcolon}{\mathpalette\hollow@colon\relax} @@ -546,27 +586,6 @@ \newcommand{\sbitbox}[2]{\bitbox{#1}{\strut #2}} -\newcommand{\docversion}{Version unavailable (check protocol.ver)} -\newcommand{\SaplingSpec}{Overwinter+Sapling} -\newcommand{\BlossomSpec}{Overwinter+Sapling+Blossom} -\newcommand{\HeartwoodSpec}{Overwinter+Sapling+Blossom+Heartwood} -\newcommand{\CanopySpec}{Overwinter+Sapling+Blossom+Heartwood+Canopy} -\newcommand{\NUFiveSpec}{NU5} -\newcommand{\NUSixSpec}{NU6} -\newtoggle{issapling} -\togglefalse{issapling} -\newtoggle{isblossom} -\togglefalse{isblossom} -\newtoggle{isheartwood} -\togglefalse{isheartwood} -\newtoggle{iscanopy} -\togglefalse{iscanopy} -\newtoggle{isnufive} -\togglefalse{isnufive} -\newtoggle{isnusix} -\togglefalse{isnusix} -\InputIfFileExists{protocol.ver}{}{} - \newcommand{\doctitle}{Zcash Protocol Specification} \newcommand{\leadauthor}{Daira-Emma Hopwood} \newcommand{\coauthora}{Sean Bowe} @@ -577,32 +596,86 @@ electronic commerce and payment, financial privacy, proof of work, zero knowledge} +% Colors % -\newcommand{\todo}[1]{{\color{Sepia}\sf{TODO: #1}}} -\definecolor{green}{RGB}{0,100,10} +\iftoggle{darkmode}{ + % The colors need to be adjusted to maintain a comfortable contrast, saturation, + % and brightness in dark mode. + \definecolor{darkpage}{RGB}{30,30,30} + \definecolor{lighttext}{RGB}{220,220,220} + \definecolor{red}{RGB}{215,20,20} + \definecolor{green}{RGB}{10,175,20} + \definecolor{blue}{RGB}{65,65,245} + \definecolor{slateblue}{RGB}{102,142,194} + \colorlet{reddishorange}{red!30!orange} + \definecolor{purple}{RGB}{157,68,150} + \colorlet{pink}{magenta!70} + \definecolor{burgundy}{RGB}{210,20,80} + \definecolor{brown}{RGB}{160,50,50} + \colorlet{warningred}{BrickRed} + \colorlet{cream}{yellow!20} + + \pagecolor{darkpage} + \color{lighttext} + \newcommand{\imagesuffix}{_dark} +}{ + \definecolor{green}{RGB}{0,100,10} + \colorlet{slateblue}{black!25!blue!65!green!65} + \colorlet{reddishorange}{red!30!orange} + \colorlet{purple}{red!50!blue!85} + \colorlet{pink}{magenta!75} + \definecolor{burgundy}{RGB}{200,18,75} + \colorlet{brown}{Sepia} + \colorlet{warningred}{BrickRed} + \colorlet{cream}{yellow!20} + + \newcommand{\imagesuffix}{} +} -\newcommand{\vulncolor}{BrickRed} +\newcommand{\todo}[1]{{\color{brown}\sf{TODO: #1}}} + +\newcommand{\vulncolor}{warningred} \newcommand{\setwarning}{\color{\warningcolor}} -\newcommand{\warningcolor}{BrickRed} +\newcommand{\warningcolor}{warningred} \newcommand{\saplingcolor}{green} \newcommand{\saplingcolorname}{\saplingcolor} \newcommand{\overwintercolor}{blue} -\newcommand{\overwintercolorname}{\overwintercolor} +\newcommand{\overwintercolorname}{bright blue} \newcommand{\blossomcolor}{red} \newcommand{\blossomcolorname}{\blossomcolor} -\newcommand{\heartwoodcolor}{red!30!orange} +\newcommand{\heartwoodcolor}{reddishorange} \newcommand{\heartwoodcolorname}{orange} -\newcommand{\canopycolor}{red!50!blue!85} -\newcommand{\canopycolorname}{purple} -\newcommand{\nufivecolor}{black!25!blue!65!green!65} +\newcommand{\canopycolor}{purple} +\newcommand{\canopycolorname}{\canopycolor} +\newcommand{\nufivecolor}{slateblue} \newcommand{\nufivecolorname}{slate blue} -\newcommand{\nusixcolor}{magenta!75} -\newcommand{\nusixcolorname}{pink} -\newcommand{\labelcolor}{yellow!20} +\newcommand{\nusixcolor}{pink} +\newcommand{\nusixcolorname}{\nusixcolor} +\newcommand{\nusixonecolor}{burgundy} +\newcommand{\nusixonecolorname}{\nusixonecolor} +\newcommand{\labelcolor}{cream} + +\iftoggle{isnusixone}{ + \iftoggle{darkmode}{ + \providecommand{\baseurl}{https://zips.z.cash/protocol/protocol-dark.pdf} + }{ + \providecommand{\baseurl}{https://zips.z.cash/protocol/protocol.pdf} + } + \toggletrue{isnusix} + \newcommand{\setnusixone}{\color{\nusixonecolor}} + \newcommand{\nusixone}[1]{\texorpdfstring{{\setnusixone{#1}}}{#1}} + \newcommand{\notnusixone}[1]{} + \newcommand{\notbeforenusixone}[1]{#1} +} { + \newcommand{\setnusixone}{} + \newcommand{\nusixone}[1]{} + \newcommand{\notnusixone}[1]{#1} + \newcommand{\notbeforenusixone}[1]{} +} \iftoggle{isnusix}{ - \providecommand{\baseurl}{https://zips.z.cash/protocol/protocol.pdf} + \providecommand{\baseurl}{https://zips.z.cash/protocol/nu6.pdf} \toggletrue{isnufive} \newcommand{\setnusix}{\color{\nusixcolor}} \newcommand{\nusix}[1]{\texorpdfstring{{\setnusix{#1}}}{#1}} @@ -749,8 +822,12 @@ \newcommand{\Blossom}{\termbf{Blossom}} \newcommand{\Heartwood}{\termbf{Heartwood}} \newcommand{\Canopy}{\termbf{Canopy}} +% "NU5" \newcommand{\NUFive}{\readasunicode{004e200b0055200b0035}{\termbf{NU5}}\xspace} +% "NU6" \newcommand{\NUSix}{\readasunicode{004e200b0055200b0036}{\termbf{NU6}}\xspace} +% "NU6.1" +\newcommand{\NUSixOne}{\readasunicode{004e200b0055200b0036002e0031}{\termbf{NU6.1}}\xspace} \newcommand{\Orchard}{\termbf{Orchard}} \newcommand{\OrchardText}{\textbf{Orchard}} \newcommand{\SaplingOrOrchard}{\Sapling{}\nufive{ or \Orchard{}}\xspace} @@ -805,10 +882,11 @@ \newcommand{\primeOrderCurve}{\term{prime-order curve}} \newcommand{\primeOrderCurves}{\terms{prime-order curve}} \newcommand{\hashToCurve}{\term{hash-to-curve}} -\newcommand{\xDiscreteLogarithmProblem}{\term{Discrete Logarithm Problem}} -\newcommand{\xDiscreteLogarithm}{\termandindex{Discrete Logarithm}{Discrete Logarithm Problem}} -\newcommand{\xDecisionalDiffieHellmanProblem}{\term{Decisional Diffie--Hellman Problem}} -\newcommand{\xDecisionalDiffieHellman}{\termandindex{Decisional Diffie--Hellman}{Decisional Diffie--Hellman Problem}} +\newcommand{\discreteLogarithm}{\term{discrete logarithm}} +\newcommand{\DiscreteLogarithmProblem}{\term{Discrete Logarithm Problem}} +\newcommand{\DiscreteLogarithmIndependence}{\term{Discrete Logarithm Independence}} +\newcommand{\DecisionalDiffieHellmanProblem}{\term{Decisional Diffie--Hellman Problem}} +\newcommand{\DecisionalDiffieHellmanAssumption}{\termandindex{Decisional Diffie--Hellman assumption}{Decisional Diffie--Hellman Problem}} \newcommand{\partitioningOracleAttack}{\term{partitioning oracle attack}} \newcommand{\partitioningOracleAttacks}{\terms{partitioning oracle attack}} \newcommand{\sideChannel}{\term{side-channel}} @@ -897,6 +975,8 @@ \newcommand{\shieldedSpends}{\terms{shielded Spend}} \newcommand{\shieldedInput}{\term{shielded input}} \newcommand{\shieldedInputs}{\terms{shielded input}} +\newcommand{\shieldedProtocol}{\term{shielded protocol}} +\newcommand{\shieldedProtocols}{\terms{shielded protocol}} \newcommand{\spendDescription}{\term{Spend description}} \newcommand{\spendDescriptions}{\terms{Spend description}} \newcommand{\spendTransfer}{\term{Spend transfer}} @@ -1128,6 +1208,9 @@ \newcommand{\chainValuePool}{\term{chain value pool}} \newcommand{\chainValuePools}{\terms{chain value pool}} \newcommand{\deferredChainValuePool}{\term{deferred development fund chain value pool}} +\newcommand{\deferredDevFundLockbox}{\term{deferred development fund lockbox}} +\newcommand{\lockboxDisbursement}{\term{lockbox disbursement}} +\newcommand{\lockboxDisbursements}{\terms{lockbox disbursement}} \newcommand{\totalIssuedSupply}{\term{total issued supply}} \newcommand{\totalOutputValue}{\term{total output value}} \newcommand{\totalInputValue}{\term{total input value}} @@ -1162,6 +1245,7 @@ \newcommand{\unifiedIncomingViewingKeys}{\terms{unified incoming viewing key}} \newcommand{\unifiedFullViewingKey}{\term{unified full viewing key}} \newcommand{\unifiedFullViewingKeys}{\terms{unified full viewing key}} +\newcommand{\IVKEncoding}{\termandindex{IVK Encoding}{IVK Encoding (in a Unified Incoming Viewing Key)}} \newcommand{\Bech}{\term{Bech32}} \newcommand{\Bechm}{\term{Bech32m}} \newcommand{\BechOptm}{\termandindex{Bech32[m]}{Bech32m}} @@ -1502,7 +1586,7 @@ \newcommand{\PaymentAddressSecondByte}{\hexint{9A}} \newcommand{\InViewingKey}{\mathsf{ivk}} \newcommand{\InViewingKeyLength}[1]{\ell^\mathsf{#1\vphantom{p}}_{\InViewingKey}\!} -\newcommand{\InViewingKeyTypeSapling}{\binaryrange{\InViewingKeyLength{Sapling}}} +\newcommand{\InViewingKeyTypeSapling}{\range{1}{2^{\InViewingKeyLength{Sapling}}\!-\!1}} \newcommand{\InViewingKeyTypeOrchard}{\range{1}{\ParamP{q}-1}} \newcommand{\InViewingKeyRepr}{{\InViewingKey\Repr}} \newcommand{\InViewingKeyLeadByte}{\hexint{A8}} @@ -1526,6 +1610,8 @@ \newcommand{\PtoPKHAddressTestnetLeadByte}{\hexint{1D}} \newcommand{\PtoPKHAddressTestnetSecondByte}{\hexint{25}} \newcommand{\NotePlaintextLeadByte}{\mathsf{leadByte}} +\newcommand{\TxVersion}{\mathsf{txVersion}} +\newcommand{\AllowedLeadBytes}{\mathsf{allowedLeadBytes}} \newcommand{\AuthPublic}{\mathsf{a_{pk}}} \newcommand{\AuthPublicSub}[1]{\mathsf{a_{pk,\mathnormal{#1}}}} \newcommand{\AuthPrivate}{\mathsf{a_{sk}}} @@ -1562,6 +1648,9 @@ % Sapling and Orchard +\newcommand{\Protocol}{\mathsf{protocol}} +\newcommand{\SaplingProto}{\mathsf{Sapling}} +\newcommand{\OrchardProto}{\mathsf{Orchard}} \newcommand{\Internal}[1]{{#1}_{\mathsf{internal}}} \newcommand{\SpendingKey}{\mathsf{sk}} \newcommand{\SpendingKeyLength}{\mathsf{\ell_{\SpendingKey}}} @@ -1579,11 +1668,11 @@ \newcommand{\AuthSignRandomizerRepr}{{\AuthSignRandomizer\Repr}} \newcommand{\AuthProvePrivate}{\mathsf{nsk}} \newcommand{\AuthProvePrivateRepr}{{\AuthProvePrivate\Repr}} -\newcommand{\AuthProveBaseSapling}{\mathcal{H}^\mathsf{Sapling}} +\newcommand{\AuthProveBaseSapling}{\mathcal{H}^\SaplingProto} \newcommand{\NullifierKey}{\mathsf{nk}} \newcommand{\NullifierKeyRepr}{{\NullifierKey\Repr}} \newcommand{\NullifierKeyTypeOrchard}{\GF{\ParamP{q}}} -\newcommand{\NullifierBaseOrchard}{\mathcal{K}^\mathsf{Orchard}} +\newcommand{\NullifierBaseOrchard}{\mathcal{K}^\OrchardProto} \newcommand{\NullifierTypeOrchard}{\GF{\ParamP{q}}} \newcommand{\OutViewingKey}{\mathsf{ovk}} \newcommand{\OutViewingKeyLength}{\mathsf{\ell_{\OutViewingKey}}} @@ -1591,7 +1680,7 @@ \newcommand{\OutCipherKey}{\mathsf{ock}} \newcommand{\NotePosition}{\mathsf{pos}} \newcommand{\NotePositionRepr}{{\NotePosition\Repr}} -\newcommand{\NotePositionBaseSapling}{\mathcal{J}^\mathsf{Sapling}} +\newcommand{\NotePositionBaseSapling}{\mathcal{J}^\SaplingProto} \newcommand{\NotePositionType}[1]{\binaryrange{\MerkleDepth{#1}}} \newcommand{\Diversifier}{\mathsf{d}} \newcommand{\DiversifierLength}{\mathsf{\ell_{\Diversifier}}} @@ -1602,6 +1691,7 @@ \newcommand{\DiversifierIndex}{\mathsf{index}} \newcommand{\FVK}{\mathsf{FVK}} \newcommand{\DeriveInternalFVKOrchard}{\mathsf{DeriveInternalFVK^{Orchard}}} +\newcommand{\DeriveDkAndOvkOrchard}{\mathsf{DeriveDkAndOvk^{Orchard}}} \newcommand{\DiversifiedTransmitBase}{\mathsf{g_d}} \newcommand{\DiversifiedTransmitBaseRepr}{\mathsf{g\Repr_d}} \newcommand{\DiversifiedTransmitBaseOld}{\mathsf{g^{old}_d}} @@ -1710,7 +1800,7 @@ \newcommand{\KA}[1]{\mathsf{KA}^\mathsf{#1\kern-0.1em}} \newcommand{\KAPublic}[1]{\KA{#1}\mathsf{.Public}} -\newcommand{\KAPublicPrimeSubgroup}[1]{\KA{#1}\mathsf{.PublicPrimeSubgroup}} +\newcommand{\KAPublicPrimeOrder}[1]{\KA{#1}\mathsf{.PublicPrimeOrder}} \newcommand{\KAPrivate}[1]{\KA{#1}\mathsf{.Private}} \newcommand{\KASharedSecret}[1]{\KA{#1}\mathsf{.SharedSecret}} \newcommand{\KAFormatPrivate}[1]{\KA{#1}\mathsf{.FormatPrivate}} @@ -1759,7 +1849,6 @@ \newcommand{\NoteCommitRandLengthSprout}{\mathsf{\ell^{Sprout}_{\NoteCommitRand}}} \newcommand{\NoteCommitRandOld}[1]{\NoteCommitRand^\mathsf{old}_{#1}} \newcommand{\NoteCommitRandNew}[1]{\NoteCommitRand^\mathsf{new}_{#1}} -\newcommand{\NoteCommitRandOrSeedBytes}{\notcanopy{\NoteCommitRand}\canopy{\NoteSeedBytes}} \newcommand{\NoteCommitRandBytesOrSeedBytes}{\notcanopy{\NoteCommitRandBytes}\canopy{\NoteSeedBytes}} \newcommand{\NoteCommitRandPre}{\mathsf{pre\_rcm}} \newcommand{\NoteUniqueRand}{\mathsf{\uprho}} @@ -1799,7 +1888,7 @@ \newcommand{\Memo}{\mathsf{memo}} \newcommand{\MemoByteLength}{512} \newcommand{\MemoType}{\byteseq{\MemoByteLength}} -\newcommand{\DecryptNoteSprout}{\mathtt{DecryptNoteSprout}} +\newcommand{\ExtractNote}[1]{\mathsf{ExtractNote^{#1}}} \newcommand{\ReplacementCharacter}{\textsf{U+FFFD}} \newcommand{\maybeSapling}{\notnufive{Sapling}} @@ -1860,13 +1949,18 @@ \newcommand{\utxosFull}{\termandindex{UTXOs (unspent transaction outputs)}{UTXO (unspent transaction output)}} \newcommand{\fundingStream}{\term{funding stream}} \newcommand{\fundingStreams}{\terms{funding stream}} -\newcommand{\prescribedWay}{\termandindex{prescribed way}{prescribed way (to pay a funding stream recipient)}} +\newcommand{\quotedPrescribedWay}{\quotedtermandindex{prescribed way}{prescribed way (to pay a funding recipient)}} +\newcommand{\prescribedWay}{\termandindex{prescribed way}{prescribed way (to pay a funding recipient)}} \newcommand{\BlossomActivationHeight}{\mathsf{BlossomActivationHeight}} \newcommand{\IsBlossomActivated}{\mathsf{IsBlossomActivated}} \newcommand{\CanopyActivationHeight}{\mathsf{CanopyActivationHeight}} \newcommand{\NUFiveActivationHeight}{\mathsf{NUFiveActivationHeight}} \newcommand{\ZIPTwoOneTwoGracePeriod}{\mathsf{ZIP212GracePeriod}} +\newcommand{\ZIPTwoSevenOneActivationHeight}{\mathsf{ZIP271ActivationHeight}} +\newcommand{\ZIPTwoSevenOneDisbursementAmount}{\mathsf{ZIP271DisbursementAmount}} +\newcommand{\ZIPTwoSevenOneDisbursementChunks}{\mathsf{ZIP271DisbursementChunks}} +\newcommand{\ZIPTwoSevenOneDisbursementAddress}{\mathsf{ZIP271DisbursementAddress}} \newcommand{\PoWLimit}{\mathsf{PoWLimit}} \newcommand{\PoWAveragingWindow}{\mathsf{PoWAveragingWindow}} @@ -2021,6 +2115,7 @@ \newcommand{\vBad}{\mathsf{v^{bad}}} \newcommand{\vSum}{\mathsf{v^{*}}} \newcommand{\totalDeferredOutput}{\mathsf{totalDeferredOutput}} +\newcommand{\totalDeferredInput}{\mathsf{totalDeferredInput}} \newcommand{\DeferredPool}{\mathsf{DEFERRED\_POOL}} \newcommand{\OracleNewAddress}{\Oracle^{\mathsf{NewAddress}}} \newcommand{\OracleDH}{\Oracle^{\mathsf{DH}}} @@ -2494,8 +2589,11 @@ \newcommand{\consensusrule}[1]{\needspace{4ex}\vspace{2ex}\callout{}{Consensus rule:}{#1}} \newenvironment{consensusrules}{\introlist\callout{}{Consensus rules:}\begin{itemize}}{\end{itemize}} +\newcommand{\prenusixoneitem}[1]{\item \prenusixone{#1}} +\newcommand{\nusixoneonlyitem}[1]{\nusixone{\item {[\NUSixOne only]}\, {#1}}} +\newcommand{\nusixoneonwarditem}[1]{\nusixone{\item {[\NUSixOne onward]}\, {#1}}} \newcommand{\prenusixitem}[1]{\item \prenusix{#1}} -\newcommand{\nusixonlyitem}[1]{\nusix{\item {[\NUSix only]}\, {#1}}} +\newcommand{\nusixonlyitem}[1]{\nusix{\item {[\NUSix only\notbeforenusixone{, pre-\NUSixOne}]}\, {#1}}} \newcommand{\nusixonwarditem}[1]{\nusix{\item {[\NUSix onward]}\, {#1}}} \newcommand{\prenufiveitem}[1]{\item \prenufive{#1}} \newcommand{\nufiveonlyitem}[1]{\nufive{\item {[\NUFive only\notbeforenusix{, pre-\NUSix}]}\, {#1}}} @@ -2521,6 +2619,9 @@ \newcommand{\overwinterprenufiveitem}[1]{\overwinter{\item \overwinterprenufive{#1}}} \newcommand{\sproutspecificitem}[1]{\item \sproutspecific{#1}} +\newcommand{\prenusixone}[1]{\notbeforenusixone{\nusixone{[Pre-\NUSixOne\!]\,}} {#1}} +\newcommand{\nusixoneonly}[1]{\nusixone{[\NUSixOne only]\, {#1}}} +\newcommand{\nusixoneonward}[1]{\nusixone{[\NUSixOne onward]\, {#1}}} \newcommand{\prenusix}[1]{\notbeforenusix{\nusix{[Pre-\NUSix\!]\,}} {#1}} \newcommand{\nusixonly}[1]{\nusix{[\NUSix only]\, {#1}}} \newcommand{\nusixonward}[1]{\nusix{[\NUSix onward]\, {#1}}} @@ -2556,6 +2657,8 @@ \newcommand{\nnote}[1]{\needspace{4ex}\vspace{2ex}\callout{}{Non-normative note:}{#1}} \newenvironment{nnotes}{\introlist\callout{}{Non-normative notes:}\begin{itemize}}{\end{itemize}} +\newcommand{\nusixoneonwardnnote}[1]{\nusixone{\callout{[\NUSixOne onward]\,\,}{Non-normative note:}{#1}}} +\newcommand{\nusixoneonwardpnote}[1]{\nusixone{\callout{[\NUSixOne onward]\,\,}{Note:}{#1}}} \newcommand{\nusixonwardnnote}[1]{\nusix{\callout{[\NUSix onward]\,\,}{Non-normative note:}{#1}}} \newcommand{\nusixonwardpnote}[1]{\nusix{\callout{[\NUSix onward]\,\,}{Note:}{#1}}} \newcommand{\nufiveonwardnnote}[1]{\nufive{\callout{[\NUFive onward]\,\,}{Non-normative note:}{#1}}} @@ -2605,14 +2708,14 @@ memory-hard \proofOfWork algorithm. \vspace{1.5ex} -\newcommand{\thisspecdefines}[1]{This specification defines the \Zcash consensus protocol at launch, and after each of the upgrades codenamed {#1}.} +\newcommand{\thisspecdefines}[1]{This specification defines the \Zcash consensus protocol at launch, and after each of the upgrades codenamed {#1}. } \noindent \notblossom{\sapling{\thisspecdefines{\Overwinter and \Sapling}}}% \notheartwood{\blossom{\thisspecdefines{\Overwinter, \Sapling, and \Blossom}}}% \notcanopy{\heartwood{\thisspecdefines{\Overwinter, \Sapling, \Blossom, and \Heartwood}}}% \notnufive{\canopy{\thisspecdefines{\Overwinter, \Sapling, \Blossom, \Heartwood, and \Canopy}}}% \notnusix{\nufive{\thisspecdefines{\Overwinter, \Sapling, \Blossom, \Heartwood, \Canopy, and \NUFive}}}% -\nusix{This specification defines the \Zcash consensus protocol at launch; after each of the upgrades -codenamed \Overwinter, \Sapling, \Blossom, \Heartwood, \Canopy, and \NUFive; and proposed changes for \NUSix.} % +\notnusixone{\nusix{\thisspecdefines{\Overwinter, \Sapling, \Blossom, \Heartwood, \Canopy, \NUFive, and \NUSix}}}% +\nusixone{\thisspecdefines{\Overwinter, \Sapling, \Blossom, \Heartwood, \Canopy, \NUFive, \NUSix, and \NUSixOne}}% It is a work in progress. Protocol differences from \Zerocash and \Bitcoin are also explained. \vspace{2ex} @@ -2683,12 +2786,15 @@ \notbeforenufive{Changes specific to the \NUFive upgrade following \Canopy are highlighted in \nufive{\nufivecolorname}.} -\notbeforenusix{Changes specific to the proposed \NUSix upgrade following \NUFive +\notbeforenusix{Changes specific to the \NUSix upgrade following \NUFive are highlighted in \nusix{\nusixcolorname}.} +\notbeforenusixone{Changes specific to the \NUSixOne upgrade following \NUSix +are highlighted in \nusixone{\nusixonecolorname}.} + All of these are also changes from \Zerocash. -The name \Sprout is used for the \Zcash protocol prior to \Sapling -(both before and after \Overwinter), and in particular its shielded protocol. + +The name \Sprout is used for the \shieldedProtocol defined prior to the \Sapling upgrade. \vspace{1ex} \introlist @@ -2783,9 +2889,11 @@ In each \shieldedTransfer, the \nullifiers of the input \notes are revealed (preventing them from being spent again) and the commitments of the output \notes are revealed -(allowing them to be spent in future). A \transaction also includes computationally sound -\zkSNARK proofs and signatures, which prove that all of the following hold except -with insignificant probability: +(allowing them to be spent in future). + +\introlist +A \transaction also includes computationally sound \zkSNARK proofs and signatures, +which prove that all of the following hold except with insignificant probability: For each \shieldedInput, @@ -3096,23 +3204,24 @@ abstractions. \readas{Image description: three diagrams showing the derivation of Sprout, Sapling, and Orchard key components. -The key components are shown by their mathematical abbreviations. They are collected into ovals for each named -abstraction, which are colour-coded from purple to green in the direction of derivation, or from more-secret to -less-secret values. The information in the diagram is otherwise mostly redundant with the textual description -of the key components and their derivation that follows it.}{\begin{center} +The key components are shown by their mathematical abbreviations. They are collected into rounded boxes for each named +abstraction, which are colour-coded from purple to green in the direction of derivation, or from more secret to +less secret values. The information in the diagram is otherwise mostly redundant with the textual description +of the key components and their derivation that follows it.}{\vspace{-2ex}\begin{center} \notnufive{\includegraphics[scale=.5]{key_components_sapling}} -\nufive{\includegraphics[scale=.385]{key_components_orchard}} +\nufive{\includegraphics[scale=.385]{key_components_orchard\imagesuffix}} \end{center}} \sproutspecific{ -\defining{The \receivingKey $\TransmitPrivate$, \incomingViewingKey +\defining{A \Sprout \receivingKey $\TransmitPrivate$, \incomingViewingKey $\InViewingKey = (\AuthPublic, \TransmitPrivate)$, and \shieldedPaymentAddress $\PaymentAddress = (\AuthPublic, \TransmitPublic)$ are derived from the \spendingKey $\AuthPrivate$, as described in \crossref{sproutkeycomponents}.} } %sproutspecific +\vspace{1ex} \saplingonward{ -\defining{An \expandedSpendingKey is composed of a \authSigningKey $\AuthSignPrivate$, +\defining{A \Sapling \expandedSpendingKey is composed of a \authSigningKey $\AuthSignPrivate$, a \authNullifierKey $\AuthProvePrivate$, and an \outgoingViewingKey $\OutViewingKey$. From these components we can derive a \authProvingKey $(\AuthSignPublic, \AuthProvePrivate)$, a \fullViewingKey $(\AuthSignPublic, \NullifierKey, \OutViewingKey)$, @@ -3123,6 +3232,7 @@ The consensus protocol does not depend on how an \expandedSpendingKey is constructed. Two methods of doing so are defined: \begin{enumerate} + \vspace{-0.5ex} \item Generate a \spendingKey $\SpendingKey$ at random and derive the \expandedSpendingKey $(\AuthSignPrivate, \AuthProvePrivate, \OutViewingKey)$ from it, as shown in the diagram above and described in \crossref{saplingkeycomponents}. @@ -3132,6 +3242,7 @@ \end{enumerate} } %saplingonward +\vspace{-0.5ex} \nufiveonward{ An \Orchard \spendingKey $\SpendingKey$ is used to derive a \authSigningKey $\AuthSignPrivate$, and a \fullViewingKey $(\AuthSignPublic, \NullifierKey, \CommitIvkRand)$. From the \fullViewingKey @@ -3141,9 +3252,15 @@ as described in \crossref{orchardkeycomponents}. } %nufiveonward +\notbeforenufive{* \nufive{ +The derivations of $\AuthSignPrivate$ and $\CommitIvkRand$ shown are not the only possibility. +For further detail see \shortcrossref{orchardkeycomponents}. +}} %notbeforenufive + \vspace{-2ex} -\sapling{\nnote{In \zcashd, all \SaplingAndOrchard keys and addresses are derived according to \cite{ZIP-32}.}} +\sapling{\nnote{Most \Zcash wallets derive \SaplingAndOrchard keys and addresses according to \cite{ZIP-32}.}} +\introlist \vspace{2ex} The composition of \shieldedPaymentAddresses, \incomingViewingKeys, \sapling{\fullViewingKeys,} and \spendingKeys is a cryptographic protocol @@ -3249,7 +3366,7 @@ \begin{itemize} \item $\Diversifier \typecolon \DiversifierType$ is the \diversifier of the recipient's \shieldedPaymentAddress; - \item $\DiversifiedTransmitPublic \typecolon \KAPublicPrimeSubgroup{Sapling}$ + \item $\DiversifiedTransmitPublic \typecolon \KAPublicPrimeOrder{Sapling}$ is the \diversifiedTransmissionKey of the recipient's \shieldedPaymentAddress; \item $\Value \typecolon \range{0}{\MAXMONEY}$ is an integer representing the value of the \note in \zatoshi; @@ -3260,7 +3377,7 @@ \introlist Let $\NoteType{Sapling}$ be the type of a \Sapling \note, i.e. \begin{formulae} - \item $\NoteType{Sapling} := \DiversifierType \times \KAPublicPrimeSubgroup{Sapling} \times \range{0}{\MAXMONEY} + \item $\NoteType{Sapling} := \DiversifierType \times \KAPublicPrimeOrder{Sapling} \times \range{0}{\MAXMONEY} \times \NoteCommitTrapdoor{Sapling}$. \end{formulae} } %sapling @@ -3274,7 +3391,7 @@ \item $\Diversifier \typecolon \DiversifierType$ is the \diversifier of the recipient's \shieldedPaymentAddress; \vspace{-0.5ex} - \item $\DiversifiedTransmitPublic \typecolon \KAPublic{Orchard}$ + \item $\DiversifiedTransmitPublic \typecolon \KAPublicPrimeOrder{Orchard}$ is the \diversifiedTransmissionKey of the recipient's \shieldedPaymentAddress; \item $\Value \typecolon \ValueType$ is an integer representing the value of the \note in \zatoshi; @@ -3292,7 +3409,7 @@ \introlist Let $\NoteType{Orchard}$ be the type of an \Orchard \note, i.e. \begin{formulae} - \item $\NoteType{Orchard} := \DiversifierType \times \KAPublic{Orchard} \times \ValueType + \item $\NoteType{Orchard} := \DiversifierType \times \KAPublicPrimeOrder{Orchard} \times \ValueType \times \NoteUniqueRandTypeOrchard \times \NoteNullifierRandType \times \NoteCommitTrapdoor{Orchard}$. \end{formulae} } %nufive @@ -3344,9 +3461,37 @@ \vspace{-1ex} The field $\NotePlaintextLeadByte$ indicates the version of the encoding of a \SaplingOrOrchard -\notePlaintext. For \Sapling it is $\hexint{01}$ before activation of the \Canopy -\networkUpgrade\canopy{ and $\hexint{02}$ afterward, as specified in \cite{ZIP-212}}. -\nufive{For \Orchard \notePlaintexts it is always $\hexint{02}$.} +\notePlaintext. + +Let the constants $\CanopyActivationHeight$ and $\ZIPTwoOneTwoGracePeriod$ be as defined in \crossref{constants}. + +Let $\Protocol \typecolon \setof{\SaplingProto, \OrchardProto}$ be the \shieldedProtocol of the \note. + +Let $\BlockHeight$ be the \blockHeight of the \block containing the \transaction having the encrypted +\notePlaintext as an output, and let $\TxVersion$ be the \transactionVersionNumber. + +Define $\AllowedLeadBytes^{\Protocol}(\BlockHeight, \TxVersion) := \notcanopy{\setof{\hexint{01}}}$\notcanopy{.} +\canopy{ +\begin{formulae} + \vspace{-1ex} + \item $\begin{cases} + \setof{\hexint{01}}, &\caseif \BlockHeight < \CanopyActivationHeight \\ + \setof{\hexint{01}, \hexint{02}},&\caseif \CanopyActivationHeight \leq \BlockHeight < \CanopyActivationHeight + \ZIPTwoOneTwoGracePeriod \\ + \setof{\hexint{02}}, &\caseotherwise. + \end{cases}$ +\end{formulae} +} %canopy + +The $\NotePlaintextLeadByte$ of a \Sapling or \Orchard \note MUST satisfy +$\NotePlaintextLeadByte \in \AllowedLeadBytes^{\Protocol}(\BlockHeight, \TxVersion)$. +Senders \SHOULD choose the highest \notePlaintextLeadByte allowed under this condition. + +\begin{nnotes} + \nufiveonwarditem{Since \Orchard was introduced after the end of the \cite{ZIP-212} grace period, + \notePlaintexts for \Orchard \notes \MUST have $\NotePlaintextLeadByte \geq \hexint{02}$.} + \item It is intentional that the definition of $\AllowedLeadBytes$ does not currently depend + on $\Protocol$ or $\TxVersion$. It might do so in future. +\end{nnotes} The fields \notcanopy{$\Diversifier$, $\Value$, and $\NoteCommitRandBytes$}\notbeforecanopy{$\Diversifier$ and $\Value$} are as defined in \crossref{notes}. @@ -3532,7 +3677,7 @@ that potentially risks \Mainnet funds or displays \Mainnet \transaction information to a user \MUST do so only for a \blockChain that includes the \activationBlock of the most recent \settled \networkUpgrade, with the corresponding \activationBlock hash. -Currently, there is social consensus that \NUFive has activated on the \Zcash \Mainnet +Currently, there is social consensus that \NUSixOne has activated on the \Zcash \Mainnet and \Testnet with the \activationBlock hashes given in \crossref{networks}. A \fullValidator \MAY impose a limit on the number of \blocks it will ``roll back'' when @@ -3555,12 +3700,23 @@ \nufive{For more detail on the distinction between these two identifiers and when to use each of them, see \cite{ZIP-239} and \cite{ZIP-244}.} -\vspace{2ex} +\vspace{1ex} \defining{\xTransparentInputs} to a \transaction insert value into a \defining{\transparentTxValuePool} associated with the \transaction, and \defining{\transparentOutputs} remove value from this pool. -As in \Bitcoin, the remaining value in the \transparentTxValuePool of a non-coinbase -\transaction is available to miners as a fee. The remaining value in the \transparentTxValuePool -of a \coinbaseTransaction is destroyed. + +The effect of \Sprout \joinSplitTransfers\sapling{,\notnufive{ and} \Sapling \spendTransfers and +\outputTransfers}\nufive{, and \Orchard \actionTransfers} on the \transparentTxValuePool are specified +in \crossref{sproutbalance}\sapling{,\notnufive{ and} \crossref{saplingbalance}}\nufive{, and +\crossref{orchardbalance}} respectively. + +As in \Bitcoin, the remaining value in the \transparentTxValuePool of a non-coinbase \transaction +is available to miners as a \defining{\transactionFee}. That is, the sum of those values for non-coinbase \transactions +in each \block is treated as an implicit input to the \transparentTxValuePool balance of the +\block's \coinbaseTransaction (in addition to the implicit input created by issuance). + +The remaining value in the \transparentTxValuePool of \coinbaseTransactions\nusix{ in \blocks +prior to \NUSix} is destroyed. \nusix{From \NUSix, this remaining value is required to be zero; +that is, all of the available balance \MUST be consumed by outputs of the \coinbaseTransaction.} \vspace{-1ex} \consensusrule{ @@ -3781,7 +3937,7 @@ \vspace{-1ex} \begin{center} -\includegraphics[scale=.4]{incremental_merkle} +\includegraphics[scale=.4]{incremental_merkle\imagesuffix} \end{center} \vspace{-1ex} @@ -3819,7 +3975,7 @@ \merkleLeafNodes.} \end{consensusrules} - +\vspace{-2ex} \lsubsection{Nullifier Sets}{nullifierset} Each \fullValidator maintains a \defining{\nullifierSet} logically associated with @@ -3851,7 +4007,7 @@ The calculations of the \blockSubsidy, \minerSubsidy, \notcanopy{and }\foundersReward\canopy{, and \fundingStreams} depend on the \blockHeight, as defined in \crossref{blockchain}. -The calculations are described in \crossref{subsidies}. +\crossref{subsidies}\notbeforenusixone{\\} describes these calculations. \lsubsection{Coinbase Transactions}{coinbasetransactions} @@ -3862,26 +4018,28 @@ collect and spend any \minerSubsidy, and \transactionFees paid by other \transactions included in the \block. -\precanopy{As described in \crossref{foundersreward}, the \coinbaseTransaction \MUST also pay +\precanopy{\crossref{foundersreward} specifies that the \coinbaseTransaction \MUST also pay the \foundersReward.} -\canopyonward{As described in \crossref{fundingstreams}, the \coinbaseTransaction \MUST also pay +\canopyonward{\crossref{fundingstreams} specifies that the \coinbaseTransaction \MUST also pay the \fundingStreams.} \lsubsection{Mainnet and Testnet}{networks} -The production \Zcash{} \defining{\network}, which supports the \ZEC token, is called \Mainnet. Governance of its -protocol is by agreement between the Electric Coin Company and the Zcash Foundation \cite{ECCZF2019}. -Subject to errors and omissions, each version of this document intends to describe some version -(or planned version) of that agreed protocol. +The production \Zcash{} \defining{\network}, which supports the \ZEC token, is called \Mainnet. +Governance of its protocol is by social consensus on which \fullValidator implementations are +considered to be faithful implementations of the intended \Mainnet consensus rules (currently, +\zebra maintained by the Zcash Foundation, and \zcashd maintained by the Electric Coin Company), +and on how those implementations should be modified. Subject to errors and omissions, each version +of this document intends to describe some version (or planned version) of the \Zcash protocol. \defining{All \blockHashes given in this section are in \rpcByteOrder (that is, byte-reversed relative to the normal order for a $\SHAFull$ hash).} \Mainnet \genesisBlock: $\mathtt{00040fe8ec8471911baa1db1266ea15dd06b4a8a5c453883c000b031973dce08}$ -\Mainnet \NUFive \activationBlock: $\mathtt{0000000000d723156d9b65ffcf4984da7a19675ed7e2f06d9e5d5188af087bf8}$ +\Mainnet \NUSixOne \activationBlock: $\mathtt{0000000000b98a7d8f390793fa113bf6755935f0c14ea817af07d2c16f2c3ef4}$ \introlist There is also a public test \network called \Testnet. It supports a \TAZ token which is intended to @@ -3892,16 +4050,18 @@ \Testnet \genesisBlock: $\mathtt{05a60a92d99d85997cce3b87616c089f6124d7342af37106edc76126334a2c38}$ -\Testnet \NUFive \activationBlock: $\mathtt{0006d75c60b3093d1b671ff7da11c99ea535df9927c02e6ed9eb898605eb7381}$ +\Testnet \NUSixOne \activationBlock: $\mathtt{01b947c7556b23040dc6840e9d3e4c6d9478c67a87b9737a83be848729d6e0af}$ -We call the smallest units of currency (on either \network) \zatoshi. +We call the smallest units of currency (on either \network) \zatoshi.\footnote{\definingquotedterm{tazoshi} +may be used for the smallest units of currency on Testnet, but it is usually more convenient to use a +\network-independent term.} On \Mainnet, $1$ \ZEC = $\pow{10}{8}$ \zatoshi. On \Testnet, $1$ \TAZ = $\pow{10}{8}$ \zatoshi. Other \networks using variants of the \Zcash protocol may exist, but are not described by this specification. -\intropart +\introsection \extralabel{cautionlinkage}{\lsection{Abstract Protocol}{abstractprotocol}} \vspace{-1ex} @@ -4098,21 +4258,20 @@ \introlist $\PRFexpand{}$ is used in the following places: \begin{itemize} - \item \sapling{\crossref{saplingkeycomponents}, with inputs $[0]$, $[1]$, $[2]$, and $[3, i \typecolon \byte]$;} - \nufiveonwarditem{in \crossref{orchardkeycomponents}, with inputs $[6]$, $[7]$, $[8]$, and with first byte $\hexint{82}$ - (the last of these is also specified in \cite{ZIP-32});} + \item \sapling{\crossref{saplingkeycomponents}, with inputs $[\hexint{00}]$, $[\hexint{01}]$, $[\hexint{02}]$, and $[\hexint{03}, i \typecolon \byte]$;} + \nufiveonwarditem{in \crossref{orchardkeycomponents}, with inputs $[\hexint{06}]$, $[\hexint{07}]$, $[\hexint{08}]$, and with first byte $\hexint{82}$;} \notnufive{ \item \sapling{sending (\crossref{saplingsend}) and receiving (\shortcrossref{saplingandorchardinband}) \Sapling \notes, - with inputs $[4]$ and $[5]$;} + with inputs $[\hexint{04}]$ and $[\hexint{05}]$;} } %notnufive \notbeforenufive{ \item \sapling{in the processes of sending (\crossref{saplingsend}\nufive{ and \crossref{orchardsend}}) and of receiving - (\crossref{saplingandorchardinband}) \notes, with inputs $[4]$ and $[5]$\nufive{, and for \Orchard - $[t] \bconcat \NoteUniqueRandBytes$ with $t \in \setof{5, 4, 9}$};} + (\crossref{saplingandorchardinband}) \notes, for \Sapling with inputs $[\hexint{04}]$ and $[\hexint{05}]$\nufive{, and for \Orchard + $[t] \bconcat \NoteUniqueRandBytes$ with $t \in \setof{\hexint{05}, \hexint{04}, \hexint{09}}$};} } %notbeforenufive - \item in \cite{ZIP-32}, \sapling{with inputs $[0]$, $[1]$, $[2]$ (intentionally matching \shortcrossref{saplingkeycomponents}), + \item in \cite{ZIP-32}, \sapling{with inputs $[\hexint{00}]$, $[\hexint{01}]$, $[\hexint{02}]$ (intentionally matching \shortcrossref{saplingkeycomponents}), $[\hexint{10}]$, $[\hexint{13}]$, $[\hexint{14}]$, and} with first byte in - $\setof{\sapling{\hexint{11}, \hexint{12}, \hexint{15}, \hexint{16}, \hexint{17}, \hexint{18},\,}\hexint{80}\nufive{, \hexint{81}, \hexint{82}, \hexint{83}}}$; + $\setof{\sapling{\hexint{11}, \hexint{12}, \hexint{15}, \hexint{16}, \hexint{17}, \hexint{18},\,}\hexint{80}\nufive{, \hexint{81}, \hexint{83}}}$; \item in \cite{ZIP-316}, with first byte $\hexint{D0}$. \end{itemize} @@ -4200,7 +4359,7 @@ A \keyAgreementScheme $\KA{}$ defines a type of \publicKeys $\KAPublic{}$, a type of \privateKeys $\KAPrivate{}$, and a type of shared secrets $\KASharedSecret{}$. -\sapling{Optionally, it also defines a type $\KAPublicPrimeSubgroup{} \subseteq \KAPublic{}$.} +\sapling{Optionally, it also defines a type $\KAPublicPrimeOrder{} \subseteq \KAPublic{}$.} \sapling{Optional:} Let $\KAFormatPrivate{} \typecolon \PRFOutputSprout \rightarrow \KAPrivate{}$ be a function to convert a bit string of length $\PRFOutputLengthSprout$ to a $\KA{}$ \privateKey. @@ -4655,6 +4814,7 @@ \nufive{ \vspace{2ex} +\introsection Let $\ScalarLength{Orchard}$ be as defined in \crossref{constants}. Let $\GroupP$, $\ellP$, $\ParamP{q}$, and $\ParamP{r}$ be as defined in \crossref{pallasandvesta}. @@ -4812,15 +4972,15 @@ a sequence of \emph{distinct} inputs $m_{\alln} \typecolon \typeexp{\SubgroupGHashInput}{n}$ and a sequence of nonzero $x_{\alln} \typecolon \typeexp{\GFstar{\ParamG{r}}}{n}$ such that $\ssum{i = 1}{n}\!\Big(\scalarmult{x_i}{\SubgroupGHash{\URS}(m_i)}\Big) = \ZeroG{}$. - \item Under the \xDiscreteLogarithm assumption on $\SubgroupG{}$, a \randomOracle almost surely satisfies - Discrete Logarithm Independence. Discrete Logarithm Independence implies \collisionResistance\!, - since a collision $(m_1, m_2)$ for $\SubgroupGHash{\URS}$ trivially gives a - discrete logarithm relation with $x_1 = 1$ and $x_2 = -1$. + \item Assuming hardness of the \DiscreteLogarithmProblem on $\SubgroupG{}$, a \randomOracle almost + surely satisfies \DiscreteLogarithmIndependence. \DiscreteLogarithmIndependence implies + \collisionResistance\!, since a collision $(m_1, m_2)$ for $\SubgroupGHash{\URS}$ trivially + gives a \discreteLogarithm relation with $x_1 = 1$ and $x_2 = -1$. \item $\GroupJHash{}$ is used in \crossref{concretediversifyhash} to instantiate $\DiversifyHash{Sapling}$. We do not know how to prove the Unlinkability property defined in that section in the standard model, but in a model where $\GroupJHash{}$ (restricted to inputs for which it does not return $\bot$) is taken as a \randomOracle, - it is implied by the \xDecisionalDiffieHellman assumption on $\SubgroupJ$\nufive{, + it is implied by the \DecisionalDiffieHellmanAssumption on $\SubgroupJ$\nufive{, and similarly for $\GroupPHash$}. \item $\URS$ is a \defining{\uniformRandomString}; we chose it verifiably at random (see \crossref{beacon}), after fixing the concrete group hash algorithm to be used. @@ -5117,7 +5277,7 @@ \vspace{-1ex} The resulting \diversifiedPaymentAddress is -$(\Diversifier \typecolon \DiversifierType, \DiversifiedTransmitPublic \typecolon \KAPublicPrimeSubgroup{Sapling})$. +$(\Diversifier \typecolon \DiversifierType, \DiversifiedTransmitPublic \typecolon \KAPublicPrimeOrder{Sapling})$. \vspace{1ex} For each \spendingKey, there is also a \defining{\defaultDiversifiedPaymentAddress} @@ -5157,9 +5317,10 @@ \vspace{-0.5ex} \item Similarly, address generators \MAY encode information in the \diversifier that can be recovered by the recipient of a payment to determine which - \diversifiedPaymentAddress was used. It is \RECOMMENDED that such \diversifiers - be randomly chosen unique values used to index into a database, rather than - directly encoding the needed data. + \diversifiedPaymentAddress was used. It is \RECOMMENDED, instead of + directly encoding information in the \diversifier, to encode it in the + \diversifierIndex specified in \cite{ZIP-32}. This ensures that the information + is only accessible to a holder of the \diversifierKey $\DiversifierKey$. \end{pnotes} \vspace{-1ex} @@ -5195,53 +5356,64 @@ \introsection \lsubsubsection{\OrchardText{} Key Components}{orchardkeycomponents} -\vspace{-1ex} Let $\PRFOutputLengthExpand$, $\SpendingKeyLength$, $\OutViewingKeyLength$, $\DiversifierLength$, and $\DiversifierKeyLength$ be as defined in \crossref{constants}. Let $\GroupP$, $\reprP$, $\ellP$, $\ParamP{q}$, and $\ParamP{r}$ be as defined in \crossref{pallasandvesta}. -\vspace{-0.25ex} +\vspace{-0.2ex} Let $\ExtractP$ be as defined in \crossref{concreteextractorpallas}. -\vspace{-0.35ex} +\vspace{-0.3ex} Let $\GroupPHash$ be as defined in \crossref{concretegrouphashpallasandvesta}. -\vspace{-0.25ex} +\vspace{-0.2ex} Let $\PRFexpand{}$ and $\PRFock{Orchard}{}$ be as defined in \crossref{concreteprfs}. -\vspace{-0.5ex} +\vspace{-0.4ex} Let $\DeriveInternalFVKOrchard$ be as defined in \cite[Orchard internal key derivation]{ZIP-32}. -\vspace{-0.25ex} +\vspace{-0.2ex} Let $\PRPd{} \typecolon \DiversifierKeyType \times \DiversifierType \rightarrow \DiversifierType$ be as defined in \crossref{concreteprps}. -\vspace{-0.35ex} +\vspace{-0.3ex} Let $\KA{Orchard}$, instantiated in \crossref{concreteorchardkeyagreement}, be a \keyAgreementScheme. -\vspace{-0.35ex} +\vspace{-0.3ex} Let $\CommitIvk{}$, instantiated in \crossref{concretesinsemillacommit}, be a \commitmentScheme. -\vspace{-0.25ex} +\vspace{-0.2ex} Let $\DiversifyHash{Orchard}$ be as defined in \crossref{concretediversifyhash}. -\vspace{-0.25ex} +\vspace{-0.2ex} Let $\SpendAuthSig{Orchard}$ instantiated in \crossref{concretespendauthsig} be a \rerandomizableSignatureScheme. -\vspace{-0.25ex} +\vspace{-0.2ex} Let $\ItoLEBSP{}$, $\ItoLEOSP{}$, and $\LEOStoIP{}$ be as defined in \crossref{endian}. -\vspace{0.5ex} +\vspace{0.4ex} Define $\ToBase{Orchard}(x \typecolon \PRFOutputExpand) := \LEOStoIPOf{\PRFOutputLengthExpand}{x} \pmod{\ParamP{q}}$. -\vspace{-1.5ex} +\vspace{-1.3ex} Define $\ToScalar{Orchard}(x \typecolon \PRFOutputExpand) := \LEOStoIPOf{\PRFOutputLengthExpand}{x} \pmod{\ParamP{r}}$. +Define $\DeriveDkAndOvkOrchard(\CommitIvkRand \typecolon \CommitIvkRandType, \AuthSignPublic \typecolon \AuthSignPublicTypeOrchard, \NullifierKey \typecolon \NullifierKeyTypeOrchard)$ +as follows: + +\begin{algorithm} + \item let $K = \ItoLEBSPOf{\SpendingKeyLength}{\CommitIvkRand}$ + \vspace{-0.3ex} + \item let $R = \PRFexpand{\!K}\big([\hexint{82}] \bconcat \ItoLEOSPOf{256}{\AuthSignPublic} \bconcat \ItoLEOSPOf{256}{\NullifierKey}\kern-0.25em\big)$ + \item let $\DiversifierKey \typecolon \DiversifierKeyType$ be the first $\DiversifierKeyLength/8$ bytes of $R$ and + let $\OutViewingKey \typecolon \OutViewingKeyType$ be the remaining $\OutViewingKeyLength/8$ bytes of $R$. + \item return $(\DiversifierKey, \OutViewingKey)$ +\end{algorithm} + \introlist A new \Orchard \spendingKey $\SpendingKey$ is generated by choosing a \bitSequence uniformly at random from $\SpendingKeyType$. @@ -5276,12 +5448,7 @@ \vspace{-0.3ex} \item if $\InViewingKey \in \setof{0, \bot}$, discard this key and repeat with a new $\SpendingKey$. \vspace{-0.2ex} - \item let $K = \ItoLEBSPOf{\SpendingKeyLength}{\CommitIvkRand}$ - \vspace{-0.5ex} - \item let $R = \PRFexpand{K}\big([\hexint{82}] \bconcat \ItoLEOSPOf{256}{\AuthSignPublic} \bconcat \ItoLEOSPOf{256}{\NullifierKey}\kern-0.25em\big)$ - \vspace{-0.2ex} - \item let $\DiversifierKey$ be the first $\DiversifierKeyLength/8$ bytes of $R$ and - let $\OutViewingKey$ be the remaining $\OutViewingKeyLength/8$ bytes of $R$. + \item let $(\DiversifierKey, \OutViewingKey) = \DeriveDkAndOvkOrchard(\CommitIvkRand, \AuthSignPublic, \NullifierKey)$ \vspace{-0.4ex} \item let $(\Internal{\AuthSignPublic}, \Internal{\NullifierKey}, \Internal{\CommitIvkRand}) = \DeriveInternalFVKOrchard(\AuthSignPublic, \NullifierKey, \CommitIvkRand)$ \vspace{-0.3ex} @@ -5289,17 +5456,14 @@ \vspace{-0.2ex} \item if $\Internal{\InViewingKey} \in \setof{0, \bot}$, discard this key and repeat with a new $\SpendingKey$. \vspace{-0.2ex} - \item let $\Internal{K} = \ItoLEBSPOf{\SpendingKeyLength}{\Internal{\CommitIvkRand}}$ - \vspace{-0.5ex} - \item let $\Internal{R} = \PRFexpand{\Internal{K}}\big([\hexint{82}] \bconcat \ItoLEOSPOf{256}{\Internal{\AuthSignPublic}} \bconcat \ItoLEOSPOf{256}{\Internal{\NullifierKey}}\kern-0.25em\big)$ - \vspace{-0.2ex} - \item let $\Internal{\DiversifierKey}$ be the first $\DiversifierKeyLength/8$ bytes of $\Internal{R}$ and - let $\Internal{\OutViewingKey}$ be the remaining $\OutViewingKeyLength/8$ bytes of $\Internal{R}$. + \item let $(\Internal{\DiversifierKey}, \Internal{\OutViewingKey}) = \DeriveDkAndOvkOrchard\big(\Internal{\CommitIvkRand}, \Internal{\AuthSignPublic}, \Internal{\NullifierKey}\big)$. \end{algorithm} +\vspace{-1ex} \introlist \pnote{$\Internal{\AuthSignPublic} = \AuthSignPublic$ and $\Internal{\NullifierKey} = \NullifierKey$.} +\vspace{1ex} As explained in \crossref{addressesandkeys}, \Orchard allows the efficient creation of multiple \diversifiedPaymentAddresses with the same \spendingAuthority. A group of such addresses shares the same \fullViewingKey, \incomingViewingKey, and @@ -5321,7 +5485,7 @@ \vspace{-1ex} The resulting \diversifiedPaymentAddress is -$(\Diversifier \typecolon \DiversifierType, \DiversifiedTransmitPublic \typecolon \KAPublic{Orchard})$. +$(\Diversifier \typecolon \DiversifierType, \DiversifiedTransmitPublic \typecolon \KAPublicPrimeOrder{Orchard})$. The \diversifiedPaymentAddress with \diversifierIndex $0$ is called the \defining{\defaultDiversifiedPaymentAddress}. @@ -5418,9 +5582,9 @@ a sequence of ciphertext components for the encrypted output \notes. \end{itemize} -\introlist The $\ephemeralKey$ and $\encCiphertexts$ fields together form the \notesCiphertextSprout. +\introlist The value $\hSig$ is also computed from $\RandomSeed$, $\nfOld{\allOld}$, and the $\joinSplitPubKey$ of the containing \transaction: \begin{formulae} @@ -5496,7 +5660,8 @@ i.e.\ $\SpendAuthSigValidate{Sapling}{\AuthSignRandomizedPublic}(\SigHash, \spendAuthSig) = 1$. \nufiveonward{As specified in \crossref{concretereddsa}, the validation of the $\RedDSAReprR{}$ - component of the signature changes to prohibit \nonCanonicalPoint encodings.} + component of the signature changes to prohibit \nonCanonicalPoint encodings. This change is also + retrospectively valid on \Mainnet and \Testnet before \NUFive.} \end{consensusrules} \vspace{-1.5ex} @@ -5587,9 +5752,11 @@ } %sapling +\vspace{-2ex} \nufive{ \lsubsection{Action Descriptions}{actiondesc} +\vspace{-1ex} An \actionTransfer, as specified in \crossref{actions}, is encoded in \transactions as an \defining{\actionDescription}. Each version 5 \transaction includes a sequence of zero or more \defining{\actionDescriptions}. @@ -5615,45 +5782,47 @@ Let $\Action$ be as defined in \crossref{abstractzk}. -\vspace{1ex} +\vspace{0.5ex} \introsection -An \actionDescription comprises $(\cvNet{}, \rt{Orchard}, \nf, \AuthSignRandomizedPublic, \spendAuthSig, -\cmX, \EphemeralPublic, \TransmitCiphertext{}, \OutCiphertext, \enableSpends, \enableOutputs,$ $\Proof{})$ -where +An \actionDescription comprises $(\cvNet{}\kern-0.2em, \rt{Orchard}\kern-0.2em, \nf, \AuthSignRandomizedPublic, \spendAuthSig, +\cmX\kern-0.1em, \EphemeralPublic, \TransmitCiphertext{}\kern-0.2em, \OutCiphertext\kern-0.2em, \enableSpends, \enableOutputs, \Proof{})$: +\vspace{-1.5ex} \begin{itemize} \item $\cvNet{} \typecolon \ValueCommitOutput{Orchard}$ is the \valueCommitment to the value of the input \note minus the value of the output \note; \vspace{-0.5ex} \item $\rt{Orchard} \typecolon \MerkleHashOrchard$ is an \anchor, as defined in \crossref{transactions}, for the output \treestate of a previous \block; - \vspace{-0.25ex} + \vspace{-0.3ex} \item $\nf \typecolon \range{0}{\ParamP{q}-1}$ is the \nullifier for the input \note; - \vspace{-0.25ex} + \vspace{-0.3ex} \item $\AuthSignRandomizedPublic \typecolon \SpendAuthSigPublic{Orchard}$ is a randomized \validatingKey that should be used to validate $\spendAuthSig$; - \vspace{-0.25ex} + \vspace{-0.3ex} \item $\spendAuthSig \typecolon \SpendAuthSigSignature{Orchard}$ is a \spendAuthSignature, validated as specified in \crossref{spendauthsig}; - \vspace{-0.25ex} + \vspace{-0.3ex} \item $\cmX \typecolon \MerkleHashOrchard$ is the result of applying $\ExtractP$ to the \noteCommitment for the output \note; - \vspace{-0.25ex} + \vspace{-0.3ex} \item $\EphemeralPublic \typecolon \KAPublic{Orchard}$ is a key agreement \publicKey, used to derive the key for encryption of the \noteCiphertextOrchard (\crossref{saplinginband}); - \vspace{-0.25ex} + \vspace{-0.3ex} \item $\TransmitCiphertext{} \typecolon \Ciphertext$ is a ciphertext component for the encrypted output \note; - \vspace{-0.25ex} + \vspace{-0.3ex} \item $\OutCiphertext{} \typecolon \Ciphertext$ is a ciphertext component that allows the holder of the \outgoingCipherKey (which can be derived from a \fullViewingKey) to recover the recipient \diversifiedTransmissionKey $\DiversifiedTransmitPublic$ and the \ephemeralPrivateKey $\EphemeralPrivate$, hence the entire \notePlaintext; + \vspace{-0.15ex} \item $\enableSpends \typecolon \bit$ is a flag that is set in order to enable \nh{non-zero-valued} spends in this Action; + \vspace{-0.15ex} \item $\enableOutputs \typecolon \bit$ is a flag that is set in order to enable \nh{non-zero-valued} outputs in this Action; - \vspace{-0.25ex} + \vspace{-0.3ex} \item $\Proof{} \typecolon \ActionProof$ is a \zkSNARKProof with \primaryInput $(\cv, \rt{Orchard}\kern-0.1em, \nf\kern-0.1em, \AuthSignRandomizedPublic, \cmX, \enableSpends, \enableOutputs)$ for the \actionStatement defined in \crossref{actionstatement}. @@ -5661,10 +5830,9 @@ \vspace{-1.5ex} \pnote{The $\rt{Orchard}$, $\enableSpends$, and $\enableOutputs$ components are the same for all -\actionTransfers in a \transaction. They are encoded once in the \transaction body (see -\crossref{txnencoding}), not in the $\type{ActionDescription}$ structure. -$\Proof{}$ is aggregated with other Action proofs and encoded in the $\proofsOrchard$ field of a -\transaction.} +\actionTransfers in a \transaction, and are encoded once in the \transaction body +(\crossref{txnencoding}), not the $\type{ActionDescription}$ structure. +$\Proof{}$ is aggregated with other Action proofs and encoded in the $\proofsOrchard$ field.} \begin{consensusrules} \vspace{-0.25ex} @@ -5684,7 +5852,7 @@ i.e.\ $\ActionVerify\big(\kern-0.1em(\cv, \rt{Orchard}, \nf, \AuthSignRandomizedPublic, \cmX, \enableSpends, \enableOutputs), \Proof{}\big) = 1$. \end{consensusrules} -\vspace{-1.5ex} +\vspace{-2ex} \begin{nnotes} \vspace{-0.25ex} \item $\cv$ and $\AuthSignRandomizedPublic$ can be the zero point $\ZeroP$. $\EphemeralPublic$ cannot @@ -5696,7 +5864,7 @@ } %nufive -\vspace{-3ex} +\vspace{-2.5ex} \lsubsection{Sending Notes}{send} \vspace{-1ex} @@ -5709,15 +5877,16 @@ \introlist Let $\JoinSplitSig$ be as specified in \crossref{abstractsig}. -\vspace{-0.5ex} +\vspace{-0.6ex} Let $\NoteCommitAlg{Sprout}$ be as specified in \crossref{abstractcommit}. -\vspace{-0.5ex} +\vspace{-0.6ex} Let $\RandomSeedLength$ and $\NoteUniquePreRandLength$ be as specified in \crossref{constants}. Sending a \transaction containing \joinSplitDescriptions involves first generating a new $\JoinSplitSig$ key pair: +\vspace{-0.4ex} \begin{formulae} \item $\joinSplitPrivKey \leftarrowR \JoinSplitSigGenPrivate()$ \item $\joinSplitPubKey := \JoinSplitSigDerivePublic(\joinSplitPrivKey)$. @@ -5742,10 +5911,10 @@ \item Let $\NotePlaintext{i} = (\hexint{00}, \Value_i, \NoteUniqueRand_i, \NoteCommitRand_i, \Memo_i)$. \end{itemize} -\vspace{-1ex} +\vspace{-1.3ex} $\NotePlaintext{\allNew}$ are then encrypted to the recipient \transmissionKeys $\TransmitPublicSub{\allNew}$, giving the \notesCiphertextSprout -$(\EphemeralPublic, \TransmitCiphertext{\allNew})$, as described in \crossref{sproutinband}. +$\big(\EphemeralPublic, \TransmitCiphertext{\allNew}\big)$, as described in \crossref{sproutinband}. In order to minimize information leakage, the sender \SHOULD randomize the order of the input \notes and of the output \notes. Other considerations relating to @@ -5760,7 +5929,7 @@ \item $\joinSplitSig \leftarrowR \JoinSplitSigSign{\text{\small\joinSplitPrivKey}}(\dataToBeSigned)$ \end{formulae} -\vspace{-0.5ex} +\vspace{-1ex} Then the encoded \transaction including $\joinSplitSig$ is submitted to the \peerToPeerNetwork. \canopyonwardpnote{\cite{ZIP-211} specifies that nodes and wallets \MUST disable any facilities @@ -5810,13 +5979,8 @@ \pnote{Choosing $\OutViewingKey = \bot$ is useful if the sender prefers to obtain forward secrecy of the payment information with respect to compromise of its own secrets.} -\canopy{ -Let $\CanopyActivationHeight$ be as defined in \crossref{constants}. - -Let $\NotePlaintextLeadByte$ be the \notePlaintextLeadByte. This \MUST be $\hexint{01}$ -if for the next \block, $\BlockHeight < \CanopyActivationHeight$, or $\hexint{02}$ -if $\BlockHeight \geq \CanopyActivationHeight$. -} +Let $\NotePlaintextLeadByte$ be the \notePlaintextLeadByte, chosen according to +\crossref{noteptconcept} with $\Protocol = \SaplingProto$. \intropart For each \outputDescription, the sender selects a value $\Value \typecolon \range{0}{\MAXMONEY}$ @@ -5825,9 +5989,9 @@ \vspace{-0.5ex} \begin{algorithm} - \item Check that $\DiversifiedTransmitPublic$ is of type $\KAPublicPrimeSubgroup{Sapling}$, i.e.\ it - \MUST be a valid \ctEdwardsCurve point on the \jubjubCurve (as defined in \crossref{jubjub}), and - $\scalarmult{\ParamJ{r}}{\DiversifiedTransmitPublic} = \ZeroJ$. + \item Check that $\DiversifiedTransmitPublic$ is of type $\KAPublicPrimeOrder{Sapling}$, i.e.\ it + \MUST be a valid \ctEdwardsCurve point on the \jubjubCurve (as defined in \crossref{jubjub}), + $\scalarmult{\ParamJ{r}}{\DiversifiedTransmitPublic} = \ZeroJ$, and $\DiversifiedTransmitPublic \neq \ZeroJ$. \vspace{-0.25ex} \item Calculate $\DiversifiedTransmitBase = \DiversifyHash{Sapling}(\Diversifier)$ and check that $\DiversifiedTransmitBase \neq \bot$. @@ -5922,7 +6086,8 @@ in \crossref{saplingsend}. \vspace{-0.25ex} -Let $\NotePlaintextLeadByte$ be the \notePlaintextLeadByte, which \MUST be $\hexint{02}$. +Let $\NotePlaintextLeadByte$ be the \notePlaintextLeadByte, chosen according to +\crossref{noteptconcept} with $\Protocol = \OrchardProto$. \vspace{0.5ex} \introlist @@ -5932,7 +6097,7 @@ \begin{algorithm} \vspace{-0.5ex} - \item Check that $\DiversifiedTransmitPublic$ is of type $\KAPublic{Orchard}$. + \item Check that $\DiversifiedTransmitPublic$ is of type $\KAPublicPrimeOrder{Orchard}$. \item Calculate $\DiversifiedTransmitBase = \DiversifyHash{Orchard}(\Diversifier)$. \item Choose a uniformly random \commitmentTrapdoor $\ValueCommitRand \leftarrowR \ValueCommitGenTrapdoor{Orchard}()$. \item Choose uniformly random $\NoteSeedBytes \leftarrowR \NoteSeedBytesType$. @@ -6058,7 +6223,9 @@ \introlist \vspace{0.75ex} -A \spendDescription for a \dummy \Sapling input \note is constructed as follows: +A \spendDescription for a \dummy \Sapling input \note with \notePlaintextLeadByte +$\hexint{02}$ is constructed as follows: + \begin{itemize} \item Choose uniformly random $\SpendingKey \leftarrowR \SpendingKeyType$. \vspace{-0.2ex} @@ -6125,6 +6292,10 @@ \vspace{-0.25ex} Let $\ItoLEOSP{}$ be as defined in \crossref{endian}. +\vspace{-0.25ex} +Let $\NotePlaintextLeadByte$ be the \notePlaintextLeadByte, chosen according to +\crossref{noteptconcept} with $\Protocol = \OrchardProto$. + \introlist \vspace{0.5ex} The spend-related fields of an \actionDescription for a \dummy \Orchard input \note are @@ -6242,7 +6413,7 @@ $\ZeroP$. Allowing the validity check to pass in that case models the fact that incomplete addition is used to implement Sinsemilla in the circuit. As proven in \theoremref{thmsinsemillaex}, a $\bot$ output from $\SinsemillaHash$ yields a - nontrivial discrete logarithm relation. Since we assume finding such a relation to be + nontrivial \discreteLogarithm relation. Since we assume finding such a relation to be infeasible, we can argue that it is safe to allow an adversary to create a proof that passes the Merkle validity check in such a case. } %nufive @@ -6327,6 +6498,8 @@ as defined in \cite{ZIP-252}.} \nusixonlyitem{All \transactions \MUST use the \NUSix \consensusBranchID \hexint{C8E71055} as defined in \cite{ZIP-253}.} + \nusixoneonlyitem{All \transactions \MUST use the \NUSixOne \consensusBranchID \hexint{4DEC4DF0} + as defined in \cite{ZIP-255}.} \end{consensusrules} @@ -6515,7 +6688,7 @@ We now explain why this works. \vspace{1ex} -A \saplingBindingSignature proves knowledge of the discrete logarithm $\BindingPrivate{Sapling}$ +A \saplingBindingSignature proves knowledge of the \discreteLogarithm $\BindingPrivate{Sapling}$ of $\BindingPublic{Sapling}$ with respect to $\ValueCommitRandBase{Sapling}$. That is, $\BindingPublic{Sapling} = \scalarmult{\BindingPrivate{Sapling}}{\ValueCommitRandBase{Sapling}}$. So the value $0$ and randomness $\BindingPrivate{Sapling}$ is an opening of the \xPedersenCommitment @@ -6550,14 +6723,14 @@ Suppose that $\vSum = \vBad \neq 0 \pmod{\ParamJ{r}}$. Then $\BindingPublic{Sapling} = \ValueCommit{Sapling}{\BindingPrivate{Sapling}}(\vBad)$. -If the adversary were able to find the discrete logarithm of this $\BindingPublic{Sapling}$ +If the adversary were able to find the \discreteLogarithm of this $\BindingPublic{Sapling}$ with respect to $\ValueCommitRandBase{Sapling}$, say ${\BindingPrivate{}}'$ (as needed to create a valid \saplingBindingSignature), then $(\vBad, \BindingPrivate{Sapling})$ and $(0, {\BindingPrivate{}}')$ would be distinct openings of $\BindingPublic{Sapling}$ to different values, breaking the \binding property of the \valueCommitmentScheme. \introlist -The above argument shows only that $\Value^* = 0 \pmod{\ParamJ{r}}$; in order to show that +The preceding argument shows only that $\Value^* = 0 \pmod{\ParamJ{r}}$; in order to show that $\vSum = 0$, we will also demonstrate that it does not overflow $\ValueCommitTypeSapling$. The $\spendStatements$ (\crossref{spendstatement}) prove that all of $\vOld{\alln}$ @@ -6709,7 +6882,7 @@ value commitments, and a different bound on the net value sum $\vSum$. \vspace{1ex} -An \orchardBindingSignature proves knowledge of the discrete logarithm $\BindingPrivate{Orchard}$ +An \orchardBindingSignature proves knowledge of the \discreteLogarithm $\BindingPrivate{Orchard}$ of $\BindingPublic{Orchard}$ with respect to $\ValueCommitRandBase{Orchard}$. That is, $\BindingPublic{Orchard} = \scalarmult{\BindingPrivate{Orchard}}{\ValueCommitRandBase{Orchard}}$. So the value $0$ and randomness $\BindingPrivate{Orchard}$ is an opening of the \xPedersenCommitment @@ -6740,14 +6913,14 @@ Suppose that $\vSum = \vBad \neq 0 \pmod{\ParamJ{r}}$. Then $\BindingPublic{Orchard} = \ValueCommit{Orchard}{\BindingPrivate{Orchard}}(\vBad)$. -If the adversary were able to find the discrete logarithm of this $\BindingPublic{Orchard}$ +If the adversary were able to find the \discreteLogarithm of this $\BindingPublic{Orchard}$ with respect to $\ValueCommitRandBase{Orchard}$, say ${\BindingPrivate{}}'$ (as needed to create a valid \orchardBindingSignature), then $(\vBad, \BindingPrivate{Orchard})$ and $(0, {\BindingPrivate{}}')$ would be distinct openings of $\BindingPublic{Orchard}$ to different values, breaking the \binding property of the \valueCommitmentScheme. \introlist -The above argument shows only that $\Value^* = 0 \pmod{\ParamP{r}}$; in order to show that +The preceding argument shows only that $\Value^* = 0 \pmod{\ParamP{r}}$; in order to show that $\vSum = 0$, we will also demonstrate that it does not overflow $\ValueCommitTypeOrchard$. The $\actionStatements$ (\crossref{actionstatement}) prove that all $\vNet{\alln}$ @@ -6775,6 +6948,7 @@ \sapling{ +\vspace{-1ex} \introsection \lsubsection{Spend Authorization Signature (\SaplingAndOrchardText)}{spendauthsig} @@ -6791,11 +6965,9 @@ \actionStatement}, similar to the check in \crossref{sproutspendauthority} that is part of the \joinSplitStatement. The motivation for a separate signature is to allow devices that are limited in memory and computational capacity, such as hardware wallets, to authorize a \SaplingOrOrchard -shielded Spend. Typically such devices cannot create, and may not be able to verify, \zkSNARKProofs -for a \statement of the size needed using the \BCTV\notnufive{ or \Groth}\notbeforenufive{, -\Groth\nufive{, or \HaloTwo}} proving systems. +Spend. Typically such devices cannot create, and may not be able to verify, \zkSNARKProofs +for a \statement of the size needed using the \Groth\nufive{ or \HaloTwo} proving system\notbeforenufive{s}. -\vspace{1ex} The \validatingKey of the signature must be revealed in the \spendDescription so that the signature can be checked by validators. To ensure that the \validatingKey cannot be linked to the \shieldedPaymentAddress or \spendingKey from which the \note was spent, we use a @@ -6804,30 +6976,37 @@ with a \randomizer known to the signer. The \defining{\spendAuthSignature} is over the \sighashTxHash, so that it cannot be replayed in other \transactions. -\vspace{2ex} +\vspace{1.5ex} Let $\SigHash$ be the \sighashTxHash as defined in \cite{ZIP-243}\nufive{ or as defined in \cite{ZIP-244} modified by \cite{ZIP-225}}, not associated with an input, using the \sighashType $\SIGHASHALL$. +\vspace{-0.2ex} Let $\AuthSignPrivate$ be the \defining{\spendAuthPrivateKey} as defined in \crossref{saplingkeycomponents}\nufive{ or in \crossref{orchardkeycomponents}}. +\vspace{-0.2ex} \notbeforenufive{ Let $\SpendAuthSig{}$ be $\SpendAuthSig{Sapling}$\nufive{ or $\SpendAuthSig{Orchard}$ as applicable}. } %notbeforenufive -\introsection +\introlist \vspace{1ex} For each \spendDescription\nufive{ or \actionDescription}, the signer chooses a fresh \defining{\spendAuthRandomizer} $\AuthSignRandomizer$: +\vspace{-1ex} \begin{enumerate} \item Choose $\AuthSignRandomizer \leftarrowR \SpendAuthSigGenRandom{\maybeSapling}()$. + \vspace{-0.2ex} \item Let $\AuthSignRandomizedPrivate = \SpendAuthSigRandomizePrivate{\maybeSapling}(\AuthSignRandomizer, \AuthSignPrivate)$. + \vspace{-0.2ex} \item Let $\AuthSignRandomizedPublic = \SpendAuthSigDerivePublic{\maybeSapling}(\AuthSignRandomizedPrivate)$. + \vspace{-0.2ex} \item Generate a proof $\Proof{}$ of the \spendStatement (\crossref{spendstatement})\nufive{ or \actionStatement (\crossref{actionstatement})}, with $\AuthSignRandomizer$ in the \auxiliaryInput and $\AuthSignRandomizedPublic$ in the \primaryInput. + \vspace{-0.2ex} \item Let $\spendAuthSig = \SpendAuthSigSign{\maybeSapling}{\AuthSignRandomizedPrivate}(\SigHash)$. \end{enumerate} @@ -6916,13 +7095,18 @@ $\NoteUniqueRand$ and $\NoteNullifierRand$ are part of the \note; and $\cm$ is the \noteCommitment. -\pnote{The addition of $\PRFnf{Orchard}{\NullifierKey}(\NoteUniqueRand)$ and $\NoteNullifierRand$ -is intentionally done modulo $\ParamP{q}$, even though the scalar multiplication is on the \pallasCurve -which has scalar field $\GF{\ParamP{r}}$.} +\begin{pnotes} + \item The addition of $\PRFnf{Orchard}{\NullifierKey}(\NoteUniqueRand)$ and $\NoteNullifierRand$ + is intentionally done modulo $\ParamP{q}$, even though the scalar multiplication is on the + \pallasCurve which has scalar field $\GF{\ParamP{r}}$. + \item For correctness, the $\NoteUniqueRand$ and $\NoteNullifierRand$ inputs must always be + consistent with the \note committed to by $\cm$. +\end{pnotes} } %nufive +\vspace{-3ex} \securityrequirement{ -For each shielded protocol, the requirements on \nullifier derivation are as follows: +For each \shieldedProtocol, the requirements on \nullifier derivation are as follows: \begin{itemize} \item The derived \nullifier must be determined completely by the fields of @@ -6985,22 +7169,37 @@ \nusix{ \vspace{1.5ex} -Define $\totalDeferredOutput$ as in \crossref{subsidies}. +Define $\totalDeferredOutput$\nusixone{ and $\totalDeferredInput$} as in \shortcrossref{subsidies}. Then, consistent with \cite{ZIP-207}, the \defining{\DeferredChainValuePoolBalance} -for a \blockChain up to and including height $\BlockHeight$ is given by -$\ChainValuePoolBalance{Deferred}(\BlockHeight) := \sum_{\mathsf{h} = 0}^{\BlockHeight} \totalDeferredOutput(\mathsf{h})$. +for a \blockChain up to and including height $\BlockHeight$ is given by: +$$ +\ChainValuePoolBalance{Deferred}(\BlockHeight) := +\sum_{\mathsf{h} = 0}^{\BlockHeight} \totalDeferredOutput(\mathsf{h})\nusixone{\;-\;\totalDeferredInput(\mathsf{h})} +$$ + +\notnusixone{ +\vspace{-2ex} +\nnote{$\totalDeferredOutput(\mathsf{h})$ is necessarily zero for heights $\mathsf{h}$ prior to \NUSix activation.} +} %notnusixone +} %nusix + +\nusixone{ +\vspace{-2ex} +\consensusrule{If the \DeferredChainValuePoolBalance would become negative in the \blockChain +created as a result of accepting a \block, then all nodes \MUST reject the block as invalid.} \begin{nnotes} +\nusix{ \item $\totalDeferredOutput(\mathsf{h})$ is necessarily zero for heights $\mathsf{h}$ prior to \NUSix activation. - \item Currently there is no way to withdraw from the \deferredChainValuePool, so - there is no possibility of it going negative. Therefore, no consensus rule to - prevent that eventuality is needed at this time. -\end{nnotes} } %nusix + \item $\totalDeferredInput(\mathsf{h})$ is necessarily zero for heights $\mathsf{h}$ + prior to \NUSixOne activation. +\end{nnotes} +} %nusixone -\vspace{1ex} +\vspace{2ex} The \defining{\totalIssuedSupply} of a \blockChain at \blockHeight $\BlockHeight$ is given by the function: $$ @@ -7385,7 +7584,7 @@ \vspace{-0.5ex} \snarkcondition{Merkle path validity}{actionmerklepathvalidity} Either $\vOld{} = 0$; or $(\TreePath{}, \NotePosition)$ is a valid \merklePath of depth $\MerkleDepth{Orchard}$, -as defined in \crossref{merklepath}, from $\cmOld{}$ to the \anchor $\rt{Orchard}$. +as defined in \crossref{merklepath}, from $\ExtractP(\cmOld{})$ to the \anchor $\rt{Orchard}$. \snarkcondition{Value commitment integrity}{actionvaluecommitmentintegrity} $\cvNet{} = \ValueCommit{Orchard}{\ValueCommitRand}(\vOld{} - \vNew{})$. @@ -7492,7 +7691,7 @@ assumed to allow them to control the output. (The formal output of $\SinsemillaHashToPoint$ is $\bot$ in such a case, while the output computed by the circuit would be nondeterministic.) But as proven in \theoremref{thmsinsemillaex}, these exceptional cases allow immediately - finding a nontrivial discrete logarithm relation. If the \xDiscreteLogarithmProblem is hard on the + finding a nontrivial \discreteLogarithm relation. If the \DiscreteLogarithmProblem is hard on the \pallasCurve, then finding such a case is infeasible. \end{nnotes} } %nufive @@ -7555,7 +7754,7 @@ \vspace{-0.5ex} \item For $i \in \setofNew$, \begin{itemize} - \item Let $\TransmitPlaintext{i}$ be the \rawEncoding of $\NotePlaintext{i}$. + \item Let $\TransmitPlaintext{i} \typecolon \byteseq{585}$ be the \rawEncoding of $\NotePlaintext{i}$. \vspace{-0.5ex} \item Let $\DHSecret{i} = \KAAgree{Sprout}(\EphemeralPrivate, \TransmitPublicSub{i})$. \vspace{-0.5ex} @@ -7595,29 +7794,28 @@ \begin{formulae} \vspace{-0.5ex} \item let $\DHSecret{i} = \KAAgree{Sprout}(\TransmitPrivate, \EphemeralPublic)$ - \vspace{-0.5ex} + \vspace{-0.4ex} \item let $\TransmitKey{i} = \KDF{Sprout}(i, \hSig, \DHSecret{i}, \EphemeralPublic, \TransmitPublic)$ + \vspace{-0.3ex} + \item let $\TransmitPlaintext{i} = \SymDecrypt{\TransmitKey{i}}(\TransmitCiphertext{i})$ \vspace{-0.5ex} - \item return $\DecryptNoteSprout(\TransmitKey{i}, \TransmitCiphertext{i}, \cm_i, \AuthPublic).$ + \item if $\TransmitPlaintext{i} = \bot$, return $\bot$ + \vspace{-0.4ex} + \item return $\ExtractNote{Sprout}(\TransmitPlaintext{i}, \cm_i, \AuthPublic).$ \end{formulae} \introlist -$\DecryptNoteSprout(\TransmitKey{i}, \TransmitCiphertext{i}, \cm_i, \AuthPublic)$ +$\ExtractNote{Sprout}(\TransmitPlaintext{i} \typecolon \byteseq{585}, \cm_i \typecolon \byteseq{32}, \AuthPublic \typecolon \PRFOutputSprout)$ is defined as follows: \begin{formulae} - \vspace{-0.4ex} - \item let $\TransmitPlaintext{i} = -\SymDecrypt{\TransmitKey{i}}(\TransmitCiphertext{i})$ - \vspace{-0.6ex} - \item if $\TransmitPlaintext{i} = \bot$, return $\bot$ - \vspace{-1.5ex} + \vspace{-1ex} \item extract $\NotePlaintext{i} = (\NotePlaintextLeadByte_i \typecolon \byte, \Value_i \typecolon \ValueType, \NoteUniqueRand_i \typecolon \PRFOutputSprout, \NoteCommitRand_i \typecolon \NoteCommitTrapdoor{Sprout}, \Memo_i \typecolon \MemoType)$ from $\TransmitPlaintext{i}$ - \vspace{-0.5ex} + \vspace{-0.4ex} \item let $\NoteTuple{i} = (\AuthPublic, \Value_i, \NoteUniqueRand_i, \NoteCommitRand_i)$ \vspace{-0.5ex} \item if $\NotePlaintextLeadByte_i \neq \hexint{00}$ or $\NoteCommitment{Sprout}(\NoteTuple{i}) \neq \cm_i$, return $\bot$ @@ -7706,9 +7904,9 @@ \extralabel{saplingencrypt}{\lsubsubsection{Encryption (\SaplingAndOrchardText)}{saplingandorchardencrypt}} \vspace{-1ex} -Let $\DiversifiedTransmitPublic \typecolon \KAPublicPrimeSubgroup{}$ be the +Let $\DiversifiedTransmitPublic \typecolon \KAPublicPrimeOrder{}$ be the \diversifiedTransmissionKey for the intended recipient address of a new \SaplingOrOrchard \note, -and let $\DiversifiedTransmitBase \typecolon \KAPublicPrimeSubgroup{}$ be the corresponding +and let $\DiversifiedTransmitBase \typecolon \KAPublicPrimeOrder{}$ be the corresponding \diversifiedBase computed as $\DiversifyHash{}(\Diversifier)$. Since \Sapling \note encryption is used only in the context of \crossref{saplingsend}\nufive{, and similarly @@ -7746,9 +7944,9 @@ \item \tab choose random $\OutCipherKey \leftarrowR \Keyspace$ and $\OutPlaintext \leftarrowR \byteseq{(\ellG{} + 256)/8}$ \item else: \item \tab let $\cvField = \LEBStoOSP{\ellG{}}\big(\reprG{}(\cv)\kern-0.12em\big)$ - \vspace{-0.25ex} + \vspace{-0.3ex} \item \tab let $\cmstarField = \LEBStoOSP{256}\big(\ExtractG(\cm)\kern-0.12em\big)$ - \vspace{-0.25ex} + \vspace{-0.3ex} \item \tab let $\OutCipherKey = \PRFock{}{\OutViewingKey}(\cvField, \cmstarField, \ephemeralKey)$ \vspace{0.25ex} \item \tab let $\OutPlaintext = \LEBStoOSPOf{\ellG{} + 256}{\reprG{}(\DiversifiedTransmitPublic) \,\bconcat\, \ItoLEBSPOf{256}{\EphemeralPrivate}\kern-0.12em}$ @@ -7785,16 +7983,17 @@ $u$-coordinate\nufive{ or \affineSW $x$-coordinate} of the \noteCommitment, i.e.\ $\ExtractG(\cm)$.) \canopy{ -Let the constants $\CanopyActivationHeight$ and $\ZIPTwoOneTwoGracePeriod$ be as defined in \crossref{constants}. +Let $\Protocol$ and $\AllowedLeadBytes$ be as defined in \crossref{noteptconcept}. -Let $\BlockHeight$ be the \blockHeight of the \block containing this \transaction. +Let $\BlockHeight$ be the \blockHeight of the \block containing this \transaction, and +let $\TxVersion$ be the \transactionVersionNumber. } %canopy \introsection The recipient will attempt to decrypt the $\ephemeralKey$ and $\TransmitCiphertext{}$ components of the \noteCiphertext: \begin{algorithm} - \vspace{-0.5ex} + \vspace{-0.2ex} \item let $\EphemeralPublic = \abstG{}\Of{\ephemeralKey}\,$. if $\EphemeralPublic = \bot$, return $\bot$ \vspace{-0.3ex} \item let $\DHSecret{} = \KAAgree{}(\InViewingKey, \EphemeralPublic)$ @@ -7805,23 +8004,22 @@ \item extract $\NotePlaintext{} = (\NotePlaintextLeadByte \typecolon \byte, \Diversifier \typecolon \DiversifierType, \Value \typecolon \ValueType, \NoteCommitRandBytesOrSeedBytes \typecolon \NoteSeedBytesType, \Memo \typecolon \MemoType)$ from $\TransmitPlaintext{}$ - \precanopyitem{if $\NotePlaintextLeadByte \neq \hexint{01}$, return $\bot$} - \vspace{-0.2ex} - \precanopyitem{let $\NoteCommitRandBytes = \NoteSeedBytes$} - \canopyonwarditem{if $\BlockHeight < \CanopyActivationHeight + \ZIPTwoOneTwoGracePeriod \text{ and } \NotePlaintextLeadByte \not\in \setof{\hexint{01}, \hexint{02}}$, return $\bot$} - \canopyonwarditem{if $\BlockHeight \geq \CanopyActivationHeight + \ZIPTwoOneTwoGracePeriod \text{ and } \NotePlaintextLeadByte \neq \hexint{02}$, return $\bot$} - \canopyonwarditem{for \Sapling, let $\NoteCommitRandPre = [4]$ and $\EphemeralPrivatePre = [5]$} + \item if $\NotePlaintextLeadByte \not\in \AllowedLeadBytes^{\Protocol}(\BlockHeight, \TxVersion)$, return $\bot$ +\notbeforecanopy{ + \item \canopy{for \Sapling, let $\NoteCommitRandPre = [4]$ and $\EphemeralPrivatePre = [5]$} +} %notbeforecanopy \nufive{ \item for \Orchard, let $\NoteUniqueRandBytes = \ItoLEOSP{256}\big(\nfOld{}$ from the same \actionDescription$\kern-0.2em\big)\kern-0.08em$, $\NoteCommitRandPre = [5] \bconcat \NoteUniqueRandBytes$, and $\EphemeralPrivatePre = [4] \bconcat \NoteUniqueRandBytes$ } %nufive - \canopyonwarditem{let $\NoteCommitRandBytes = \begin{cases} - \NoteSeedBytes,&\caseif \NotePlaintextLeadByte = \hexint{01} \\ - \ToScalar{}\big(\PRFexpand{\NoteSeedBytes}(\NoteCommitRandPre)\kern-0.1em\big),&\caseotherwise - \end{cases}$} - \item let $\NoteCommitRand = \LEOStoIPOf{256}{\NoteCommitRandBytes}$ - and $\DiversifiedTransmitBase = \DiversifyHash{}(\Diversifier)$. - if $\NoteCommitRand \geq \ParamG{r}$ or\notbeforenufive{ (for \Sapling)} $\DiversifiedTransmitBase = \bot$, return $\bot$ + \item let $\NoteCommitRand = \notcanopy{\LEOStoIP{256}(\NoteCommitRandBytes)}\canopy{\begin{cases} + \LEOStoIP{256}(\NoteSeedBytes),&\caseif \NotePlaintextLeadByte = \hexint{01} \\ + \ToScalar{}\big(\PRFexpand{\NoteSeedBytes}(\NoteCommitRandPre)\kern-0.1em\big),&\caseotherwise + \end{cases}}$ + \item if $\NoteCommitRand \geq \ParamG{r}$, return $\bot$ + \vspace{-0.2ex} + \item let $\DiversifiedTransmitBase = \DiversifyHash{}(\Diversifier)$. + if\notbeforenufive{ (for \Sapling)} $\DiversifiedTransmitBase = \bot$, return $\bot$ \canopyonwarditem{if $\NotePlaintextLeadByte \neq \hexint{01}$:} \canopy{ \vspace{-0.2ex} @@ -7886,7 +8084,7 @@ \sapling{ \vspace{-3ex} -\extralabel{saplingdecryptovk}{\lsubsubsection{Decryption using a Full Viewing Key (\SaplingAndOrchardText)}{decryptovk}} +\extralabel{saplingdecryptovk}{\lsubsubsection{Decryption using an Outgoing Viewing Key (\SaplingAndOrchardText)}{decryptovk}} \vspace{-1ex} Let $\OutViewingKey \typecolon \OutViewingKeyType$ be the \outgoingViewingKey, as specified @@ -7899,7 +8097,8 @@ Let the constants $\CanopyActivationHeight$ and $\ZIPTwoOneTwoGracePeriod$ be as defined in \crossref{constants}. \vspace{-0.4ex} -Let $\BlockHeight$ be the \blockHeight of the \block containing this \transaction. +Let $\BlockHeight$ be the \blockHeight of the \block containing this \transaction, and +let $\TxVersion$ be the \transactionVersionNumber. } %canopy \vspace{-0.5ex} @@ -7931,7 +8130,7 @@ and $\DiversifiedTransmitPublic = \abstG{}\Of{\DiversifiedTransmitPublicRepr}$ \vspace{-0.2ex} \item if $\EphemeralPrivate \geq \ParamG{r}$ or $\DiversifiedTransmitPublic = \bot$, return $\bot$ - \nufiveonwarditem{if $\reprP\big(\DiversifiedTransmitPublic\big) \neq \DiversifiedTransmitPublicRepr$, return $\bot$} + \item if $\reprP\big(\DiversifiedTransmitPublic\big) \neq \DiversifiedTransmitPublicRepr$, return $\bot$ \vspace{-0.2ex} \item let $\DHSecret{} = \KAAgree{}(\EphemeralPrivate, \DiversifiedTransmitPublic)$ \vspace{-0.2ex} @@ -7942,25 +8141,24 @@ \item extract $\NotePlaintext{} = (\NotePlaintextLeadByte \typecolon \byte, \Diversifier \typecolon \DiversifierType, \Value \typecolon \ValueType, \NoteCommitRandBytesOrSeedBytes \typecolon \NoteSeedBytesType, \Memo \typecolon \MemoType)$ from $\TransmitPlaintext{}$ - \precanopyitem{if $\NotePlaintextLeadByte \neq \hexint{01}$, return $\bot$} - \precanopyitem{let $\NoteCommitRandBytes = \NoteSeedBytes$} - \canopyonwarditem{if $\BlockHeight < \CanopyActivationHeight + \ZIPTwoOneTwoGracePeriod \text{ and } \NotePlaintextLeadByte \not\in \setof{\hexint{01}, \hexint{02}}$, return $\bot$} - \canopyonwarditem{if $\BlockHeight \geq \CanopyActivationHeight + \ZIPTwoOneTwoGracePeriod \text{ and } \NotePlaintextLeadByte \neq \hexint{02}$, return $\bot$} - \canopyonwarditem{for \Sapling, let $\NoteCommitRandPre = [4]$ and $\EphemeralPrivatePre = [5]$} + \item if $\NotePlaintextLeadByte \not\in \AllowedLeadBytes^{\Protocol}(\BlockHeight, \TxVersion)$, return $\bot$ +\notbeforecanopy{ + \item \canopy{for \Sapling, let $\NoteCommitRandPre = [4]$ and $\EphemeralPrivatePre = [5]$} +} %notbeforecanopy \nufive{ \item for \Orchard, let $\NoteUniqueRandBytes = \ItoLEOSP{256}\big(\nfOld{}$ from the same \actionDescription$\kern-0.2em\big)\kern-0.08em$, $\NoteCommitRandPre = [5] \bconcat \NoteUniqueRandBytes$, and $\EphemeralPrivatePre = [4] \bconcat \NoteUniqueRandBytes$ } %nufive \canopyonwarditem{if $\NotePlaintextLeadByte \neq \hexint{01}$ and $\ToScalar{}\big(\PRFexpand{\NoteSeedBytes}(\EphemeralPrivatePre)\kern-0.1em\big) \neq \EphemeralPrivate$, return $\bot$} \vspace{-0.2ex} - \canopyonwarditem{let $\NoteCommitRandBytes = \begin{cases} - \NoteSeedBytes,&\caseif \NotePlaintextLeadByte = \hexint{01} \\ - \ToScalar{}\big(\PRFexpand{\NoteSeedBytes}(\NoteCommitRandPre)\kern-0.1em\big),&\caseotherwise - \end{cases}$} - \item let $\NoteCommitRand = \LEOStoIPOf{256}{\NoteCommitRandBytes}$ - and $\DiversifiedTransmitBase = \DiversifyHash{}(\Diversifier)$ + \item let $\NoteCommitRand = \notcanopy{\LEOStoIP{256}(\NoteCommitRandBytes)}\canopy{\begin{cases} + \LEOStoIP{256}(\NoteSeedBytes),&\caseif \NotePlaintextLeadByte = \hexint{01} \\ + \ToScalar{}\big(\PRFexpand{\NoteSeedBytes}(\NoteCommitRandPre)\kern-0.1em\big),&\caseotherwise + \end{cases}}$ + \item if $\NoteCommitRand \geq \ParamG{r}$, return $\bot$ \vspace{-0.2ex} - \item if $\NoteCommitRand \geq \ParamG{r}$ or\notbeforenufive{ (for \Sapling)} $\DiversifiedTransmitBase = \bot$ or $\DiversifiedTransmitPublic \not\in \SubgroupJstar$ (see note below), return $\bot$ + \item let $\DiversifiedTransmitBase = \DiversifyHash{}(\Diversifier)$. + if\notbeforenufive{ (for \Sapling)} $\DiversifiedTransmitBase = \bot$ or $\DiversifiedTransmitPublic \not\in \SubgroupJstar$ (see note below), return $\bot$ \item \notbeforenufive{for \Sapling,} let $\NoteTuple{} = (\Diversifier, \DiversifiedTransmitPublic, \Value, \NoteCommitRand)$ \vspace{-0.2ex} \nufive{ @@ -8004,10 +8202,10 @@ compressed encodings of \jubjubCurve points. Therefore, an implementation \MUST use the original $\ephemeralKey$ field as encoded in the \transaction as input to $\PRFock{}{}$ and $\KDF{Sapling}$, and in the comparison against - $\reprG{}\big(\KADerivePublic{Sapling}(\EphemeralPrivate, \DiversifiedTransmitBase)\kern-0.12em\big)$\rlap{.}\nufive{\; For + $\reprG{}\kern-0.1em\big(\KADerivePublic{Sapling}(\EphemeralPrivate, \DiversifiedTransmitBase)\kern-0.12em\big)$\rlap{\kern-0.1em.}\nufive{\; For consistency this is also what is specified for \Orchard.}\vspace{-0.6ex} \item For \Sapling \outgoingCiphertexts, $\DiversifiedTransmitPublicRepr$ could also be \nonCanonicalPoint. - After \NUFive activation, the above algorithm explicitly returns $\bot$ if + The above algorithm explicitly returns $\bot$ if $\reprP\big(\DiversifiedTransmitPublic\big) \neq \DiversifiedTransmitPublicRepr$. However, this is technically redundant with the later check that returns $\bot$ if $\DiversifiedTransmitPublic \not\in \smash{\SubgroupJstar}$, because only \smallOrderAdjective \jubjubCurve @@ -8702,8 +8900,8 @@ \item Suppose that $\GroupJHash{}$ (restricted to inputs for which it does not return $\bot$) is modelled as a \randomOracle from \diversifiers to points of order $\ParamJ{r}$ on the \jubjubCurve. In this model, Unlinkability - of $\DiversifyHash{Sapling}$ holds under the \xDecisionalDiffieHellman assumption on the - \primeOrderSubgroup of points on the \jubjubCurve. + of $\DiversifyHash{Sapling}$ holds under the \DecisionalDiffieHellmanAssumption + on the \primeOrderSubgroup of points on the \jubjubCurve. To prove this, consider the ElGamal encryption scheme \cite{ElGamal1985} on this \primeOrderSubgroup, restricted to encrypting plaintexts encoded @@ -8722,11 +8920,10 @@ of the candidate \diversifiedPaymentAddresses.) So if ElGamal is \keyPrivate, then $\DiversifyHash{Sapling}$ is Unlinkable under the same conditions. - \cite[Appendix A]{BBDP2001} gives a security proof for \keyPrivacy - (both \nh{IK-CPA} and \nh{IK-CCA}) of ElGamal under the \xDecisionalDiffieHellman - assumption on the relevant group. (In fact the proof needed is the - ``small modification'' described in the last paragraph in which the generator - is chosen at random for each key.) + \cite[Appendix A]{BBDP2001} gives a security proof for \keyPrivacy (both \nh{IK-CPA} + and \nh{IK-CCA}) of ElGamal under the \DecisionalDiffieHellmanAssumption on the + relevant group. (In fact the proof needed is the ``small modification'' described in + the last paragraph in which the generator is chosen at random for each key.) \item It is assumed (also for the security of other uses of the group hash, such as Pedersen hashes and commitments) that the discrete @@ -8780,7 +8977,7 @@ $\PedersenHash$ is an algebraic \hashFunction with \collisionResistance (for fixed input length) derived from assumed hardness of the -\xDiscreteLogarithmProblem on the \jubjubCurve. +\DiscreteLogarithmProblem on the \jubjubCurve. It is based on the work of David Chaum, Ivan Damgård, Jeroen van de Graaf, Jurgen Bos, George Purdy, Eugène van Heijst and Birgit Pfitzmann in \cite{CDvdG1987}, \cite{BCP1988} and \cite{CvHP1991}, @@ -8957,7 +9154,7 @@ \vspace{-2ex} \defining{$\SinsemillaHash$} is an algebraic \hashFunction with \collisionResistance (for fixed input length) derived from assumed hardness -of the \xDiscreteLogarithmProblem. It is designed by Sean Bowe and \nh{Daira-Emma} Hopwood. +of the \DiscreteLogarithmProblem. It is designed by Sean Bowe and \nh{Daira-Emma} Hopwood. The motivation for introducing a new discrete-logarithm-based hash function (rather than using $\PedersenHash$) is to make efficient use of the lookups available in recent proof systems including \HaloTwo. @@ -9077,7 +9274,7 @@ \vspace{-2.5ex} We show a correspondence between Sinsemilla and a vector Pedersen hash, which allows using the security argument from \cite{BGG1995} to show that collision-resistance can be tightly reduced -to the \xDiscreteLogarithmProblem in $\mathbb{P}$. +to the \DiscreteLogarithmProblem in $\mathbb{P}$. \vspace{1ex} Define $\delta(a, b) = \begin{cases} @@ -9111,7 +9308,7 @@ Let $D \typecolon \byteseqs$ be a personalization input, and let $\ell \typecolon \range{0}{k \mult c}$. Finding a collision $M, M' \typecolon \bitseq{\ell}$ with $M \neq M'$ such that $\SinsemillaHashToPoint(D, M) = \SinsemillaHashToPoint(D, M') \neq \bot$ efficiently yields a nontrivial -discrete logarithm relation, and similarly for $\SinsemillaHash(D, M) = \SinsemillaHash(D, M') \neq \bot$. +\discreteLogarithm relation, and similarly for $\SinsemillaHash(D, M) = \SinsemillaHash(D, M') \neq \bot$. \end{theorem} \begin{proof} @@ -9132,9 +9329,9 @@ The fixed offset does not affect \collisionResistance in this context. (See below for why it cannot be eliminated for $\SinsemillaHash$, or when using incomplete addition.) \theoremref{thmsinsemillaex} will prove that a $\bot$ output from $\SinsemillaHashToPoint$ -yields a nontrivial discrete log relation. It follows that the \collisionResistance of +yields a nontrivial \discreteLogarithm relation. It follows that the \collisionResistance of $\SinsemillaHashToPoint$ can be tightly reduced, via the proof in \cite[Appendix A]{BGG1995}, -to the \xDiscreteLogarithmProblem over $\GroupP$. +to the \DiscreteLogarithmProblem over $\GroupP$. Note that \cite{BGG1995} requires for their main scheme that the scalars are nonzero, which is not necessarily the case in our context. However, their proof in Appendix A does not depend @@ -9146,7 +9343,7 @@ Now we consider $\SinsemillaHash$. We want to prove that, for given $D$, if we can find two distinct messages $M$ and $M'$ such that $\ExtractPbot\smash{\big(\SinsemillaHashToPoint(D, M)\kern-0.1em\big)} = \ExtractPbot\smash{\big(\SinsemillaHashToPoint(D, M')\kern-0.1em\big)} \neq \bot$ then we can efficiently -extract a discrete logarithm. +extract a \discreteLogarithm. The inputs to $\ExtractPbot$ are not $\bot$, therefore they are in $\GroupP$. $\ExtractPbot$ maps $P, Q \in \GroupP$ to the same output if and only if $P = \pm Q$. @@ -9162,12 +9359,12 @@ \vspace{1ex} Because $2^{n+1} \leq \ParamP{r}-1$, the coefficients $\!\!\pmod{\ParamP{r}}$ are not all zero, and therefore -this is a nontrivial discrete logarithm relation between independent bases. +this is a nontrivial \discreteLogarithm relation between independent bases. \end{proof} \begin{nnotes} - \item \cite[Lemma 3]{JT2020} proves a tight reduction from finding a nontrivial discrete logarithm - relation in a \primeOrderGroup to solving the \xDiscreteLogarithmProblem in that group. + \item \cite[Lemma 3]{JT2020} proves a tight reduction from finding a nontrivial \discreteLogarithm + relation in a \primeOrderGroup to solving the \DiscreteLogarithmProblem in that group. \item The above theorem easily extends to the case where additional scalar multiplication terms with independent bases may be added to the $\SinsemillaHashToPoint$ output before applying $\ExtractPbot$. This is needed to show security of the $\SinsemillaShortCommitAlg$ \commitmentScheme defined in @@ -9181,7 +9378,7 @@ \introsection \theoremlabel{thmsinsemillaex} -\begin{theorem}[A $\bot$ output from $\SinsemillaHashToPoint$ yields a nontrivial discrete log relation]\end{theorem} +\begin{theorem}[$\SinsemillaHashToPoint(\ldots) = \bot$ yields a nontrivial \discreteLogarithm relation]\end{theorem} \begin{proof} For convenience of reference, we repeat the algorithm for $\SinsemillaHashToPoint$ in terms @@ -9212,7 +9409,7 @@ \vspace{-0.5ex} $\Acc_i$ has a representation $\scalarmult{2^i}{\SinsemillaGenInit(D)} + \ssum{j=0}{2^k - 1} \,\scalarmult{X_{i,j+1}}{\SinsemillaGenBase(j)}$ for some $X_i \typecolon \typeexp{\binaryrange{i}}{2^j}$. -So given $m$ that results in an exceptional case, the nontrivial discrete logarithm relation +So given $m$ that results in an exceptional case, the nontrivial \discreteLogarithm relation $\scalarmult{\alpha \mult 2^i}{\SinsemillaGenInit(D)} + \Big(\ssum{j=0}{\smash{2^k - 1}} \,\scalarmult{\alpha \mult X_{i,j+1}}{\SinsemillaGenBase(j)}\kern-0.15em\Big) + \SinsemillaGenBase(m_i) = \ZeroP$ is easily computable from $m$. The coefficients in this representation do not overflow since $X_{i,j+1} < 2^i$ for all $i \in \range{1}{n}$ and $j \in \binaryrange{k}$; and @@ -9220,10 +9417,10 @@ \end{proof} \vspace{-0.5ex} -Similarly, a $\bot$ output from $\SinsemillaHash$ yields a nontrivial discrete logarithm relation, +Similarly, a $\bot$ output from $\SinsemillaHash$ yields a nontrivial \discreteLogarithm relation, because $\ExtractPbot$ only returns $\bot$ when its input is $\bot$. -Since by assumption it is hard to find a nontrivial discrete logarithm relation, +Since by assumption it is hard to find a nontrivial \discreteLogarithm relation, we can argue that it is safe to use incomplete additions when computing Sinsemilla inside a circuit. } %nufive @@ -9302,7 +9499,7 @@ against a potential discrete-log-breaking adversary. Given the weak assumption that the $\PoseidonHash$ sponge produces output that preserves sufficient entropy from the inputs $\NullifierKey$ and $\NoteUniqueRand$, this nullifier - construction would still be secure under a \xDecisionalDiffieHellman assumption + construction would still be secure under a \DecisionalDiffieHellmanAssumption on the \Pallas curve, even if the $\Poseidon$-based PRF were distinguishable from an ideal PRF. \item The constant $2^{65}$ comes from \cite[section 4.2]{GKRRS2019}: @@ -9752,7 +9949,7 @@ Define $\KAPublic{Sapling} := \GroupJ$. -Define $\KAPublicPrimeSubgroup{Sapling} := \SubgroupJ$. +Define $\KAPublicPrimeOrder{Sapling} := \SubgroupJstar$. Define $\KASharedSecret{Sapling} := \SubgroupJ$. @@ -9808,6 +10005,8 @@ Define $\KAPublic{Orchard} := \GroupPstar$. +Define $\KAPublicPrimeOrder{Orchard} := \GroupPstar$. + Define $\KASharedSecret{Orchard} := \GroupPstar$. Define $\KAPrivate{Orchard} := \GFstar{\ParamP{r}}$. @@ -10131,11 +10330,12 @@ \begin{pnotes} \vspace{-0.25ex} \item The validation algorithm \emph{does not} check that $\RedDSASigR{}$ is a point of order -at least $\ParamG{r}$. + at least $\ParamG{r}$. \nufive{ \vspace{-0.5ex} - \item After activation of \cite{ZIP-216}, validation returns $0$ if $\RedDSAReprR{}$ is a - \nonCanonicalPoint compressed point encoding. + \item After the activation of \cite{ZIP-216} with \NUFive, validation returns $0$ if $\RedDSAReprR{}$ + is a \nonCanonicalPoint compressed point encoding. This change is also retrospectively valid + on \Mainnet and \Testnet before \NUFive. } \vspace{-0.5ex} \item The value $\RedDSAReprR{}$ used as part of the input to $\RedDSAHashToScalar$ \MUST be exactly @@ -10272,7 +10472,7 @@ \vspace{-2ex} \securityrequirement{ \nufive{Each instantiation of} $\BindingSig{}$ must be a \nh{SUF-CMA-secure} \keyMonomorphicSignatureScheme -as defined in \crossref{abstractsigmono}. A signature must prove knowledge of the discrete logarithm of +as defined in \crossref{abstractsigmono}. A signature must prove knowledge of the \discreteLogarithm of the \validatingKey with respect to the base $\ValueCommitRandBase{Sapling}$\nufive{ or $\ValueCommitRandBase{Orchard}$}. } %securityrequirement @@ -10532,7 +10732,7 @@ \vspace{1ex} The probability of $\SinsemillaHashToPoint$ returning $\bot$ is insignificant -(and would yield a nontrivial discrete logarithm relation). +(and would yield a nontrivial \discreteLogarithm relation). The \binding property of $\SinsemillaCommitAlg$ follows from \collisionResistance of $\SinsemillaHashToPoint$ proven in \theoremref{thmsinsemillacr}, given that $\GroupPHash\Of{D \bconcat \ascii{-r}, \ascii{}}$ is independent of any of the bases @@ -10611,7 +10811,7 @@ $\NoteCommitAlg{Orchard}$ in this specification, the implementation in the \actionCircuit constrains the result to an unspecified set of values when an input results in an exceptional case for any incomplete addition. If this - occurs then it yields a nontrivial discrete logarithm relation for the + occurs then it yields a nontrivial \discreteLogarithm relation for the \pallasCurve, as proven in \theoremref{thmsinsemillaex}. We can therefore assume that it is infeasible to find such inputs with nonnegligible probability. \item There are also no points in $\GroupP$ with \affineSW $x$-coordinate @@ -12062,10 +12262,10 @@ be as defined in \crossref{endian}. A \Sapling{} \defining{\shieldedPaymentAddress} consists of $\Diversifier \typecolon \DiversifierType$ -and $\DiversifiedTransmitPublic \typecolon \KAPublicPrimeSubgroup{Sapling}$. +and $\DiversifiedTransmitPublic \typecolon \KAPublicPrimeOrder{Sapling}$. $\DiversifiedTransmitPublic$ is an encoding of a $\KA{Sapling}$ \publicKey of type -$\KAPublicPrimeSubgroup{Sapling}$, for use with the encryption scheme defined in +$\KAPublicPrimeOrder{Sapling}$, for use with the encryption scheme defined in \crossref{saplinginband}. $\Diversifier$~is a \diversifier. These components are derived as described in \crossref{saplingkeycomponents}. @@ -12086,12 +12286,20 @@ \end{itemize} When decoding the representation of $\DiversifiedTransmitPublic$, the address \MUST be -considered invalid if $\abstJ$ returns $\bot$. +considered invalid if $\abstJ$ returns $\bot$, or the encoding of $\DiversifiedTransmitPublic$ +is a \nonCanonicalPoint encoding as defined in \crossref{abstractgroup}, or the resulting +$\DiversifiedTransmitPublic$ is not in $\SubgroupJstar$. -\nufive{\cite{ZIP-216} specifies that the address \MUST also be considered invalid if the -resulting $\DiversifiedTransmitPublic$ is not in the \primeOrderSubgroup $\SubgroupJ$, or -if it is a \nonCanonicalPoint encoding as defined in \crossref{abstractgroup}. This \MAY be -enforced in advance of activation of \NUFive.} +\begin{nnotes} + \item There are no \nonCanonicalPoint encodings of \jubjubCurve points in $\SubgroupJstar$. + \item The restriction on $\DiversifiedTransmitPublic$ reflects its current type + $\KAPublicPrimeOrder{Sapling} = \SubgroupJstar$. In versions of this specification + prior to \historyref{2025.6.0}, $\DiversifiedTransmitPublic$ had type + $\KA{Sapling}\mathsf{.PublicPrimeSubgroup} = \SubgroupJ$, i.e. including $\ZeroJ$. + Implementations of consumers for this encoding may need to be updated to exclude + $\ZeroJ$, and should be checked for consistency with the current version of + \cite{ZIP-216}. +\end{nnotes} \vspace{1ex} For addresses on \Mainnet, the \defining{\humanReadablePart} (as defined in \cite{ZIP-173}) is \ascii{zs}. @@ -12136,6 +12344,18 @@ For \incomingViewingKeys on \Mainnet, the \humanReadablePart is \ascii{zivks}. For \incomingViewingKeys on \Testnet, the \humanReadablePart is \ascii{zivktestsapling}. + +\begin{nnotes} + \item The \diversifierKey is not present in this encoding, so it does not provide + sufficient information to decrypt the \diversifier to obtain a \diversifierIndex. + This encoding is therefore deprecated: the preferred way to encode a \Sapling + \incomingViewingKey is as a component of a \unifiedIncomingViewingKey using the + \IVKEncoding specified in \cite{ZIP-316}, which does include the \diversifierKey. + \item In versions of this specification prior to \historyref{2025.6.0}, the range + of $\InViewingKey$ was defined as $\binaryrange{\InViewingKeyLength{Sapling}}$, + i.e.\ including $0$. Implementations of consumers for this encoding may need + to be updated to exclude $0$. +\end{nnotes} } %sapling @@ -12268,10 +12488,10 @@ Let $\KA{Orchard}$ be as defined in \crossref{concreteorchardkeyagreement}. An \Orchard{} \defining{\shieldedPaymentAddress} consists of $\Diversifier \typecolon \DiversifierType$ -and $\DiversifiedTransmitPublic \typecolon \KAPublic{Orchard}$. +and $\DiversifiedTransmitPublic \typecolon \KAPublicPrimeOrder{Orchard}$. $\DiversifiedTransmitPublic$ is an encoding of a $\KA{Orchard}$ \publicKey of type -$\KAPublic{Orchard}$, for use with the encryption scheme defined in \crossref{saplingandorchardinband}. +$\KAPublicPrimeOrder{Orchard}$, for use with the encryption scheme defined in \crossref{saplingandorchardinband}. $\Diversifier$~is a sequence of $11$ bytes. These components are derived as described in \crossref{orchardkeycomponents}. @@ -12386,9 +12606,9 @@ \vspace{-1.5ex} When decoding this representation, the key \MUST be considered invalid if $\AuthSignPublic$, $\NullifierKey$, or $\CommitIvkRand$ are not canonically encoded elements of their respective -fields, or if $\AuthSignPublic$ is not a valid \Pallas $x$-coordinate, or if either the -external or internal \incomingViewingKeys derived as specified in \crossref{orchardkeycomponents} -are $0$ or $\bot$. +fields, or if $\AuthSignPublic$ is not a valid affine $x$-coordinate of a \pallasCurve point +in $\GroupPstar$, or if either the external or internal \incomingViewingKeys derived as specified +in \crossref{orchardkeycomponents} are $0$ or $\bot$. There is no \BechOptm encoding defined for an individual \Orchard \fullViewingKey; instead use a \unifiedFullViewingKey as defined in \cite{ZIP-316}. @@ -12529,17 +12749,22 @@ \cite{ZIP-212}, \cite{ZIP-213}, and \cite{ZIP-221}. Additional information and rationale is given in \cite{Zcash-Orchard} and \cite{Zcash-halo2}.} -\nusix{ -This draft specification describes the set of changes proposed for the \NUSix \networkUpgrade, -for which the \Mainnet activation \blockHeight has been set at $2726400$. Its specifications are -described in this document, \cite{ZIP-253}, \cite{ZIP-236}, and \cite{ZIP-2001}, with updates to -\cite{ZIP-207} and \cite{ZIP-214}. +\nusix{A seventh upgrade, called \defining{\NUSix}, activated on \Mainnet on 23~November, 2024 +at \blockHeight $2726400$ (coinciding with the second \blockSubsidy \halving) \cite{Zcash-Nu6}. +Its specifications are described in this document, \cite{ZIP-253}, \cite{ZIP-236}, and +\cite{ZIP-2001}, with updates to \cite{ZIP-207} and \cite{ZIP-214}. Additional information and rationale is given in \cite{ZIP-1015}.} +\nusixone{This draft specification describes the set of changes proposed for the \NUSixOne +\networkUpgrade \cite{Zcash-Nu6.1}, for which the \Mainnet activation \blockHeight has not +yet been set. Its specifications are described in this document, +\cite{ZIP-255}, and \cite{ZIP-271}, with updates to \cite{ZIP-214}. +Additional information and rationale is given in \cite{ZIP-1016}.} + \introlist -\vspace{2ex} +\vspace{1.5ex} This section summarizes the strategy for upgrading from \Sprout to subsequent versions -of the protocol (\Overwinter, \Sapling, \Blossom, \Heartwood, \Canopy, \NUFive, and \NUSix), +of the protocol (\Overwinter, \Sapling, \Blossom, \Heartwood, \Canopy, \NUFive, \NUSix, and \NUSixOne), and for future upgrades. \defining{The \networkUpgrade mechanism is described in \cite{ZIP-200}.} @@ -12558,12 +12783,13 @@ \activationHeight. \end{itemize} +\vspace{-1ex} Full support for each \networkUpgrade is indicated by a minimum version of the \peerToPeerProtocol. At the planned \activationHeight, nodes that support a given upgrade will disconnect from (and will not reconnect to) nodes with a protocol version lower than this -minimum. \overwinter{See \cite{ZIP-201} for how this applies to the \Overwinter -upgrade, for example.} +minimum. See \cite{ZIP-201} for how this applies to the \Overwinter +upgrade, for example. This ensures that upgrade-supporting nodes transition cleanly from the old protocol to the new protocol. Nodes that do not @@ -12879,7 +13105,8 @@ $\BindingPublic{Sapling}$ of $\SigHash$ --- i.e.\ $\BindingSigValidate{Sapling}{\BindingPublic{Sapling}}(\SigHash, \bindingSig{Sapling}) = 1$. \nufiveonward{As specified in \crossref{concretereddsa}, the validation of the $\RedDSAReprR{}$ - component of the signature changes to prohibit \nonCanonicalPoint encodings.} + component of the signature changes to prohibit \nonCanonicalPoint encodings. This change + is also retrospectively valid on \Mainnet and \Testnet before \NUFive.} \end{itemize}} \vspace{-1ex} \saplingonwarditem{If $\effectiveVersion = 4$ and there are no \spendDescriptions or \outputDescriptions, @@ -12895,14 +13122,15 @@ of the signature prohibits \nonCanonicalPoint encodings. \end{itemize}} \vspace{-1ex} - \item \nusix{Let $\totalDeferredOutput$ be as defined in \shortcrossref{subsidies}.} + \item \nusix{Let $\totalDeferredOutput$\nusixone{ and $\totalDeferredInput$} be as defined in \shortcrossref{subsidies}.} For the \block at \blockHeight $\mathsf{height}$: \begin{itemize} \item define the \totalOutputValue of its \coinbaseTransaction to be the total value in \zatoshi of its \transparentOutputs\heartwood{, minus $\vBalance{Sapling}$}\nufive{, minus $\vBalance{Orchard}$}\nusix{, plus $\totalDeferredOutput(\mathsf{height})$}; \item define the \totalInputValue of its \coinbaseTransaction to be the value in \zatoshi - of the \blockSubsidy, plus the \transactionFees paid by \transactions in the \block. + of the \blockSubsidy, plus the \transactionFees paid by \transactions in the + \block\nusixone{, plus $\totalDeferredInput(\mathsf{height})$}. \end{itemize} \vspace{-1ex} \prenusix{The \totalOutputValue of a \coinbaseTransaction \MUSTNOT be greater than its \totalInputValue.} @@ -12930,7 +13158,8 @@ \item %\consensuslink{bad-txns-premature-spend-of-coinbase} A \transaction \MUSTNOT spend a \transparentOutput of a \coinbaseTransaction from a \block less than 100 \blocks prior to the spend. Note that \transparentOutputs of - \coinbaseTransactions include \foundersReward outputs \canopy{and \transparent \fundingStream outputs}. + \coinbaseTransactions include \foundersReward outputs\canopy{, \notnusixone{and }\transparent + \fundingStream outputs \cite{ZIP-207}}\nusixone{, and \lockboxDisbursement outputs \cite{ZIP-271}}. \item A \transaction \MUSTNOT spend an output of the \genesisBlock \coinbaseTransaction. (There is one such zero-valued output, on each of \Testnet and \Mainnet.) \overwinterprenufiveitem{\nExpiryHeight{} \MUST be less than or equal to $499999999$.} @@ -13485,6 +13714,10 @@ \vspace{-0.5ex} \item There are no changes to the \blockVersionNumber or format for \NUSix. } %nusix +\nusixone{ + \vspace{-0.5ex} + \item There are no changes to the \blockVersionNumber or format for \NUSixOne. +} %nusix \end{pnotes} \introlist @@ -13794,7 +14027,8 @@ \introlist \vspace{-1.5ex} -\lsubsection{Calculation of Block Subsidy\notbeforecanopy{, Funding Streams,} and Founders' Reward}{subsidies} +\lsubsection{Calculating Block Subsidy\notbeforecanopy{, Funding Streams,}\notbeforenusixone{ Lockbox Disbursement,} +and Founders' Reward}{subsidies} \vspace{-0.5ex} In \crossref{subsidyconcepts} the \blockSubsidy, \minerSubsidy,\notcanopy{ and} \foundersReward\canopy{, @@ -13807,6 +14041,8 @@ \canopy{Let $\FundingStreams$ be as specified in \crossref{zip214fundingstreams}.} +\nusixone{Let $\ZIPTwoSevenOneActivationHeight$ and $\ZIPTwoSevenOneDisbursementAmount$ be as defined in \cite{ZIP-271}.} + \vspace{1ex} \begin{formulae} \item $\SlowStartShift \typecolon \Nat := \hfrac{\SlowStartInterval}{2}$ @@ -13857,6 +14093,13 @@ \vspace{1ex} \item $\totalDeferredOutput(\BlockHeight) := \ssum{\fs\, \in\, \FundingStreams \;:\; \fsRecipient(\BlockHeight) \;=\; \DeferredPool}{} \fsValue(\BlockHeight)$ } %nusix +\nusixone{ + \vspace{1ex} + \item $\totalDeferredInput(\BlockHeight) := \begin{cases} + \ZIPTwoSevenOneDisbursementAmount,&\caseif \BlockHeight = \ZIPTwoSevenOneActivationHeight \\ + 0,&\caseotherwise. + \end{cases}$ +} %nusixone \item $\MinerSubsidy(\BlockHeight) := \BlockSubsidy(\BlockHeight) - \FoundersReward(\BlockHeight) \canopy{\,- \ssum{\fs\, \in\, \FundingStreams}{} \fsValue(\BlockHeight)}$. @@ -13976,7 +14219,7 @@ \consensusrule{\precanopy{ A \coinbaseTransaction at $\BlockHeight \in \range{1}{\FoundersRewardLastBlockHeight}$ \MUST include at least one output that pays exactly $\FoundersReward(\BlockHeight)$ \zatoshi -with a \standardPtoSHScript of the form $\ScriptOP{HASH160} \;\FounderRedeemScriptHash(\BlockHeight)\; \ScriptOP{EQUAL}$ +with a \standardPtoSHScript of the form $\ScriptOP{HASH160}$ $\FounderRedeemScriptHash(\BlockHeight)\; \ScriptOP{EQUAL}$ as its $\scriptPubKey$. }} @@ -14011,19 +14254,31 @@ \canopy{ \vspace{-2ex} -\lsubsection{Payment of Funding Streams}{fundingstreams} +\extralabel{lockbox}{\lsubsection{Payment of Funding Streams\notbeforenusix{,\notnusixone{ and} Deferred Lockbox}\notbeforenusixone{, and Lockbox Disbursement}}{fundingstreams}} -\vspace{-0.5ex} +\vspace{-2ex} Let $\PostBlossomHalvingInterval$ be as defined in \crossref{constants}. -Let $\Halving$ be as defined in \crossref{subsidies}. +Let $\Halving$ be as defined in \shortcrossref{subsidies}. + +\nusixone{ +Let $\ZIPTwoSevenOneActivationHeight$, $\ZIPTwoSevenOneDisbursementAmount$, +$\ZIPTwoSevenOneDisbursementChunks$, and $\ZIPTwoSevenOneDisbursementAddress$ be as defined +for the relevant network (\Mainnet or \Testnet) in \cite{ZIP-271}. +} %nusixone \vspace{1ex} +\cite{ZIP-207} defines a consensus mechanism to require \coinbaseTransactions to include +\fundingStream outputs, intended to provide funds from issuance for Zcash development. +\nusix{\cite{ZIP-2001} extended this mechanism to support directing funds from issuance into +a reserve, the \defining{\deferredDevFundLockbox}.} +\nusixone{\cite{ZIP-271} defines a one-time disbursal of funds from this lockbox in order +to support the Community And Coinholder Funding Model \cite{ZIP-1016}.} + The \defining{\fundingStreams} are paid to one of a pre-defined set of recipients, depending on the \blockHeight. Each recipient identifier is either the string encoding of an address to be paid by an output in the \coinbaseTransaction\nusix{, or the identifier $\DeferredPool$}. -\nusix{The latter 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.} +\nusix{The latter indicates that the value is to be paid into the \deferredDevFundLockbox.} \introlist A \fundingStream $\fs$ is defined by a \blockSubsidy fraction (represented as a numerator and @@ -14066,17 +14321,27 @@ or a \Sapling \shieldedPaymentAddress as specified in \crossref{saplingpaymentaddrencoding}\nusix{, or the identifier $\DeferredPool$}. -Recall from \crossref{subsidies} the definition of $\fsValue$. A \fundingStream $\fs$ is -``active'' at \blockHeight $\BlockHeight$ when $\fsValue(\BlockHeight) > 0$. +A \fundingStream $\fs$ is ``active'' at \blockHeight $\BlockHeight$ when $\fsValue(\BlockHeight) > 0$, +where $\fsValue$ is defined in \crossref{subsidies}. \introlist \consensusrule{ \canopyonward{In each \block with \coinbaseTransaction $\cb$ at \blockHeight $\BlockHeight$, -for each \fundingStream $\fs$ active at that \blockHeight with a recipient identifier\nusix{ other than $\DeferredPool$} -given by $\fsRecipient(\BlockHeight)$, $\cb$ \MUST contain at least one output that pays -$\fsValue(\BlockHeight)$ \zatoshi in the \prescribedWay to the address represented by that -recipient identifier. +$\cb$ \MUST contain at least the given number of distinct outputs for each of the following: +\begin{itemize} + \item for each \fundingStream $\fs$ active at that \blockHeight with a recipient + identifier\nusix{ other than $\DeferredPool$} given by $\fsRecipient(\BlockHeight)$, + one output that pays $\fsValue(\BlockHeight)$ \zatoshi in the \prescribedWay to the + address represented by that recipient identifier\notnusixone{.}\notbeforenusixone{;} + \nusixoneonwarditem{if the \blockHeight is $\ZIPTwoSevenOneActivationHeight$, + $\ZIPTwoSevenOneDisbursementChunks$ equal outputs paying a total of + $\ZIPTwoSevenOneDisbursementAmount$ \zatoshi in the \prescribedWay to the + Key-Holder Organizations' P2SH multisig address represented by + $\ZIPTwoSevenOneDisbursementAddress$, as specified by \cite{ZIP-271}.} +\end{itemize} +\introlist +The term \defining{\quotedPrescribedWay} is defined as follows: \vspace{1ex} \begin{itemize} \item The \defining{\prescribedWay} to pay a \transparentPtoSHAddress is to use a @@ -14086,25 +14351,35 @@ \standardRedeemScript hash for the recipient address for $\fsRecipient(\BlockHeight)$ in \BaseFiftyEightCheck form. - \defining{\xStandardRedeemScript} hashes are defined in \cite{Bitcoin-Multisig} for + \defining{\xStandardRedeemScript} hashes are defined in \cite{ZIP-48} for \PtoSHMultisigAddresses, or \cite{Bitcoin-P2SH} for other \PtoSHAddresses. - \vspace{1ex} - \item The \defining{\prescribedWay} to pay a \Sapling \paymentAddress is defined in - \cite{ZIP-213}, using the post-\Heartwood consensus rules specified for \Sapling - outputs of \coinbaseTransactions in \crossref{txnconsensus}. + \vspace{0.5ex} + \item The \defining{\prescribedWay} to pay a \SaplingOrOrchard \paymentAddress is + defined in \cite{ZIP-213}, using the post-\Heartwood consensus rules specified + for \SaplingAndOrchard outputs of \coinbaseTransactions in \crossref{txnconsensus}. \end{itemize} } %canopyonward } %consensusrule -\vspace{-3ex} +\vspace{-1ex} \begin{pnotes} \item The \fundingStream addresses are not treated specially in any other way, and there can be other outputs to them, in \coinbaseTransactions or otherwise. In particular, it is valid for a \coinbaseTransaction to have other outputs, possibly to the same address, that do not meet the criterion - in the above consensus rule, as long as at least one output meets it. + in the above consensus rule, as long as there is at least the given number of + distinct outputs that meet it, disjointly for each funding item. + \item For clarification, if there are multiple active \fundingStreams or + \lockboxDisbursements with the same recipient identifier and/or value, there + \MUST be at least the given number of distinct outputs for each of them. + \item Up to and including \NUSixOne there have been no \fundingStreams or + \lockboxDisbursements defined with a \shieldedPaymentAddress as a recipient. + That might change in future, so implementations are encouraged to support + \SaplingAndOrchard outputs as recipients, as permitted by \cite{ZIP-213} + and \cite{ZIP-207}. \end{pnotes} +\vspace{-1ex} \lsubsubsection{ZIP 214 Funding Streams}{zip214fundingstreams} Let $\CanopyActivationHeight$ be as defined in \crossref{constants}. @@ -14124,6 +14399,7 @@ \end{tabular} \end{formulae} +\introlist It also defines these \fundingStreams for \Testnet: \begin{formulae} @@ -14179,7 +14455,33 @@ halving on Testnet occurred prior to the introduction of the new funding streams. For both new funding streams on each network, the associated duration corresponds to approximately one year's worth of blocks.} -} %nu6 +} %nusix + +\nusixone{ +\vspace{2ex} +\introlist +\nusixoneonward{\cite{ZIP-214} Revision 2 defines these \fundingStreams for \Mainnet:} + +\begin{formulae} +\item \begin{tabular}{|l|c|c|c|c|} +\hline +Stream & Numerator & Denominator & Start height & End height \\\hline\raisedstrut +\texttt{FS\_FPF\_ZCG\_H3}& $8$ & $100$ & $3146400$ & $4406400$ \\ +\texttt{FS\_CCF\_H3} & $12$ & $100$ & $3146400$ & $4406400$ \\\hline +\end{tabular} +\end{formulae} + +It also defines these \fundingStreams for \Testnet: + +\begin{formulae} +\item \begin{tabular}{|l|c|c|c|c|} +\hline +Stream & Numerator & Denominator & Start height & End height \\\hline\raisedstrut +\texttt{FS\_FPF\_ZCG\_H3}& $8$ & $100$ & $3536500$ & $4476000$ \\ +\texttt{FS\_CCF\_H3} & $12$ & $100$ & $3536500$ & $4476000$ \\\hline +\end{tabular} +\end{formulae} +} %nusixone \lsubsection{Changes to the Script System}{scripts} @@ -14481,7 +14783,7 @@ \crossref{rhoandnullifiers}). Resistance to Faerie Gold attacks, on the other hand, depends entirely on hardness -of the \xDiscreteLogarithmProblem. The $\NoteUniqueRand$ value of a \note created +of the \DiscreteLogarithmProblem. The $\NoteUniqueRand$ value of a \note created in a given \actionTransfer is obtained from the \nullifier of the \note spent in that \actionTransfer; this ensures (without any cryptographic assumption) that all $\NoteUniqueRand$ values of \notes added to the \noteCommitmentTree are unique. @@ -14490,7 +14792,7 @@ that \commitmentScheme ensures that \Orchard \nullifiers will be unique. (Specifically, this is a Sinsemilla commitment with an additional term having base $\NullifierBaseOrchard$, truncated to its $x$-coordinate. The $x$-coordinate truncation cannot harm -\collisionResistance because, assuming hardness of the \xDiscreteLogarithmProblem +\collisionResistance because, assuming hardness of the \DiscreteLogarithmProblem on the \pallasCurve, \crossref{sinsemillasecurity} covers the case where the additional term is added.) Roadblock attacks are not possible because $\NoteUniqueRand$ does not repeat for \notes in the \noteCommitmentTree, and by a corresponding argument @@ -14569,7 +14871,7 @@ These commitments are statistically \hiding, and so ``everlasting anonymity'' is supported for \SaplingAndOrchard notes under the same conditions as in \Zerocash (by the protocol, not necessarily by \zcashd). Note that -\diversifiedPaymentAddresses can be linked if the \xDecisionalDiffieHellmanProblem +\diversifiedPaymentAddresses can be linked if the \DecisionalDiffieHellmanProblem on the \jubjubCurve\nufive{ or the \pallasCurve} can be broken. } %saplingonward @@ -14765,7 +15067,7 @@ expected to cause any weakness in \note encryption. } %sapling -For all shielded protocols, the checking of \noteCommitments makes +For all \shieldedProtocols, the checking of \noteCommitments makes \defining{\partitioningOracleAttacks} \cite{LGR2021} against the \noteCiphertext infeasible, at least in the absence of \sideChannel attacks. \sapling{The following argument applies to \Sapling\nufive{ and \Orchard}, but can be adapted to \Sprout @@ -14785,8 +15087,8 @@ the maximum value of $\InViewingKey$ that can be an output of $\CRHivk{}$\nufive{ or $\CommitIvkAlg$}. -There is also a decryption procedure that makes use of \outgoingCiphertexts in -\Sapling\nufive{ and \Orchard}, as specified in \crossref{decryptovk}. It checks +There is also a decryption procedure making use of \outgoingCiphertexts in +\Sapling\nufive{ and \Orchard}, as specified in \shortcrossref{decryptovk}. It checks (via $\KADerivePublic{}$\canopy{, and also via $\PRFexpand{\NoteSeedBytes}$ in the case of post-\cite{ZIP-212} ciphertexts with $\notePlaintextLeadByte \neq \hexint{01}$}) that the decrypted $\EphemeralPrivate$ value is consistent with the \noteCiphertext, @@ -14911,7 +15213,7 @@ David Campbell, Elena Giralt, Francisco Gindre, Joseph Van~Geffen, Josh Swihart, Kevin Gorham, Larry Ruane, Marshall Gaucher, Ryan Taylor, Sasha Meyer, Conrado Gouvêa, Aditya Bharadwaj, Andrew Arnott, Arya, Andrea Kobrlova, -Lukas Korba, Honza Rychnovský, and no doubt others. +Lukáš Korba, Honza Rychnovský, Schell Scivally, and no doubt others. We would also like to thank the designers and developers of \Bitcoin and \BitcoinCore. @@ -14960,8 +15262,9 @@ Numerous people have contributed to the science of \zeroKnowledgeProvingSystems, but we would particularly like to acknowledge the work of Shafi Goldwasser, Silvio Micali, Oded Goldreich, Mihir Bellare, Charles Rackoff, -Rosario Gennaro, Bryan Parno, Jon Howell, Craig Gentry, Mariana Raykova, -Jens Groth, Rafail Ostrovsky, and Amit Sahai. +Joe Kilian, Yael Tauman Kalai, Guy Rothblum, Rosario Gennaro, Bryan Parno, +Jon Howell, Craig Gentry, Mariana Raykova, Jens Groth, Rafail Ostrovsky, and +Amit Sahai. We thank the organizers of the ZKProof standardization effort and workshops; and also Anna Rose, Fredrik Harrysson, Terun Chitra, James Prestwich, @@ -14991,6 +15294,120 @@ \intropart \lsection{Change History}{changehistory} +\historyentry{2025.6.3}{2025-12-02} + +\begin{itemize} +\nusixone{ + \item Specify in \crossref{blockchain} that \NUSixOne is the most recent \settled \networkUpgrade + on \Testnet and \Mainnet. +} %nusixone + \item Update the description in \crossref{networks} of protocol governance. +\end{itemize} + + +\historyentry{2025.6.2}{2025-11-11} + +\begin{itemize} +\nufive{ + \item In \crossref{rhoandnullifiers}, add a note that the $\NoteUniqueRand$ and $\NoteNullifierRand$ + inputs to $\DeriveNullifierAlg$ must be consistent with the note committed to by $\cm$. + \item Fix an error in the statement of \snarkref{Merkle Path Validity}{actionmerklepathvalidity} + for \Orchard: the \merklePath should be from the leaf value $\ExtractP(\cmOld{})$ rather than + $\cmOld{}$. + This was implemented as intended in the \texttt{orchard} crate. + \item Add a note to the \Orchard key components diagram in \crossref{addressesandkeys}, saying + that the derivations of $\AuthSignPrivate$ and $\CommitIvkRand$ shown there are not the + only possibility, and referencing \crossref{orchardkeycomponents}. Also change the existing + note in that section to say that ``most \Zcash wallets'', not just \zcashd, derive + \SaplingAndOrchard keys and addresses according to \cite{ZIP-32}. +} %nufive +\canopy{ + \item Fix type errors in \crossref{decryptivk} and in \crossref{decryptovk}: $\ToScalar{}$ returns + an integer, not a byte sequence, and so cannot be assigned to $\NoteCommitRandBytes$. + This was implemented as intended in the \texttt{zcash\_note\_encryption} crate. +} %canopy +\sapling{ + \item Rename \shortcrossref{decryptovk} from ``Decryption using a Full Viewing Key (\SaplingAndOrchard)'' + to ``Decryption using an Outgoing Viewing Key (\SaplingAndOrchard)''. +} %sapling + \item Define $\AllowedLeadBytes$ in \crossref{noteptconcept}, and use it to refactor the + constraints on \notePlaintextLeadBytes. + \item Correct the accents on Lukáš Korba's name. + \item Add acknowledgements to Joe Kilian, Yael Tauman Kalai, and Guy Rothblum for contributions + to the science of \zeroKnowledgeProvingSystems. +\end{itemize} + + +\historyentry{2025.6.1}{2025-10-08} + +\begin{itemize} +\nusixone{ + \item Update \NUSixOne consensus changes with the one-time \lockboxDisbursement + addresses, the splitting of the disbursement into $\ZIPTwoSevenOneDisbursementChunks$ + chunks, and other updates to \cite{ZIP-271}. + \item Remove "proposal" from the version string. +} %nusixone +\notnusixone{ + \item No changes before \NUSixOne. +} %notnusixone +\end{itemize} + + +\historyentry{2025.6.0}{2025-09-17} + +\begin{itemize} +\nusixone{ + \item Apply \NUSixOne consensus changes from \cite{ZIP-271}. + \item Add boilerplate support for \NUSixOne. +} %nusixone +\nusix{ + \item Specify in \crossref{blockchain} that \NUSix is the most recent settled \networkUpgrade. + \item Clarify \crossref{transactions}, taking into account the \NUSix consensus changes from \cite{ZIP-236}. +} %nusix +\sapling{ + \item Adjust the recommendation in \crossref{saplingkeycomponents} not to encode + information in the \diversifier, to recommend instead using a \cite{ZIP-32} + \diversifierIndex. + \item Deprecate the encoding of a \Sapling $\InViewingKey$ in \crossref{saplinginviewingkeyencoding}, + in favour of using a \unifiedIncomingViewingKey with a \Sapling component that + includes the \diversifierKey $\DiversifierKey$. + \item Tighten the type of $\InViewingKey$ in \Sapling to $\InViewingKeyTypeSapling$, + and the type of $\DiversifiedTransmitPublic$ in \Sapling to $\KAPublicPrimeOrder{Sapling}$, + in order to make the exclusion of the zero point for $\DiversifiedTransmitPublic$ + more obvious \cite{Zips-Issue664}. This also has the effect that a \Sapling + \incomingViewingKey \crossref{saplinginviewingkeyencoding} or a \Sapling \IVKEncoding + in a \unifiedIncomingViewingKey \cite{ZIP-316} that encodes the zero $\InViewingKey$ + \MUST be considered invalid when imported. + Notes have been added in \crossref{saplingpaymentaddrencoding} and + \crossref{saplinginviewingkeyencoding} calling out these changes. + \item In \crossref{decryptovk}, retrospectively enforce the check for canonicity of + $\DiversifiedTransmitPublic$. This has no effect on consensus relative to the + previous version, because only small-order + \jubjubCurve points have \nonCanonicalPoint encodings, and so the check that + returns $\bot$ if $\DiversifiedTransmitPublic \not\in \SubgroupJstar$ would catch + all such cases. +} %sapling +\nufive{ + \item Document in \crossref{concretereddsa}, \crossref{spenddesc}, and \crossref{txnconsensus} + that the canonicity restriction on the encoding of $\RedDSASigR{}$ in $\RedDSA$ + signature validation is retrospectively valid on \Mainnet and \Testnet before \NUFive. + \item So that \SaplingAndOrchard are consistent, \crossref{concreteorchardkeyagreement} + now also defines $\KAPublicPrimeOrder{Orchard}$, which is used instead of + $\KAPublic{Orchard}$ as the type of an \Orchard $\DiversifiedTransmitPublic$. + This has no effect on conformance since both $\KAPublicPrimeOrder{Orchard}$ and + $\KAPublic{Orchard}$ are defined as $\GroupPstar$. + \item In \crossref{orchardfullviewingkeyencoding}, clarify the requirement on + $\AuthSignPublic$ by rewording ``valid \Pallas $x$-coordinate`` to + ``valid affine $x$-coordinate of a \pallasCurve point in $\GroupPstar$``. + Implementations might use $(0, 0)$ to represent $\ZeroP$, but $0$ is not a + valid $x$-coordinate in the sense required here. +} %nufive + \item Change incorrect uses of ``block reward`` to \blockSubsidy. + \item Added dark mode rendering (\url{https://zips.z.cash/protocol/protocol-dark.pdf}). + \item Add an acknowledgement to Schell Scivally for discussions on the Zcash protocol. +\end{itemize} + + \historyentry{2024.5.1}{2024-09-26} \begin{itemize} @@ -15001,7 +15418,7 @@ \crossref{chainvaluepoolbalances}. \item Add a definition of \totalIssuedSupply. \item Add acknowledgements to Aditya Bharadwaj, Andrew Arnott, Arya, - Andrea Kobrlova, Lukas Korba, and Honza Rychnovský for discussions + Andrea Kobrlova, Lukáš Korba, and Honza Rychnovský for discussions on the Zcash protocol. \end{itemize} @@ -15279,7 +15696,7 @@ \crossref{inbandrationale}:\!\! \begin{itemize} \item The argument for decryption with an \incomingViewingKey does not need to - depend on the \xDecisionalDiffieHellmanProblem, since $\DiversifiedTransmitBase$ + depend on the \DecisionalDiffieHellmanProblem, since $\DiversifiedTransmitBase$ is committed to by the \noteCommitment as well as $\DiversifiedTransmitPublic$. \item It is necessary to say that the \noteCommitment is always checked for a successful decryption. @@ -15588,8 +16005,8 @@ \item Clarify the distinction between \Orchard \incomingViewingKeys and $\KA{Orchard}$ \privateKeys. \item Add a note in \crossref{concretesinsemillahash} that \cite[Lemma 3]{JT2020} proves - a tight reduction from finding a nontrivial discrete logarithm relation to the - \xDiscreteLogarithmProblem. + a tight reduction from finding a nontrivial \discreteLogarithm relation to the + \DiscreteLogarithmProblem. } %nufive \sapling{ \item Add a note to \crossref{merklepath} clarifying the encoding of $\rt{Sapling}$ @@ -15624,8 +16041,8 @@ a non-null $\prevoutField$ field. \item Caveat how the result of \cite{GG2015} applies to analysis of $\PRFnf{Orchard}{}$ in \crossref{concreteprfs}. - \item Unlinkability of \diversifiedPaymentAddresses depends on the \xDecisionalDiffieHellmanProblem, - not the \xDiscreteLogarithmProblem. + \item Unlinkability of \diversifiedPaymentAddresses depends on the \DecisionalDiffieHellmanProblem, + not the \DiscreteLogarithmProblem. \item Add a paragraph to \crossref{truncation} covering \Orchard. \item Clarify the definition of $\pad$ in \crossref{concretesinsemillahash} by disambiguating $\Mpieces$ from $\Mpadded$. @@ -15693,7 +16110,7 @@ \item Add a caveat in \crossref{orchardkeycomponents} about reuse of $\CommitIvkRand$ between $\PRFexpand{}$ and $\CommitIvk{}$. \item Expand the set of ZIPs associated with \NUFive in \crossref{networkupgrades}, and - reference \cite{Zcash-Orchard} and \cite{Zcash-halo2} there. + reference \cite{Zcash-halo2} and \cite{Zcash-Orchard} there. \item Section \crossref{concreteorchardkdf} should be in \nufivecolorname. \item Explicitly note that the end of the \cite{ZIP-212} grace period precedes \NUFive activation. \item Change the condition for presence of $\anchorField{Sapling}$ in a version 5 \transaction @@ -15849,8 +16266,8 @@ but was previously proving that $\PedersenHash$ does not return that value. \item The note about \nonCanonicalPoint encodings in \crossref{jubjub} gave incorrect values for the encodings of the point of order $2$, by omitting a $\ParamJ{q}$ term. - \item The specification of decryption in \crossref{decryptovk} differed from its implementation - in \zcashd, in two respects: + \item The specification of decryption in \shortcrossref{decryptovk} differed from the \zcashd + implementation in two respects: \begin{itemize} \item The specification had a type error in that it failed to check whether $\abstJ\Of{\DiversifiedTransmitPublicRepr} = \bot$, which is needed in @@ -15858,7 +16275,7 @@ \item The specification did not require $\DiversifiedTransmitPublic$ to be in the subgroup $\SubgroupJ$, while the implementation in \zcashd did. This check is not needed for security; however, since \Jubjub public keys - are normally of type $\KAPublicPrimeSubgroup{Sapling}$, we change the + are normally of type $\KAPublicPrimeOrder{Sapling}$, we change the specification to match \zcashd. \end{itemize} \item Correct the procedure for generating \dummy \Sapling \notes in \crossref{saplingdummynotes}. @@ -15939,13 +16356,23 @@ \historyentry{2020.1.13}{2020-08-11} \begin{itemize} \sapling{ - \item Rename the type of \Sapling \transmissionKeys from $\KA{Sapling}\mathsf{.PublicPrimeOrder}$ - to $\KAPublicPrimeSubgroup{Sapling}$. This type is defined as $\SubgroupJ$, which reflects + \item Rename the type of \Sapling \transmissionKeys from $\KAPublicPrimeOrder{Sapling}$ to + $\KA{Sapling}\mathsf{.PublicPrimeSubgroup}$. This type is defined as $\SubgroupJ$, which reflects the implementation in \zcashd (subject to the next point below); it was never enforced that a \transmissionKey ($\DiversifiedTransmitPublic$) cannot be $\ZeroJ$. - \item Add a non-normative note saying that \zcashd does not fully conform to the requirement - to treat \transmissionKeys not in $\KAPublicPrimeSubgroup{Sapling}$ as invalid when importing + \item Add a non-normative note saying that \zcashd does not fully conform to the requirement to treat + \transmissionKeys not in $\KA{Sapling}\mathsf{.PublicPrimeSubgroup}$ as invalid when importing \shieldedPaymentAddresses. + \item \textbf{Retrospective note:} + Changing $\KAPublicPrimeOrder{Sapling}$ to $\KA{Sapling}\mathsf{.PublicPrimeSubgroup}$ + was a mistake and has since been reverted in specification version \historyref{2025.6.0}. + As discussed in notes added in version \historyref{2023.4.0} at \crossref{decryptovk}, + \librustzcash changed in \cite{librustzcash-109} to enforce that $\DiversifiedTransmitPublic$ + is not $\ZeroJ$. \zcashd also used a different implementation for a consensus check on \shielded + coinbase outputs. The missing check on $\DiversifiedTransmitPublic$ for the latter was corrected + in \cite{zcashd-6459}, and simplified when it was observed to be retrospectively valid in + \cite{zcashd-6725}. However \cite{ZIP-216} was only corrected later \cite{Zips-Issue664}, at the + same time as the publication of \historyref{2025.6.0}. } %sapling \canopy{ \item Set $\CanopyActivationHeight$ for \Testnet. @@ -16354,7 +16781,7 @@ \item Add Eirik \nh{Ogilvie-Wigley} and Benjamin Winston to acknowledgements. \sapling{ \item Rename \zkSNARK Parameters sections to be named according to the proving - system (\BCTV or \Groth), not the shielded protocol construction + system (\BCTV or \Groth), not the \shieldedProtocol construction (\Sprout or \Sapling). \item In \crossref{networkupgrades}, say when \Sapling activated. } %sapling @@ -18102,7 +18529,7 @@ The specification of the \xPedersenHashes used in \Sapling is given in \crossref{concretepedersenhash}. It is based on the scheme from \cite[section 5.2]{CvHP1991} --for which a tighter security reduction to -the \xDiscreteLogarithmProblem was given in \cite{BGG1995}-- but tailored +the \DiscreteLogarithmProblem was given in \cite{BGG1995}-- but tailored to allow several optimizations in the circuit implementation. \xPedersenHashes are the single most commonly used primitive in the @@ -19024,7 +19451,7 @@ } %nnote The performance benefit of this approach arises from computing two of the three Miller loops, and -the final exponentation, per batch instead of per proof. For the multiplications by $z_j$, an efficient +the final exponentiation, per batch instead of per proof. For the multiplications by $z_j$, an efficient algorithm for multiscalar multiplication such as Pippinger's method \cite{Bernstein2001} or the Bos--Coster method \cite{deRooij1995} may be used. diff --git a/protocol/zcash.bib b/protocol/zcash.bib index ec823e03d..b2291bdc0 100644 --- a/protocol/zcash.bib +++ b/protocol/zcash.bib @@ -1212,6 +1212,15 @@ @misc{ZIP-32 urldate={2019-08-28} } +@misc{ZIP-48, + presort={ZIP-0048}, + author={Kris Nuttycombe and Jack Grigg and {Daira\nbh{}Emma} Hopwood and Arya}, + title={Transparent Multisig Wallets}, + howpublished={Zcash Improvement Proposal 48.}, + url={https://zips.z.cash/zip-0048}, + urldate={2025-10-08} +} + @misc{ZIP-76, presort={ZIP-0076}, author={Jack Grigg and {Daira\nbh{}Emma} Hopwood}, @@ -1489,6 +1498,24 @@ @misc{ZIP-253 urldate={2024-09-24} } +@misc{ZIP-255, + presort={ZIP-0255}, + author={Arya}, + title={Deployment of the {NU6.1} Network Upgrade}, + howpublished={Zcash Improvement Proposal 255. Created May~6, 2025.}, + url={https://zips.z.cash/zip-0255}, + urldate={2025-08-20} +} + +@misc{ZIP-271, + presort={ZIP-0271}, + author={Daira\nbh{}Emma Hopwood and Kris Nuttycombe and Jack Grigg}, + title={Deferred Dev Fund Lockbox Disbursement}, + howpublished={Zcash Improvement Proposal 271. Created February~19, 2025.}, + url={https://zips.z.cash/zip-0271}, + urldate={2025-08-20} +} + @misc{ZIP-302, presort={ZIP-0302}, author={Jay Graber and Jack Grigg}, @@ -1519,12 +1546,21 @@ @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} } +@misc{ZIP-1016, + presort={ZIP-1016}, + author={Josh Swihart}, + title={Community and Coinholder Funding Model}, + howpublished={Zcash Improvement Proposal 1016. Created February~19, 2025.}, + url={https://zips.z.cash/zip-1016}, + urldate={2025-08-20} +} + @misc{ZIP-2001, presort={ZIP-2001}, author={Kris Nuttycombe}, @@ -1592,11 +1628,19 @@ @misc{Bowe2018 @misc{Zcash-Issue2113, presort={Zcash-Issue2113}, author={Simon Liu}, - title={GitHub repository `\hairspace zcash/zcash'\hairspace: Issue 2113}, + title={GitHub repository `\hairspace zcash/zcash'\hairspace: Issue 2113 -- Upgrade testnet to fix bug in test and update fr addresses}, url={https://github.com/zcash/zcash/issues/2113}, urldate={2017-02-20} } +@misc{Zips-Issue664, + presort={Zips-Issue664}, + author={{Daira\nbh{}Emma} Hopwood}, + title={GitHub repository `\hairspace zcash/zips'\hairspace: Issue 664 -- [protocol spec] [ZIP 216] Sapling pk\_d should not allow the zero point}, + url={https://github.com/zcash/zips/issues/664}, + urldate={2025-09-07} +} + @book{IEEE2000, presort={IEEE2000}, author={IEEE Computer Society}, @@ -1779,6 +1823,24 @@ @misc{Zcash-Nu5 urldate={2022-05-11} } +@misc{Zcash-Nu6, + presort={Zcash-Nu6}, + author={Electric Coin Company}, + title={Network Upgrade 6}, + date={2025-08-20}, + url={https://z.cash/upgrade/nu6/}, + urldate={2025-08-20} +} + +@misc{Zcash-Nu6.1, + presort={Zcash-Nu6.1}, + author={Electric Coin Company}, + title={Network Upgrade 6.1}, + date={2025-08-20}, + url={https://z.cash/upgrade/nu6.1/}, + urldate={2025-08-20} +} + @misc{WCBTV2015, presort={WCBTV2015}, author={Zooko Wilcox and Alessandro Chiesa and Eli {Ben\nbh{}Sasson} and Eran Tromer and Madars Virza}, diff --git a/render.sh b/render.sh new file mode 100755 index 000000000..e499e0990 --- /dev/null +++ b/render.sh @@ -0,0 +1,100 @@ +#!/bin/bash + +# If a URL in this script should not be checked as a dependency by `update_check.sh`, +# break it up like this: 'https''://' . + +set -euo pipefail + +if ! ( [ $# -eq 3 ] && ( [ "x$1" = "x--rst" ] || [ "x$1" = "x--pandoc" ] || [ "x$1" = "x--mmd" ] ) ); 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='' +Math2='' +Math3='' + +Mermaid='' + +ViewAndStyle='' + +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||${Math1}\n ${Math2}\n ${Math3}|; + s||${ViewAndStyle}|" + 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 "" + echo "" + echo "" + echo " ${title}" + echo " " + echo " ${ViewAndStyle}" + if grep -q -E 'class="mermaid"' "${outputfile}.temp"; then + echo " ${Mermaid}" + fi + if grep -q -E 'class="math( inline)?"' "${outputfile}.temp"; then + echo " ${Math1}" + echo " ${Math2}" + echo " ${Math3}" + fi + 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/COPYING.html b/rendered/COPYING.html deleted file mode 100644 index ae9994f2f..000000000 --- a/rendered/COPYING.html +++ /dev/null @@ -1,15 +0,0 @@ - - - - COPYING - - - -
-

Copyright (c) 2016-2020 The Zcash Core developers

-

Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions:

-

The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software.

-

THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.

-
- - \ No newline at end of file diff --git a/rendered/draft-hopwood-coinbase-balance.html b/rendered/draft-hopwood-coinbase-balance.html deleted file mode 100644 index 8c72eba08..000000000 --- a/rendered/draft-hopwood-coinbase-balance.html +++ /dev/null @@ -1,10 +0,0 @@ - - - - ZIP 236: Blocks should balance exactly (redirect) - - - -

This draft was assigned ZIP number 236.

- - \ No newline at end of file diff --git a/rendered/draft-noamchom67-manufacturing-consent.html b/rendered/draft-noamchom67-manufacturing-consent.html deleted file mode 100644 index 8a4bf2958..000000000 --- a/rendered/draft-noamchom67-manufacturing-consent.html +++ /dev/null @@ -1,291 +0,0 @@ - - - - Draft noamchom67-manufacturing-consent: Manufacturing Consent; Re-Establishing a Dev Fund for ECC, ZF, ZCG, Qedit, FPF, and ZecHub - - - -
-
ZIP: ####
-Title: Manufacturing Consent; Re-Establishing a Dev Fund for ECC, ZF, ZCG, Qedit, FPF, and ZecHub
-Owner: Noam Chom <noamchom1967@gmail.com>
-Credits: The ZIP-1014 Authors
-Status: Withdrawn
-Category: Consensus Process
-Created: 2024-06-25
-License: MIT
-Discussions-To: <https://forum.zcashcommunity.com/t/manufacturing-consent-noamchoms-nu6-block-reward-proposal/47155>
-Pull-Request: TBD
-

Terminology

-

The key words "MUST", "MUST NOT", "SHALL", "SHALL 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 6 and the Zcash Trademark Donation and License Agreement (4 or successor agreement).

-

The terms "block subsidy" and "halving" in this document are to be interpreted as described in sections 3.10 and 7.8 of the Zcash Protocol Specification. 2

-

"Electric Coin Company", also called "ECC", refers to the Zerocoin Electric Coin Company, LLC.

-

"Bootstrap Project", also called "BP", refers to the 501(c)(3) nonprofit corporation of that name.

-

"Zcash Foundation", also called "ZF", refers to the 501(c)(3) nonprofit corporation of that name.

-

"Section 501(c)(3)" refers to that section of the U.S. Internal Revenue Code (Title 26 of the U.S. Code). 12

-

"Community Advisory Panel" refers to the panel of community members assembled by the Zcash Foundation and described at 11.

-

"Zcash Community Grants", also called "ZCG", refers to grants program (formerly known as ZOMG) that funds independent teams entering the Zcash ecosystem, to perform major ongoing development (or other work) for the public good of the Zcash ecosystem. <https://zcashcommunitygrants.org/>

-

"Financial Privacy Foundation", also called "FPF" refers to the start-up non-profit organization incorporated and based in the Cayman Islands. <https://www.financialprivacyfoundation.org/>

-

"Qedit" refers to the company founded in 2016 by a world-class team of accomplished tech entrepreneurs, researchers, and developers; QEDIT has emerged as a global leader in the field of Zero-Knowledge Proofs. <https://qed-it.com/about-us/>

-

"ZecHub" refers to the team of content creators who have supported Zcash through a series of ZCG approved grants. <https://forum.zcashcommunity.com/t/zechub-an-education-hub-for-zcash-2024-continued/47947>

-

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

-

The term "ZSA" is to be interpreted as "Zcash Shielded Assets" the protocol feature enhancement (and subsequent application layer, legal, maintenance efforts, et al) on-going by Qedit, et al. <https://forum.zcashcommunity.com/t/grant-update-zcash-shielded-assets-monthly-updates/41153>

-

✳️ is used to denote elements of the process part of the ZIP that are still to-be-determined.

-
-

Abstract

-

This proposal describes a structure for the Zcash Development Fund, to be enacted in Network Upgrade 6 and last for 4 years. This Dev Fund would consist of 15% of the block subsidies, as the following allocations:

-
    -
  • 5% for the Zcash Foundation (for internal work and grants);
  • -
  • 4% for the Bootstrap Project (the parent of the Electric Coin Company) for the 1st year only;
  • -
  • 4% for Zcash Community Grants for continuation of their current activities as-is;
  • -
  • 2% for Qedit in support of their ZSA activities, and other Zcash protocol support;
  • -
-

Following the first year, when ECC will no longer receive their 4% allocation, those block subsidies will be distributed as 1% to ZCG, 1% to ZecHub, 1% to FPF, and 1% to ZF.

-

Governance and accountability are based on existing entities and legal mechanisms, and increasingly decentralized governance is encouraged. This proposal mandates the ecosystem to design and deploy a "non-direct funding model" as generally recommended in Josh Swihart's proposal. 13

-

Upon creation/ activation of a "non-direct funding model" this ZIP should be reconsidered (potentially terminated) by the Zcash ecosystem, to determine if its ongoing direct block subsidies are preferred for continuation. Discussions/ solications/ sentiment gathering from the Zcash ecosystem should be initiated ~6 months in advance of the presumed activation of a "non-direct funding model", such that the Zcash ecosystem preference can be expediently realized.

-

Block subsidies will be administered through two organizations:

-
    -
  1. Zcash Foundation (✳️ for ECC, ZCG)
  2. -
  3. Financial Privacy Foundation (✳️ for Qedit, ZecHub)
  4. -
-

✳️ ZF and FPF adminstration of block subsidy details, costs, et al are currently under debate 14

-
-

Motivation

-

As of Zcash's second halving in November 2024, by default 100% of the block subsidies will be allocated to miners, and no further funds will be automatically allocated to any other entities. Consequently, no new funding may be available to existing teams dedicated to furthering charitable, educational, or scientific purposes, such as research, development, and outreach: the Electric Coin Company (ECC), the Zcash Foundation (ZF), the ZCG, and the many entities funded by the ZF and ZCG grant programs.

-

There is a need to strike a balance between incentivizing the security of the consensus protocol (i.e., mining) versus crucial charitable, educational, and/or scientific aspects, such as research, development and outreach.

-

Furthermore, there is a need to balance the sustenance of ongoing work by the current teams dedicated to Zcash, with encouraging decentralization and growth of independent development teams.

-

For these reasons, the Zcash Community desires to allocate and contribute a portion of the block subsidies otherwise allocated to miners as a donation to support charitable, educational, and scientific activities within the meaning of Section 501(c)(3).

-

This proposal also introduces the benefit of a non-USA based entity (FPF) as the administrator for block subsidies to two organizations that are also non-USA based (Qedit and ZecHub). USA based regulatory risk continues to (negatively) impact the Zcash project, which has been predominantly based in the USA.

-
-

Requirements

-

The Dev Fund should encourage decentralization of the work and funding, by supporting new teams dedicated to Zcash.

-

The Dev Fund should maintain the existing teams and capabilities in the Zcash ecosystem, unless and until concrete opportunities arise to create even greater value for the Zcash ecosystem.

-

There should not be any single entity which is a single point of failure, i.e., whose capture or failure will effectively prevent effective use of the funds.

-

Major funding decisions should be based, to the extent feasible, on inputs from domain experts and pertinent stakeholders.

-

The Dev Fund mechanism should not modify the monetary emission curve (and in particular, should not irrevocably burn coins).

-

In case the value of ZEC jumps, the Dev Fund recipients should not wastefully use excessive amounts of funds. Conversely, given market volatility and eventual halvings, it is desirable to create rainy-day reserves.

-

The Dev Fund mechanism should not reduce users' financial privacy or security. In particular, it should not cause them to expose their coin holdings, nor cause them to maintain access to secret keys for much longer than they would otherwise. (This rules out some forms of voting, and of disbursing coins to past/future miners.)

-

The Dev Fund system should be simple to understand and realistic to implement. In particular, it should not assume the creation of new mechanisms (e.g., election systems) or entities (for governance or development) for its execution; but it should strive to support and use these once they are built.

-

Dev Fund recipients should comply with legal, regulatory, and taxation constraints in their pertinent jurisdiction(s).

-
-

Non-requirements

-

General on-chain governance is outside the scope of this proposal.

-

Rigorous voting mechanisms (whether coin-weighted, holding-time-weighted or one-person-one-vote) are outside the scope of this proposal, however this proposal does mandate the undertaking of the project to build a "non-direct funding model" as generally described in 13.

-
-

Specification

-

Consensus changes implied by this specification are applicable to the Zcash Mainnet. Similar (but not necessarily identical) consensus changes SHOULD be applied to the Zcash Testnet for testing purposes.

-

Dev Fund allocation

-

Starting at the second Zcash halving in 2024, until the third halving in 2028, 15% of the block subsidy of each block SHALL be allocated to a "Dev Fund" that consists of the following allocations:

-
    -
  • 5% for the Zcash Foundation (for internal work and grants);
  • -
  • 4% for the Bootstrap Project (the parent of the Electric Coin Company) for the 1st year only;
  • -
  • 4% for Zcash Community Grants for continuation of their current activities as-is;
  • -
  • 2% for Qedit in support of their ZSA activities, and other Zcash protocol support;
  • -
-

Following the first year, when ECC will no longer receive their 4% allocation, those block subsidies will be distributed as 1% to ZCG, 1% to ZecHub, 1% to FPF, and 1% to ZF.

-

This proposal mandates the ecosystem to design and deploy a "non-direct funding model" as generally recommended in Josh Swihart's proposal 13.

-

"Dev Fund" block subsidies will be administered through two organizations:

-
    -
  1. Zcash Foundation (✳️ for ECC, ZCG)
  2. -
  3. Financial Privacy Foundation (✳️ for Qedit, ZecHub)
  4. -
-

✳️ ZF and FPF adminstration of block subsidy details, costs, et al are currently under debate 14

-

The allocations are described in more detail below. The fund flow will be implemented at the consensus-rule layer, by sending the corresponding ZEC to the designated address(es) for each block. This Dev Fund will end at the third halving (unless extended/modified by a future ZIP).

-

BP allocation (Bootstrap Project)

-

✳️ These funds SHALL be received and administered by ZF.

-

This allocation of the Dev Fund will flow as charitable contributions from the Zcash Community to the Bootstrap Project, the newly formed parent organization to the Electric Coin Company. The Bootstrap Project is organized for exempt educational, charitable, and scientific purposes in compliance with Section 501(c)(3), including but not limited to furthering education, information, resources, advocacy, support, community, and research relating to cryptocurrency and privacy, including Zcash. This allocation will be used at the discretion of the Bootstrap Project for any purpose within its mandate to support financial privacy and the Zcash platform as permitted under Section 501(c)(3). The BP allocation will be treated as a charitable contribution from the Community to support these educational, charitable, and scientific purposes.

-
-

ZF allocation (Zcash Foundation's general use)

-

This allocation of the Dev Fund will flow as charitable contributions from the Zcash Community to ZF, to be used at its discretion for any purpose within its mandate to support financial privacy and the Zcash platform, including: development, education, supporting community communication online and via events, gathering community sentiment, and awarding external grants for all of the above, subject to the requirements of Section 501(c)(3). The ZF allocation will be treated as a charitable contribution from the Community to support these educational, charitable, and scientific purposes.

-
-

Zcash Community Grants (ZCG)

-

This allocation of the Dev Fund is intended to fund independent teams entering the Zcash ecosystem, to perform major and minor ongoing development (or other work) for the public good of the Zcash ecosystem, to the extent that such teams are available and effective.

-

✳️ These funds SHALL be received and administered by ZF (or FPF, pending TBD outcomes of FPF proposal: 14). ZF MUST disburse them for "Major Grants" and expenses reasonably related to the administration of Major Grants, but subject to the following additional constraints:

-
    -
  1. These funds MUST only be used to issue Major Grants to external parties that are independent of ZF, and to pay for expenses reasonably related to the administration of Major Grants. They MUST NOT be used by ZF for its internal operations and direct expenses not related to administration of Major Grants. Additionally, BP, ECC, and ZF are ineligible to receive Major Grants.
  2. -
  3. Major Grants SHOULD support well-specified work proposed by the grantee, at reasonable market-rate costs. They can be of any duration or ongoing without a duration limit. Grants of indefinite duration SHOULD have semiannual review points for continuation of funding.
  4. -
  5. Priority SHOULD be given to Major Grants that bolster teams with substantial (current or prospective) continual existence, and set them up for long-term success, subject to the usual grant award considerations (impact, ability, risks, team, cost-effectiveness, etc.). Priority SHOULD be given to Major Grants that support ecosystem growth, for example through mentorship, coaching, technical resources, creating entrepreneurial opportunities, etc. If one proposal substantially duplicates another's plans, priority SHOULD be given to the originator of the plans.
  6. -
  7. Major Grants SHOULD be restricted to furthering the Zcash cryptocurrency and its ecosystem (which is more specific than furthering financial privacy in general) as permitted under Section 501(c)(3).
  8. -
  9. Major Grants awards are subject to approval by a five-seat Major Grant Review Committee. The Major Grant Review Committee SHALL be selected by the ZF's Community Advisory Panel or successor process.
  10. -
  11. The Major Grant Review Committee's funding decisions will be final, requiring no approval from the ZF Board, but are subject to veto if the Foundation judges them to violate U.S. law or the ZF's reporting requirements and other (current or future) obligations under U.S. IRS 501(c)(3).
  12. -
  13. Major Grant Review Committee members SHALL have a one-year term and MAY sit for reelection. The Major Grant Review Committee is subject to the same conflict of interest policy that governs the ZF Board of Directors (i.e. they MUST recuse themselves when voting on proposals where they have a financial interest). At most one person with association with the BP/ECC, and at most one person with association with the ZF, are allowed to sit on the Major Grant Review Committee. "Association" here means: having a financial interest, full-time employment, being an officer, being a director, or having an immediate family relationship with any of the above. The ZF SHALL continue to operate the Community Advisory Panel and SHOULD work toward making it more representative and independent (more on that below).
  14. -
  15. From 1st January 2022, a portion of the MG allocation shall be allocated to a Discretionary Budget, which may be disbursed for expenses reasonably related to the administration of Major Grants. The amount of funds allocated to the Discretionary Budget SHALL be decided by the ZF's Community Advisory Panel or successor process. Any disbursement of funds from the Discretionary Budget MUST be approved by the Major Grant Review Committee. Expenses related to the administration of Major Grants include, without limitation the following: -
      -
    • Paying third party vendors for services related to domain name registration, or the design, website hosting and administration of websites for the Major Grant Review Committee.
    • -
    • Paying independent consultants to develop requests for proposals that align with the Major Grants program.
    • -
    • Paying independent consultants for expert review of grant applications.
    • -
    • Paying for sales and marketing services to promote the Major Grants program.
    • -
    • Paying third party consultants to undertake activities that support the purpose of the Major Grants program.
    • -
    • Reimbursement to members of the Major Grant Review Committee for reasonable travel expenses, including transportation, hotel and meals allowance.
    • -
    -

    The Major Grant Review Committee's decisions relating to the allocation and disbursement of funds from the Discretionary Budget will be final, requiring no approval from the ZF Board, but are subject to veto if the Foundation judges them to violate U.S. law or the ZF's reporting requirements and other (current or future) obligations under U.S. IRS 501(c)(3).

    -
  16. -
-

ZF SHALL recognize the MG allocation of the Dev Fund as a Restricted Fund donation under the above constraints (suitably formalized), and keep separate accounting of its balance and usage under its Transparency and Accountability obligations defined below.

-

ZF SHALL strive to define target metrics and key performance indicators, and the Major Grant Review Committee SHOULD utilize these in its funding decisions.

-
-

Qedit

-

✳️ These funds SHALL be received and administered by FPF.

-

This allocation of the Dev Fund will flow as charitable contributions from the Zcash Community to Qedit, for the purposes of supporting their ongoing activities related to Zcash Shielded Assets, and related protocol/ application/ legal/ and other efforts.

-
-

ZecHub

-

✳️ These funds SHALL be received and administered by FPF.

-

This allocation of the Dev Fund will flow as charitable contributions from the Zcash Community to ZecHub, for the purposes of continuing their ongoing content contributions, community organizing, et al within the Zcash ecosystem.

-
-
-

Transparency and Accountability

-

Obligations

-

BP, ECC, ZF, ZCG, Qedit, FPF and ZecHub are recommended to accept the obligations in this section.

-

Ongoing public reporting requirements:

-
    -
  • Quarterly reports, detailing future plans, execution on previous plans, and finances (balances, and spending broken down by major categories).
  • -
  • Monthly developer calls, or a brief report, on recent and forthcoming tasks. (Developer calls may be shared.)
  • -
  • Annual detailed review of the organization performance and future plans.
  • -
  • Annual financial report (IRS Form 990, or substantially similar information).
  • -
-

These reports may be either organization-wide, or restricted to the income, expenses, and work associated with the receipt of Dev Fund. As BP is the parent organization of ECC it is expected they may publish joint reports.

-

It is expected that ECC, ZF, and ZCG will be focused primarily (in their attention and resources) on Zcash. Thus, they MUST promptly disclose:

-
    -
  • Any major activity they perform (even if not supported by the Dev Fund) that is not in the interest of the general Zcash ecosystem.
  • -
  • Any conflict of interest with the general success of the Zcash ecosystem.
  • -
-

BP, ECC, ZF, and grant recipients MUST promptly disclose any security or privacy risks that may affect users of Zcash (by responsible disclosure under confidence to the pertinent developers, where applicable).

-

BP's reports, ECC's reports, and ZF's annual report on its non-grant operations, SHOULD be at least as detailed as grant proposals/reports submitted by other funded parties, and satisfy similar levels of public scrutiny.

-

All substantial software whose development was funded by the Dev Fund SHOULD be released under an Open Source license (as defined by the Open Source Initiative 5), preferably the MIT license.

-
-

Enforcement

-

For grant recipients, these conditions SHOULD be included in their contract with ZF, such that substantial violation, not promptly remedied, will cause forfeiture of their grant funds and their return to ZF.

-

BP, ECC, and ZF MUST contractually commit to each other to fulfill these conditions, and the prescribed use of funds, such that substantial violation, not promptly remedied, will permit the other party to issue a modified version of Zcash node software that removes the violating party's Dev Fund allocation, and use the Zcash trademark for this modified version. The allocation's funds will be reassigned to MG (whose integrity is legally protected by the Restricted Fund treatment).

-
-
-

Future Community Governance

-

It is highly desirable to develop robust means of decentralized community voting and governance –either by expanding the Zcash Community Advisory Panel or a successor mechanism– and to integrate them into this process by the end of 2025. BP, ECC, ZCG, and ZF SHOULD place high priority on such development and its deployment, in their activities and grant selection.

-
-

ZF Board Composition

-

Members of ZF's Board of Directors MUST NOT hold equity in ECC or have current business or employment relationships with ECC, except as provided for by the grace period described below.

-

Grace period: members of the ZF board who hold ECC equity (but do not have other current relationships to ECC) may dispose of their equity, or quit the Board, by 21 November 2024. (The grace period is to allow for orderly replacement, and also to allow time for ECC corporate reorganization related to Dev Fund receipt, which may affect how disposition of equity would be executed.)

-

The Zcash Foundation SHOULD endeavor to use the Community Advisory Panel (or successor mechanism) as advisory input for future board elections.

-
-
-

Acknowledgements

-

This proposal is a modification of ZIP 1014 10 and a modification from the original "Manufacturing Consent" proposal as described in the Zcash Forum, in response to observable Zcash community sentiment.

-

The author is grateful to everyone in the Zcash ecosystem.

-
-

References

- - - - - - - -
1Information 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"
- - - - - - - -
2Zcash Protocol Specification, Version 2021.2.16 or later
- - - - - - - -
3Zcash Protocol Specification, Version 2021.2.16. Section 3.12: Mainnet and Testnet
- - - - - - - -
4Zcash Trademark Donation and License Agreement
- - - - - - - -
5The Open Source Definition
- - - - - - - -
6ZIP 200: Network Upgrade Mechanism
- - - - - - - -
7ZIP 1003: 20% Split Evenly Between the ECC and the Zcash Foundation, and a Voting System Mandate
- - - - - - - -
8ZIP 1010: Compromise Dev Fund Proposal With Diverse Funding Streams
- - - - - - - -
9ZIP 1011: Decentralize the Dev Fee
- - - - - - - -
10ZIP 1012: Dev Fund to ECC + ZF + Major Grants
- - - - - - - -
11ZF Community Advisory Panel
- - - - - - - -
12U.S. Code, Title 26, Section 501(c)(3)
- - - - - - - -
13Zcash Funding Bloc : A Dev Fund Proposal from Josh at ECC
- - - - - - - -
14Proposal: ZCG under FPF
-
-
- - \ No newline at end of file diff --git a/rendered/draft-nuttycom-funding-allocation.html b/rendered/draft-nuttycom-funding-allocation.html deleted file mode 100644 index 1f1c1a17b..000000000 --- a/rendered/draft-nuttycom-funding-allocation.html +++ /dev/null @@ -1,328 +0,0 @@ - - - - Draft nuttycom-funding-allocation: Block Reward Allocation for Non-Direct Development Funding - - - -
-
ZIP: Unassigned
-Title: Block Reward Allocation for Non-Direct Development Funding
-Owners: Kris Nuttycombe <kris@nutty.land>
-        Jason McGee <aquietinvestor@gmail.com>
-Original-Authors: Skylar Saveland <skylar@free2z.com>
-Credits: Daira-Emma Hopwood
-         Jack Grigg
-         @Peacemonger (Zcash Forum)
-Status: Withdrawn
-Category: Consensus
-Created: 2024-07-03
-License: MIT
-Pull-Request: <https://github.com/zcash/zips/pull/866>
-

Terminology

-

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.

-
-

Abstract

-

This ZIP proposes several options for the allocation of a percentage of the Zcash block subsidy, post-November 2024 halving, to an in-protocol "lockbox." The "lockbox" will be a separate pool of issued funds tracked by the protocol, as described in ZIP 2001: Lockbox Funding Streams 4. No disbursement mechanism is currently defined for this "lockbox"; the Zcash community will need to decide upon and specify a suitable decentralized mechanism for permitting withdrawals from this lockbox in a future ZIP in order to make these funds available for funding grants to ecosystem participants.

-

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, by default 100% of the block subsidies will be allocated to miners, and no further funds will 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 will 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:

-
    -
  1. Regulatory Risks: The current model involves direct funding of US-based organizations, which can potentially attract regulatory scrutiny from entities such as the SEC, posing legal risks to the Zcash ecosystem.
  2. -
  3. Funding Inefficiencies: The current model directly funds organizations rather than specific projects, leading to a potential mismatch between those organizations' development priorities and the priorities of the community. Furthermore, if organizations are guaranteed funds regardless of performance, there is little incentive to achieve key performance indicators (KPIs) or align with community sentiment. A future system that allocates resources directly to projects rather than organizations may help reduce inefficiencies and better align development efforts with community priorities.
  4. -
  5. Centralization Concerns: The current model centralizes decision-making power within a few organizations, contradicting the decentralized ethos of blockchain technology. Traditional organizational structures with boards and executives introduce single points of failure and limit community involvement in funding decisions.
  6. -
  7. Community Involvement: The current system provides minimal formal input from the community regarding what projects should be funded, leading to a misalignment between funded projects and community priorities.
  8. -
  9. Moving Towards a Non-Direct Funding Model: There is strong community support for a non-direct Dev Fund funding model. Allocating funds to a Deferred Dev Fund Lockbox incentivizes the development of a decentralized mechanism for the disbursement of the locked funds.
  10. -
-

By addressing these issues, this proposal aims to ensure sustainable, efficient, and decentralized funding for essential activities within the Zcash ecosystem.

-
-

Requirements

-
    -
  1. In-Protocol Lockbox: The alternatives presented in this ZIP depend upon the Lockbox Funding Streams proposal 4.
  2. -
  3. Regulatory Considerations: The allocation of funds should minimize regulatory risks by avoiding direct funding of specific organizations. The design should enable and encourage compliance with applicable laws and regulations to support the long-term sustainability of the funding model.
  4. -
-
-

Non-requirements

-

The following considerations are explicitly deferred to future ZIPs and are not covered by this proposal:

-
    -
  1. Disbursement Mechanism: The exact method for disbursing the accumulated funds from the lockbox is not defined in this ZIP. The design, implementation, and governance of the disbursement mechanism will be addressed in a future ZIP. This includes specifics on how funds will be allocated, the voting or decision-making process, and the structure of the decentralized mechanism (such as a DAO).
  2. -
  3. Regulatory Compliance Details: The proposal outlines the potential to reduce regulatory risks by avoiding direct funding of US-based organizations, but it does not detail specific regulatory compliance strategies. Future ZIPs will need to address how the disbursement mechanism complies with applicable laws and regulations.
  4. -
  5. Impact Assessment: The long-term impact of reallocating a portion of the block subsidy to the lockbox on the Zcash ecosystem, including its effect on miners, developers, and the broader community, is not analyzed in this ZIP. Subsequent proposals will need to evaluate the outcomes and make necessary adjustments based on real-world feedback and data.
  6. -
-
-

Specification

-

The following alternatives all depend upon the Lockbox Funding Streams proposal 4 for storage of funds into a deferred value pool.

-

Some of the alternatives described below do not specify a termination height for the funding streams they propose. In these cases, the termination height is set to u32::MAX_VALUE. A future network upgrade that alters the maximum possible block height MUST also alter these termination heights.

-
-

Alternatives

-

Alternative 1: Lockbox For Decentralized Grants Allocation (perpetual 50% option)

-

Proposed by Skylar Saveland

-
    -
  • 50% of the block subsidy is to be distributed to the lockbox.
  • -
-

As of block height 2726400, and continuing until modified by a future ZIP, the complete set of funding streams will be:

- - - - - - - - - - - - - - - - - - - -
StreamNumeratorDenominatorStart heightEnd height
FS_DEFERRED501002726400u32::MAX
-

Motivations for Alternative 1

-

This alternative proposes allocating a significantly larger portion of the block subsidy to development funding than is currently allocated, aiming to establish a long-term source of funding for protocol improvements. The disbursement of these funds will be governed by a mechanism to be determined by the community in the future, ensuring that the funds are released under agreed-upon constraints to maintain availability for years to come.

-

The proposed lockbox funding model for Zcash's post-NU6 halving period allocates 50% of the block reward to a deferred reserve, or "lockbox," designated for future decentralized grants funding. This approach is designed to address several critical motivations:

- -
    -
  1. Regulatory Compliance: -
      -
    • Reduction of Regulatory Risks: Direct funding to legal entities poses significant regulatory risks. Allocating funds to a decentralized lockbox mitigates these risks by avoiding direct funding of any specific organizations. This alternative represents the strongest regulatory posture, as it reduces the likelihood of legal challenges associated with funding centralized entities directly.
    • -
    • Potential Minimization of KYC Requirements: The current funding mechanism involves 100% KYC for recipients, which can be detrimental to security, privacy, resilience, and participation. A sufficiently decentralized disbursement mechanism could reduce the need for recipients to undergo KYC with a controlling entity. This would preserve privacy and encourage broader participation from developers and contributors who value anonymity and privacy. By shifting from direct funding of specific legal entities to a decentralized funding model, we create a more secure, private, and resilient ecosystem. This potential future difference enhances the robustness of the Zcash network by fostering a diverse and engaged community without the constraints of centralized direct funding.
    • -
    -
  2. -
  3. Ensuring Sustainable Development Funding: -
      -
    • Need for Continuous Funding: Zcash has numerous ongoing and future projects essential for its ecosystem's growth and security. Without a change, the expiration of the devfund will result in 100% of the block reward going to miners, jeopardizing funding for development. The proposed 50% lockbox allocation ensures that funds are directed towards sustaining and improving the Zcash ecosystem through a wide array of initiatives. These include protocol development, new features, security audits, legal support, marketing, ZSAs (Zcash Shielded Assets), stablecoins, programmability, transitioning to a modern Rust codebase, wallets, integrations with third-party services, improved node software, block explorers, supporting ambassadors, and educational initiatives like ZecHub.
    • -
    • Balanced Incentives for Network and Protocol Security: While miners have been essential in providing network security through hashpower, allocating 100% of the block reward to mining alone overlooks the crucial need for development, innovation, and protocol security. By investing in these priorities, we enhance the long-term health and value of the protocol, which ultimately benefits miners. A well-maintained and innovative protocol increases the overall value of the network, making miners' rewards more valuable. This balanced approach aligns the interests of miners with the broader community, ensuring sustainable growth and security for Zcash.
    • -
    -
  4. -
  5. Efficiency, Accountability, and Decentralization: -
      -
    • Reduction of Inefficiencies: Traditional funding models often involve significant corporate overhead and centralized decision-making, leading to inefficiencies. The prior model provided two 501(c)(3) organizations with constant funding for four years, which reduced accountability and allowed for potential misalignment with the community's evolving priorities. By funding projects directly rather than organizations, we can allocate resources more efficiently, ensuring that funds are used for tangible development rather than administrative costs. This approach minimizes the influence of corporate executives, whose decisions have sometimes failed to address critical issues promptly.
    • -
    • Increased Accountability: A presumed grants-only mechanism, to be defined in a future ZIP, would necessitate continuous accountability and progress for continuous funding. Unlike the prior model, where organizations received guaranteed funding regardless of performance, a grants-based approach would require projects to demonstrate ongoing success and alignment with community goals to secure funding. This continuous evaluation fosters a more responsive and responsible allocation of resources, ensuring that funds are directed towards initiatives that provide the most value to the Zcash ecosystem. By increasing accountability, this model promotes a culture of excellence and innovation, driving sustained improvements and advancements in the protocol.
    • -
    • Promotion of Decentralization: The proposed non-direct funding model stores deferred funds for future use, with the specifics of the disbursement mechanism to be determined by a future ZIP. This could allow the community to have a greater influence over funding decisions, aligning more closely with the ethos of the Zcash project. By decentralizing the allocation process, this approach has the potential to foster innovation and community involvement, ensuring that development priorities are more reflective of the community's needs and desires, promoting a more open, transparent, and resilient ecosystem.
    • -
    -
  6. -
  7. Incentives for Development and Collaboration: -
      -
    • Creating a Strong Incentive to Implement the Disbursement Mechanism: Allocating 50% of the block reward to the lockbox indefinitely creates a powerful incentive for the community to work together to implement the disbursement mechanism without delay. Knowing that there is a substantial amount of funds available, stakeholders will be motivated to develop and agree on an effective, decentralized method for distributing these funds.
    • -
    • Incentivizing Continuous Improvements: The accumulation of a large stored fortune within the lockbox incentivizes continuous improvements to the Zcash protocol and ecosystem. Developers, contributors, and community members will be driven to propose and execute projects that enhance the network, knowing that successful initiatives have the potential to receive funding. This model fosters a culture of ongoing innovation and development, ensuring that Zcash remains at the forefront of blockchain technology.
    • -
    • Aligning Long-Term Interests: By tying a significant portion of the block reward to future decentralized grants funding, the model aligns the long-term interests of all stakeholders. Miners, developers, and community members alike have a vested interest in maintaining and improving the Zcash network, as the value and success of their efforts are directly linked to the availability and effective use of the lockbox funds. This alignment of incentives ensures that the collective efforts of the community are focused on the sustainable growth and advancement of the Zcash ecosystem.
    • -
    -
  8. -
-
-

Guidance on Future Requirements for Alternative 1

-

To support the motivations outlined, the following guidance is proposed for Alternative 1. Future ZIP(s) will define the disbursement mechanism. These are suggestions to achieve the outlined motivations and should be considered in those future ZIP(s). It is important to note that these are ideas and guidance, not hard, enforceable requirements:

-
    -
  1. Cap on Grants: Grants should be capped to promote more granular accountability and incremental goal-setting. This approach ensures that projects are required to define their work, goals, milestones, KPIs, and achievements in smaller, more manageable increments. Even if a single project is utilizing significant funds quickly, the cap ensures that progress is continuously evaluated and approved based on tangible results and alignment with community priorities.
  2. -
  3. Decentralized Disbursement Mechanism: The disbursement mechanism should be sufficiently decentralized to ensure the regulatory motivations are fulfilled. A decentralized mechanism could reduce the need for recipients to undergo KYC with a controlling party, preserving privacy and aligning with the ethos of the Zcash project.
  4. -
  5. Governance and Accountability: The governance structure for the disbursement mechanism should be open and accountable, with decisions made through community consensus or decentralized voting processes to maintain trust and accountability. This approach will help ensure that the allocation of funds is fair and aligned with the community's evolving priorities.
  6. -
  7. Periodic Review and Adjustment: There should be provisions for periodic review and adjustment of the funding mechanism to address any emerging issues or inefficiencies and to adapt to the evolving needs of the Zcash ecosystem. This could include the ability to add or remove participants as necessary. Regular assessments will help keep the funding model responsive and effective, ensuring it continues to meet the community's goals.
  8. -
-

By addressing these motivations and providing this guidance, Alternative 1 aims to provide a robust, sustainable, and decentralized funding model that aligns with the principles and long-term goals of the Zcash community.

-
-
-

Alternative 2: Hybrid Deferred Dev Fund: Transitioning to a Non-Direct Funding Model

-

Proposed by Jason McGee, Peacemonger, GGuy

-
    -
  • 12% of the block subsidy is to be distributed to the lockbox.
  • -
  • 8% of the block subsidy is to be distributed to the Financial Privacy Foundation (FPF), for the express use of the Zcash Community Grants Committee (ZCG) to fund independent teams in the Zcash ecosystem.
  • -
-

As of block height 2726400, and continuing for one year, the complete set of funding streams will be:

- - - - - - - - - - - - - - - - - - - - - - - - - - -
StreamNumeratorDenominatorStart heightEnd height
FS_DEFERRED1210027264003146400
FS_FPF_ZCG810027264003146400
-

Motivations for Alternative 2

-
    -
  • Limited Runway: ZCG does not have the financial runway that ECC/BP and ZF have. As such, allocating ongoing funding to ZCG will help ensure the Zcash ecosystem has an active grants program.
  • -
  • Promoting Decentralization: Allocating a portion of the Dev Fund to Zcash Community Grants ensures small teams continue to receive funding to contribute to Zcash. Allowing the Dev Fund to expire, or putting 100% into a lockbox, would disproportionally impact grant recipients. This hybrid approach promotes decentralization and the growth of independent development teams.
  • -
  • Mitigating Regulatory Risks: The Financial Privacy Foundation (FPF) is a non-profit organization incorporated and based in the Cayman Islands. By minimizing direct funding of US-based organizations, this proposal helps to reduce potential regulatory scrutiny and legal risks.
  • -
-
-
-

Alternative 3: Lockbox For Decentralized Grants Allocation (20% option)

-

Proposed by Kris Nuttycombe

-
    -
  • 20% of the block subsidy is to be distributed to the lockbox.
  • -
-

As of block height 2726400, and continuing for two years, the complete set of funding streams will be:

- - - - - - - - - - - - - - - - - - - -
StreamNumeratorDenominatorStart heightEnd height
FS_DEFERRED2010027264003566400
-

Motivations for Alternative 3

-

This alternative is presented as the simplest allocation of block rewards to a lockbox for future disbursement that is consistent with results of community polling.

-
-
-

Alternative 4: Masters Of The Universe?

-

Proposed by NoamChom (Zcash forum)

-
    -
  • 17% of the block subsidy is to be distributed to the lockbox.
  • -
  • 8% of the block subsidy is to be distributed to the Financial Privacy Foundation (FPF), for the express use of the Zcash Community Grants Committee (ZCG) to fund independent teams in the Zcash ecosystem.
  • -
-

As of block height 2726400, and continuing for four years, the complete set of funding streams will be:

- - - - - - - - - - - - - - - - - - - - - - - - - - -
StreamNumeratorDenominatorStart heightEnd height
FS_DEFERRED1710027264004406400
FS_FPF_ZCG810027264004406400
-

Motivations for Alternative 4

-

This alternative proposes a slightly larger slice of the block subsidy than is currently allocated for development funding, in order to better provide for the needs of the Zcash community.

-
-

Revisitation Requirement for Alternative 4

-

The terms for this Alternative should be revisited by the Zcash ecosystem upon creation/ activation of a "non-direct funding model" (NDFM). At that completion of an NDFM which accessess the lockbox funds, this ZIP should be reconsidered (potentially terminated) by the Zcash ecosystem, to determine if its ongoing direct block subsidies are preferred for continuation. Discussions / solications / sentiment gathering from the Zcash ecosystem should be initiated ~6 months in advance of the presumed activation of a "non-direct funding model", such that the Zcash ecosystem preference can be expediently realized.

-
-
-
- -

References

- - - - - - - -
1Information 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"
- - - - - - - -
2The Open Source Definition
- - - - - - - -
3ZIP 1014: Dev Fund Proposal and Governance
- - - - - - - -
4ZIP 2001: Lockbox Funding Streams
-
-
- - \ No newline at end of file diff --git a/rendered/draft-nuttycom-lockbox-streams.html b/rendered/draft-nuttycom-lockbox-streams.html deleted file mode 100644 index 17c801d92..000000000 --- a/rendered/draft-nuttycom-lockbox-streams.html +++ /dev/null @@ -1,10 +0,0 @@ - - - - ZIP 2001: Lockbox Funding Streams (redirect) - - - -

This draft was assigned ZIP number 2001.

- - \ No newline at end of file diff --git a/rendered/draft-zf-community-dev-fund-2-proposal.html b/rendered/draft-zf-community-dev-fund-2-proposal.html deleted file mode 100644 index 13c5b253e..000000000 --- a/rendered/draft-zf-community-dev-fund-2-proposal.html +++ /dev/null @@ -1,280 +0,0 @@ - - - - Draft zf-community-dev-fund-2-proposal: Establishing a Hybrid Dev Fund for ZF, ZCG and a Dev Fund Reserve - - - -
-
ZIP: Unassigned
-Title: Establishing a Hybrid Dev Fund for ZF, ZCG and a Dev Fund Reserve
-Owners: Jack Gavigan <jack@zfnd.org>
-Credits: The ZIP 1014 Authors
-Status: Withdrawn
-Category: Consensus Process
-Created: 2024-07-01
-License: MIT
-Discussions-To:
-Pull-Request:
-

Terminology

-

The key words "MUST", "MUST NOT", "SHALL", "SHALL 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 6 and the Zcash Trademark Donation and License Agreement (4 or successor agreement).

-

The terms "block subsidy" and "halving" in this document are to be interpreted as described in sections 3.10 and 7.8 of the Zcash Protocol Specification. 2

-

"Electric Coin Company", also called "ECC", refers to the US-incorporated Zerocoin Electric Coin Company, LLC.

-

"Bootstrap Project", also called "BP", refers to the US-incorporated 501(c)(3) nonprofit corporation of that name.

-

"Zcash Foundation", also called "ZF", refers to the US-incorporated 501(c)(3) nonprofit corporation of that name.

-

"Financial Privacy Foundation", also called "FPF", refers to the Cayman Islands-incorporated non-profit foundation company limited by guarantee of that name.

-

"Autonomous Entities" refers to committees, DAOs, teams or other groups to which FPF provides operations, administrative, and financial management support.

-

"Section 501(c)(3)" refers to that section of the U.S. Internal Revenue Code (Title 26 of the U.S. Code). 14

-

"Zcash Community Advisory Panel", also called "ZCAP", refers to the panel of community members assembled by the Zcash Foundation and described at 13.

-

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

-

“Lockbox” refers to a deferred funding pool of issued Zcash value as described in ZIP 2001 12.

-

“Dev Fund Reserve”, also called “DFR”, refers to the funds that are to be stored in the Lockbox as a result of the changes described in this ZIP.

-
-

Abstract

-

This proposal describes a structure for a new Zcash Development Fund (“Dev Fund”), to be enacted in Network Upgrade 6 and last for 2 years. This Dev Fund shall consist of 20% of the block subsidies.

-

The Dev Fund shall be split into 3 slices:

-
    -
  • 32% for Zcash Foundation;
  • -
  • 40% for "Zcash Community Grants", intended to fund large-scale long-term Projects (administered by the Financial Privacy Foundation, with extra community input and scrutiny).
  • -
  • 28% for a Dev Fund Reserve, to be stored in a Lockbox.
  • -
-

The Lockbox will securely store funds until a disbursement mechanism is established in a future ZIP.

-

Governance and accountability are based on existing entities and legal mechanisms, and increasingly decentralized governance is encouraged.

-
-

Motivation

-

Starting at Zcash's second halving in November 2024, the first Dev Fund will expire, meaning that by default 100% of the block subsidies will be allocated to miners, and no further funds will be automatically allocated to any other entities. Consequently, no substantial new funding may be available to existing teams dedicated to furthering charitable, educational, or scientific purposes, such as research, development, and outreach: the Electric Coin Company (ECC), the Zcash Foundation (ZF), and the many entities funded by the ZF grants and Zcash Community Grants programs.

-

There is a need to continue to strike a balance between incentivizing the security of the consensus protocol (i.e., mining) versus crucial charitable, educational, and/or scientific aspects, such as research, development and outreach.

-

Furthermore, there is a need to balance the sustenance of ongoing work by the current teams dedicated to Zcash, with encouraging decentralization and growth of independent development teams.

-

For these reasons, the Zcash Community desires to allocate and contribute a slice of the block subsidies otherwise allocated to miners as a donation to support charitable, educational, and scientific activities within the meaning of Section 501(c)(3) of Title 26 of the United States Code, and the Cayman Islands’ Foundation Companies Law, 2017.

-

The Zcash Community also supports the concept of a non-direct funding model, and desires to allocate a slice of the block subsidies otherwise allocated to miners to a Lockbox, with the expectation that those funds will be distributed under a non-direct funding model, which may be implemented in a future network upgrade.

-

For these reasons, the Zcash Community wishes to establish a Hybrid Development Fund after the second halving in November 2024, and apportion it among ZF, ZCG, and a Dev Fund Reserve to be held in a Lockbox.

-
-

Requirements

-

The Dev Fund should encourage decentralization of the Zcash ecosystem, by supporting new teams dedicated to Zcash.

-

The Dev Fund should maintain the existing teams and capabilities in the Zcash ecosystem, unless and until concrete opportunities arise to create even greater value for the Zcash ecosystem.

-

There should not be any single entity which is a single point of failure, i.e., whose capture or failure will effectively prevent effective use of the funds.

-

Major funding decisions should be based, to the extent feasible, on inputs from domain experts and pertinent stakeholders.

-

The Dev Fund mechanism itself should not modify the monetary emission curve (and in particular, should not irrevocably burn coins).

-

In case the value of ZEC jumps, the Dev Fund recipients should not wastefully use excessive amounts of funds. Conversely, given market volatility and eventual halvings, it is desirable to create rainy-day reserves.

-

The Dev Fund mechanism should not reduce users' financial privacy or security. In particular, it should not cause them to expose their coin holdings, nor cause them to maintain access to secret keys for much longer than they would otherwise. (This rules out some forms of voting, and of disbursing coins to past/future miners.)

-

The new Dev Fund system should be simple to understand and realistic to implement. In particular, it should not assume the creation of new mechanisms (e.g., election systems) or entities (for governance or development) for its execution; but it should strive to support and use these once they are built.

-

The Dev Fund should comply with legal, regulatory, and taxation constraints in pertinent jurisdictions.

-

The Lockbox must be prepared to allocate resources efficiently once the disbursement mechanism is defined. This includes ensuring that funds are readily available for future projects and not tied up in organizational overhead.

-

The Lockbox must implement robust security measures to protect against unauthorized access or misuse of funds. It must not be possible to disburse funds from the Lockbox until the Zcash Community reaches consensus on the design of a disbursement mechanism that is defined in a ZIP and implemented as part of a future Network Upgrade.

-
-

Non-requirements

-

General on-chain governance is outside the scope of this proposal.

-

Rigorous voting mechanisms (whether coin-weighted, holding-time-weighted or one-person-one-vote) are outside the scope of this proposal, though there is prescribed room for integrating them once available.

-

The mechanism by which funds held in the Dev Fund Reserve Lockbox are to be distributed is outside the scope of this proposal.

-
-

Specification

-

Consensus changes implied by this specification are applicable to the Zcash Mainnet. Similar (but not necessarily identical) consensus changes SHOULD be applied to the Zcash Testnet for testing purposes.

-

Dev Fund allocation

-

Starting at the second Zcash halving in 2024, until block height 3566400 (which is expected to occur approximately two years after the second Zcash halving), 20% of the block subsidy of each block SHALL be allocated to a Dev Fund that consists of the following three slices:

-
    -
  • 32% for the Zcash Foundation (denoted ZF slice);
  • -
  • 40% for the Financial Privacy Foundation, for "Zcash Community Grants" for large-scale long-term projects (denoted ZCG slice);
  • -
  • 28% for the Dev Fund Reserve (denoted DFR slice).
  • -
-

The slices are described in more detail below. The fund flow will be implemented at the consensus-rule layer, by sending the corresponding ZEC to the designated address(es) for each block. This Dev Fund will end at block height 3566400 (unless extended/modified by a future ZIP).

-

ZF slice (Zcash Foundation)

-

This slice of the Dev Fund will flow as charitable contributions from the Zcash Community to ZF, to be used at its discretion for any purpose within its mandate to support financial privacy and the Zcash platform, including: development, education, supporting community communication online and via events, gathering community sentiment, and awarding external grants for all of the above, subject to the requirements of Section 501(c)(3). The ZF slice will be treated as a charitable contribution from the Community to support these educational, charitable, and scientific purposes.

-
-

ZCG slice (Zcash Community Grants)

-

This slice of the Dev Fund is intended to fund independent teams entering the Zcash ecosystem, to perform major ongoing development (or other work) for the public good of the Zcash ecosystem, to the extent that such teams are available and effective.

-

The funds SHALL be received and administered by FPF. FPF MUST disburse them for "Zcash Community Grants" and expenses reasonably related to the administration of Zcash Community Grants, but subject to the following additional constraints:

-
    -
  1. These funds MUST only be used to issue Zcash Community Grants to external parties that are independent of FPF or to Autonomous Entities that operate under the FPF umbrella, and to pay for expenses reasonably related to the administration of Zcash Community Grants. They MUST NOT be used by FPF for its internal operations and direct expenses not related to administration of Zcash Community Grants. Additionally, ZF is ineligible to receive Zcash Community Grants while ZF is receiving a slice of the Dev Fund.
  2. -
  3. Zcash Community Grants SHOULD support well-specified work proposed by the grantee, at reasonable market-rate costs. They can be of any duration or ongoing without a duration limit. Grants of indefinite duration SHOULD be reviewed periodically (on a schedule that the Zcash Community Grants Committee considers appropriate for the value and complexity of the grant) for continuation of funding.
  4. -
  5. Priority SHOULD be given to Zcash Community Grants that bolster teams with substantial (current or prospective) continual existence, and set them up for long-term success, subject to the usual grant award considerations (impact, ability, risks, team, cost-effectiveness, etc.). Priority SHOULD Be given to grants that support ecosystem growth, for example through mentorship, coaching, technical resources, creating entrepreneurial opportunities, etc. If one proposal substantially duplicates another's plans, priority SHOULD be given to the originator of the plans.
  6. -
  7. Zcash Community Grants SHOULD be restricted to furthering the Zcash cryptocurrency and its ecosystem (which is more specific than furthering financial privacy in general).
  8. -
  9. Zcash Community Grants awards are subject to approval by a five-seat Zcash Community Grants Committee. The Zcash Community Grants Committee SHALL be selected by the ZF's Zcash Community Advisory Panel (ZCAP) or successor process.
  10. -
  11. The Zcash Community Grants Committee's funding decisions will be final, requiring no approval from the FPF Board, but are subject to veto if FPF judges them to violate Cayman law or the FPF's reporting requirements and other (current or future) obligations under the Cayman Islands’ Companies Act (2023 Revision) and Foundation Companies Law, 2017.
  12. -
  13. Zcash Community Grants Committee members SHALL have a one-year term and MAY sit for reelection. The Zcash Community Grants Committee is subject to the same conflict of interest policy that governs the FPF Board of Directors (i.e. they MUST recuse themselves when voting on proposals where they have a financial interest). At most one person with association with the BP/ECC, at most one person with association with the ZF and at most one person with association with the FPF, are allowed to sit on the Zcash Community Grants Committee. "Association" here means: having a financial interest, full-time employment, being an officer, being a director, or having an immediate family relationship with any of the above.
  14. -
  15. A portion of the ZCG Slice shall be allocated to a Discretionary Budget, which may be disbursed for expenses reasonably related to the administration of Zcash Community Grants. The amount of funds allocated to the Discretionary Budget SHALL be decided by the ZF's Zcash Community Advisory Panel or successor process. Any disbursement of funds from the Discretionary Budget MUST be approved by the Zcash Community Grants Committee. Expenses related to the administration of Zcash Community Grants include, without limitation the following: -
      -
    • Paying for operational management and administration services that support the purpose of the Zcash Community Grants program, including administration services provided by FPF.
    • -
    • Paying third party vendors for services related to domain name registration, or the design, website hosting and administration of websites for the Zcash Community Grants Committee.
    • -
    • Paying independent consultants to develop requests for proposals that align with the Zcash Community Grants program.
    • -
    • Paying independent consultants for expert review of grant applications.
    • -
    • Paying for sales and marketing services to promote the Zcash Community Grants program.
    • -
    • Paying third party consultants to undertake activities that support the purpose of the Zcash Community Grants program.
    • -
    • Reimbursement to members of the Zcash Community Grants Committee for reasonable travel expenses, including transportation, hotel and meals allowance.
    • -
    -

    The Zcash Community Grants Committee's decisions relating to the allocation and disbursement of funds from the Discretionary Budget will be final, requiring no approval from the FPF Board, but are subject to veto if FPF judges them to violate Cayman law or the FPF's reporting requirements and other (current or future) obligations under Cayman Islands law.

    -
  16. -
  17. A portion of the Discretionary Budget MAY be allocated to provide reasonable compensation to members of the Zcash Community Grants Committee. The time for which each Committee member is compensated SHALL be limited to the hours needed to successfully perform their positions, up to a maximum of 15 hours in each month, and MUST align with the scope and responsibilities of that member's role. The compensation rate for each Committee member SHALL be $115 per hour (and therefore the maximum compensation for a Committee member is $1725 per month). The allocation and distribution of compensation to committee members SHALL be administered by FPF. Changes to the hours or rate SHALL be determined by the ZF’s Zcash Community Advisory Panel or successor process.
  18. -
-

As part of the contractual commitment specified under the Enforcement section below, FPF SHALL be contractually required to recognize the ZCG slice of the Dev Fund as a Restricted Fund donation under the above constraints (suitably formalized), and keep separate accounting of its balance and usage under its Transparency and Accountability obligations defined below.

-
-

DFR slice (Dev Fund Reserve)

-

This slice of the Dev Fund is to be stored in a Lockbox until such time as the Zcash Community reaches consensus on the design of a disbursement mechanism that is defined in a ZIP and implemented as part of a future Network Upgrade.

-
-
-

Transparency and Accountability

-

Obligations

-

ZF, FPF and Zcash Community Grant recipients (during and leading to their award period) SHALL all accept the obligations in this section.

-

Ongoing public reporting requirements:

-
    -
  • Quarterly reports, detailing future plans, execution on previous plans, and finances (balances, and spending broken down by major categories).
  • -
  • Monthly developer calls, or a brief report, on recent and forthcoming tasks. (Developer calls may be shared.)
  • -
  • Annual detailed review of the organization performance and future plans.
  • -
  • Annual financial report (IRS Form 990, or substantially similar information).
  • -
-

These reports may be either organization-wide, or restricted to the income, expenses, and work associated with the receipt of Dev Fund.

-

It is expected that ZF, FPF and Zcash Community Grant recipients will be focused primarily (in their attention and resources) on Zcash. Thus, they MUST promptly disclose:

-
    -
  • Any major activity they perform (even if not supported by the Dev Fund) that is not in the interest of the general Zcash ecosystem.
  • -
  • Any conflict of interest with the general success of the Zcash ecosystem.
  • -
-

BP, ECC, ZF, FPF and grant recipients MUST promptly disclose any security or privacy risks that may affect users of Zcash (by responsible disclosure under confidence to the pertinent developers, where applicable).

-

ZF's and FPF's annual reports on its non-grant operations, SHOULD be at least as detailed as grant proposals/reports submitted by other funded parties, and satisfy similar levels of public scrutiny.

-

All substantial software whose development was funded by the Dev Fund SHOULD be released under an Open Source license (as defined by the Open Source Initiative 5), preferably the MIT license.

-

The ZF SHALL continue to operate the Zcash Community Advisory Panel and SHOULD work toward making it more representative and independent (more on that below).

-
-

Enforcement

-

For grant recipients, these conditions SHOULD be included in their contract with FPF, such that substantial violation, not promptly remedied, will cause forfeiture of their grant funds and their return to FPF.

-

ZF and FPF MUST contractually commit to each other to fulfill these conditions, and the prescribed use of funds, such that substantial violation, not promptly remedied, will permit the other parties to issue a modified version of Zcash node software that removes the violating party's Dev Fund slice, and use the Zcash trademark for this modified version. The slice's funds will be reassigned to ZCG (whose integrity is legally protected by the Restricted Fund treatment).

-
-
-

Amendments and Replacement of the Dev Fund

-

Nothing in this ZIP is intended to preclude any amendments to the Dev Fund (including but not limited to, changes to the Dev Fund allocation and/or the addition of new Dev Fund recipients), if such amendments enjoy the consensus support of the Zcash community.

-

Nothing in this ZIP is intended to preclude replacement of the Dev Fund with a different mechanism for ecosystem development funding.

-

ZF and FPF SHOULD facilitate the amendment or replacement of the Dev Fund if there is sufficient community support for doing so.

-

This ZIP recognizes there is strong community support for a non-direct funding model. As such, ZF MUST collaborate with the Zcash community to research and explore the establishment of a non-direct funding model. The research should consider potential designs as well as possible legal and regulatory risks.

-
-

Future Community Governance

-

Decentralized community governance is used in this proposal via the Zcash Community Advisory Panel as input into the Zcash Community Grants Committee which governs the ZCG slice (Zcash Community Grants).

-

It is highly desirable to develop robust means of decentralized community voting and governance, either by expanding the Zcash Community Advisory Panel or a successor mechanism. ZF, FPF and ZCG SHOULD place high priority on such development and its deployment, in their activities and grant selection.

-
-

ZF Board Composition

-

Members of ZF's Board of Directors MUST NOT hold equity in ECC or have current business or employment relationships with ECC or BP.

-

The Zcash Foundation SHOULD endeavor to use the Zcash Community Advisory Panel (or successor mechanism) as advisory input for future board elections.

-
-

FPF Board Composition

-

Members of FPF's Board of Directors MUST NOT hold equity in ECC or have current business or employment relationships with ECC or BP.

-
-
-

Acknowledgements

-

This proposal is a modification of ZIP 1014 11 by the Zcash Foundation based on feedback and suggestions from the community, and incorporating elements of draft ZIPs by community members Jason McGee and Skylar.

-

ZIP 1014 is a limited modification of Eran Tromer's ZIP 1012 10 by the Zcash Foundation and ECC, further modified by feedback from the community.

-

Eran's proposal is most closely based on the Matt Luongo 'Decentralize the Dev Fee' proposal (ZIP 1011) 9. Relative to ZIP 1011 there are substantial changes and mixing in of elements from @aristarchus's '20% Split Evenly Between the ECC and the Zcash Foundation' (ZIP 1003) 7, Josh Cincinnati's 'Compromise Dev Fund Proposal With Diverse Funding Streams' (ZIP 1010) 8, and extensive discussions in the Zcash Community Forum, including valuable comments from forum users @aristarchus and @dontbeevil.

-
-

References

- - - - - - - -
1Information 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"
- - - - - - - -
2Zcash Protocol Specification, Version 2021.2.16 or later
- - - - - - - -
3Zcash Protocol Specification, Version 2021.2.16. Section 3.12: Mainnet and Testnet
- - - - - - - -
4Zcash Trademark Donation and License Agreement
- - - - - - - -
5The Open Source Definition
- - - - - - - -
6ZIP 200: Network Upgrade Mechanism
- - - - - - - -
7ZIP 1003: 20% Split Evenly Between the ECC and the Zcash Foundation, and a Voting System Mandate
- - - - - - - -
8ZIP 1010: Compromise Dev Fund Proposal With Diverse Funding Streams
- - - - - - - -
9ZIP 1011: Decentralize the Dev Fee
- - - - - - - -
10ZIP 1012: Dev Fund to ECC + ZF + Major Grants
- - - - - - - -
11ZIP 1014: Establishing a Dev Fund for ECC, ZF, and Major Grants
- - - - - - - -
12ZIP 2001: Lockbox Funding Streams
- - - - - - - -
13Zcash Community Advisory Panel
- - - - - - - -
14U.S. Code, Title 26, Section 501(c)(3)
-
-
- - \ No newline at end of file diff --git a/rendered/index.html b/rendered/index.html deleted file mode 100644 index 4837413ba..000000000 --- a/rendered/index.html +++ /dev/null @@ -1,263 +0,0 @@ - - - - README: Specifications and Zcash Improvement Proposals - - - -
- -

What are ZIPs?

-

Zcash Improvement Proposals (ZIPs) are the way to:

-
    -
  • propose new features for the Zcash cryptocurrency and their rationale,
  • -
  • specify the implementation details of the feature,
  • -
  • collect community input on the proposal, and
  • -
  • document design decisions.
  • -
-
-

Contributing

-

The authors of a ZIP are responsible for building consensus within the community and documenting / addressing dissenting opinions.

-

Anyone can write a ZIP! We encourage community contributions and decentralization of work on the Zcash protocol. If you’d like to bounce ideas off people before formally writing a ZIP, we encourage it! Visit the ZcashCommunity Discord chat to talk about your idea.

-

Participation in the Zcash project is subject to a Code of Conduct.

-

The Zcash protocol is documented in its Protocol Specification.

-

To start contributing, first read ZIP 0 which documents the ZIP process. Then clone this repo from GitHub, and start adding your draft ZIP, formatted either as reStructuredText or as Markdown, into the zips/ directory.

-

For example, if using reStructuredText, use a filename matching zips/draft-*.rst. Use make to check that you are using correct reStructuredText or Markdown syntax, and double-check the generated rendered/draft-*.html file before filing a Pull Request. See here for the project dependencies.

-
-

License

-

Unless otherwise stated in this repository’s individual files, the contents of this repository are released under the terms of the MIT license. See COPYING for more information or see https://opensource.org/licenses/MIT .

-
-

Released ZIPs

- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
ZIP Title Status
0 ZIP Process Active
32 Shielded Hierarchical Deterministic Wallets Final
143 Transaction Signature Validation for Overwinter Final
155 addrv2 message Proposed
173 Bech32 Format Final
200 Network Upgrade Mechanism Final
201 Network Peer Management for Overwinter Final
202 Version 3 Transaction Format for Overwinter Final
203 Transaction Expiry Final
205 Deployment of the Sapling Network Upgrade Final
206 Deployment of the Blossom Network Upgrade Final
207 Funding Streams Final
208 Shorter Block Target Spacing Final
209 Prohibit Negative Shielded Chain Value Pool Balances Final
211 Disabling Addition of New Value to the Sprout Chain Value Pool Final
212 Allow Recipient to Derive Ephemeral Secret from Note Plaintext Final
213 Shielded Coinbase Final
214 Consensus rules for a Zcash Development Fund Revision 0: Final, Revision 1: Draft
215 Explicitly Defining and Modifying Ed25519 Validation Rules Final
216 Require Canonical Jubjub Point Encodings Final
221 FlyClient - Consensus-Layer Changes Final
224 Orchard Shielded Protocol Final
225 Version 5 Transaction Format Final
239 Relay of Version 5 Transactions Final
243 Transaction Signature Validation for Sapling Final
244 Transaction Identifier Non-Malleability Final
250 Deployment of the Heartwood Network Upgrade Final
251 Deployment of the Canopy Network Upgrade Final
252 Deployment of the NU5 Network Upgrade Final
253 Deployment of the NU6 Network Upgrade Proposed
300 Cross-chain Atomic Transactions Proposed
301 Zcash Stratum Protocol Final
308 Sprout to Sapling Migration Final
316 Unified Addresses and Unified Viewing Keys Revision 0: Final, Revision 1: Proposed
317 Proportional Transfer Fee Mechanism Active
320 Defining an Address Type to which funds can only be sent from Transparent Addresses Proposed
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
2001 Lockbox Funding Streams Proposed
-

Draft ZIPs

-

These are works-in-progress that have been assigned ZIP numbers. These will eventually become either Proposed (and thus Released), or one of Withdrawn, Rejected, or Obsolete.

-

In some cases a ZIP number is reserved by the ZIP Editors before a draft is written.

- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
ZIP Title Status
1 Network Upgrade Policy and Scheduling Reserved
2 Design Considerations for Network Upgrades Reserved
68 Relative lock-time using consensus-enforced sequence numbers Draft
76 Transaction Signature Validation before Overwinter Reserved
112 CHECKSEQUENCEVERIFY Draft
113 Median Time Past as endpoint for lock-time calculations Draft
204 Zcash P2P Network Protocol Reserved
217 Aggregate Signatures Reserved
219 Disabling Addition of New Value to the Sapling Chain Value Pool Reserved
222 Transparent Zcash Extensions Draft
226 Transfer and Burn of Zcash Shielded Assets Draft
227 Issuance of Zcash Shielded Assets Draft
228 Asset Swaps for Zcash Shielded Assets Reserved
230 Version 6 Transaction Format Draft
231 Decouple Memos from Transaction Outputs Reserved
233 Establish the Zcash Sustainability Fund on the Protocol Level Draft
234 Smooth Out The Block Subsidy Issuance Draft
236 Blocks should balance exactly Draft
245 Transaction Identifier Digests & Signature Validation for Transparent Zcash Extensions Draft
302 Standardized Memo Field Format Draft
303 Sprout Payment Disclosure Reserved
304 Sapling Address Signatures Draft
305 Best Practices for Hardware Wallets supporting Sapling Reserved
306 Security Considerations for Anchor Selection Reserved
307 Light Client Protocol for Payment Detection Draft
309 Blind Off-chain Lightweight Transactions (BOLT) Reserved
310 Security Properties of Sapling Viewing Keys Draft
311 Zcash Payment Disclosures Draft
312 FROST for Spend Authorization Multisignatures Draft
314 Privacy upgrades to the Zcash light client protocol Reserved
315 Best Practices for Wallet Implementations Draft
318 Associated Payload Encryption Reserved
319 Options for Shielded Pool Retirement Reserved
322 Generic Signed Message Format Reserved
323 Specification of getblocktemplate for Zcash Reserved
324 URI-Encapsulated Payments Draft
332 Wallet Recovery from zcashd HD Seeds Reserved
339 Wallet Recovery Words Reserved
400 Wallet.dat format Draft
402 New Wallet Database Format Reserved
403 Verification Behaviour of zcashd Reserved
416 Support for Unified Addresses in zcashd Reserved
guide-markdown {Something Short and To the Point} Draft
guide {Something Short and To the Point} Draft
-

Drafts without assigned ZIP numbers

-

These are works-in-progress, and may never be assigned ZIP numbers if their ideas become obsoleted or abandoned. Do not assume that these drafts will exist in perpetuity; instead assume that they will either move to a numbered ZIP, or be deleted.

- - - - - -
Title
Manufacturing Consent; Re-Establishing a Dev Fund for ECC, ZF, ZCG, Qedit, FPF, and ZecHub
Block Reward Allocation for Non-Direct Development Funding
Establishing a Hybrid Dev Fund for ZF, ZCG and a Dev Fund Reserve
-

Withdrawn, Rejected, or Obsolete ZIPs

-
-Click to show/hide - - - - - - - - - - - - - - - - - - -
ZIP Title Status
210 Sapling Anchor Deduplication within Transactions Withdrawn
220 Zcash Shielded Assets Withdrawn
313 Reduce Conventional Transaction Fee to 1000 zatoshis Obsolete
1001 Keep the Block Distribution as Initially Defined — 90% to Miners Obsolete
1002 Opt-in Donation Feature Obsolete
1003 20% Split Evenly Between the ECC and the Zcash Foundation, and a Voting System Mandate Obsolete
1004 Miner-Directed Dev Fund Obsolete
1005 Zcash Community Funding System Obsolete
1006 Development Fund of 10% to a 2-of-3 Multisig with Community-Involved Third Entity Obsolete
1007 Enforce Development Fund Commitments with a Legal Charter Obsolete
1008 Fund ECC for Two More Years Obsolete
1009 Five-Entity Strategic Council Obsolete
1010 Compromise Dev Fund Proposal With Diverse Funding Streams Obsolete
1011 Decentralize the Dev Fee Obsolete
1012 Dev Fund to ECC + ZF + Major Grants Obsolete
1013 Keep It Simple, Zcashers: 10% to ECC, 10% to ZF Obsolete
-
-

Index of ZIPs

- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
ZIP Title Status
0 ZIP Process Active
1 Network Upgrade Policy and Scheduling Reserved
2 Design Considerations for Network Upgrades Reserved
32 Shielded Hierarchical Deterministic Wallets Final
68 Relative lock-time using consensus-enforced sequence numbers Draft
76 Transaction Signature Validation before Overwinter Reserved
112 CHECKSEQUENCEVERIFY Draft
113 Median Time Past as endpoint for lock-time calculations Draft
143 Transaction Signature Validation for Overwinter Final
155 addrv2 message Proposed
173 Bech32 Format Final
200 Network Upgrade Mechanism Final
201 Network Peer Management for Overwinter Final
202 Version 3 Transaction Format for Overwinter Final
203 Transaction Expiry Final
204 Zcash P2P Network Protocol Reserved
205 Deployment of the Sapling Network Upgrade Final
206 Deployment of the Blossom Network Upgrade Final
207 Funding Streams Final
208 Shorter Block Target Spacing Final
209 Prohibit Negative Shielded Chain Value Pool Balances Final
210 Sapling Anchor Deduplication within Transactions Withdrawn
211 Disabling Addition of New Value to the Sprout Chain Value Pool Final
212 Allow Recipient to Derive Ephemeral Secret from Note Plaintext Final
213 Shielded Coinbase Final
214 Consensus rules for a Zcash Development Fund Revision 0: Final, Revision 1: Draft
215 Explicitly Defining and Modifying Ed25519 Validation Rules Final
216 Require Canonical Jubjub Point Encodings Final
217 Aggregate Signatures Reserved
219 Disabling Addition of New Value to the Sapling Chain Value Pool Reserved
220 Zcash Shielded Assets Withdrawn
221 FlyClient - Consensus-Layer Changes Final
222 Transparent Zcash Extensions Draft
224 Orchard Shielded Protocol Final
225 Version 5 Transaction Format Final
226 Transfer and Burn of Zcash Shielded Assets Draft
227 Issuance of Zcash Shielded Assets Draft
228 Asset Swaps for Zcash Shielded Assets Reserved
230 Version 6 Transaction Format Draft
231 Decouple Memos from Transaction Outputs Reserved
233 Establish the Zcash Sustainability Fund on the Protocol Level Draft
234 Smooth Out The Block Subsidy Issuance Draft
236 Blocks should balance exactly Draft
239 Relay of Version 5 Transactions Final
243 Transaction Signature Validation for Sapling Final
244 Transaction Identifier Non-Malleability Final
245 Transaction Identifier Digests & Signature Validation for Transparent Zcash Extensions Draft
250 Deployment of the Heartwood Network Upgrade Final
251 Deployment of the Canopy Network Upgrade Final
252 Deployment of the NU5 Network Upgrade Final
253 Deployment of the NU6 Network Upgrade Proposed
300 Cross-chain Atomic Transactions Proposed
301 Zcash Stratum Protocol Final
302 Standardized Memo Field Format Draft
303 Sprout Payment Disclosure Reserved
304 Sapling Address Signatures Draft
305 Best Practices for Hardware Wallets supporting Sapling Reserved
306 Security Considerations for Anchor Selection Reserved
307 Light Client Protocol for Payment Detection Draft
308 Sprout to Sapling Migration Final
309 Blind Off-chain Lightweight Transactions (BOLT) Reserved
310 Security Properties of Sapling Viewing Keys Draft
311 Zcash Payment Disclosures Draft
312 FROST for Spend Authorization Multisignatures Draft
313 Reduce Conventional Transaction Fee to 1000 zatoshis Obsolete
314 Privacy upgrades to the Zcash light client protocol Reserved
315 Best Practices for Wallet Implementations Draft
316 Unified Addresses and Unified Viewing Keys Revision 0: Final, Revision 1: Proposed
317 Proportional Transfer Fee Mechanism Active
318 Associated Payload Encryption Reserved
319 Options for Shielded Pool Retirement Reserved
320 Defining an Address Type to which funds can only be sent from Transparent Addresses Proposed
321 Payment Request URIs Proposed
322 Generic Signed Message Format Reserved
323 Specification of getblocktemplate for Zcash Reserved
324 URI-Encapsulated Payments Draft
332 Wallet Recovery from zcashd HD Seeds Reserved
339 Wallet Recovery Words Reserved
400 Wallet.dat format Draft
401 Addressing Mempool Denial-of-Service Active
402 New Wallet Database Format Reserved
403 Verification Behaviour of zcashd Reserved
416 Support for Unified Addresses in zcashd Reserved
1001 Keep the Block Distribution as Initially Defined — 90% to Miners Obsolete
1002 Opt-in Donation Feature Obsolete
1003 20% Split Evenly Between the ECC and the Zcash Foundation, and a Voting System Mandate Obsolete
1004 Miner-Directed Dev Fund Obsolete
1005 Zcash Community Funding System Obsolete
1006 Development Fund of 10% to a 2-of-3 Multisig with Community-Involved Third Entity Obsolete
1007 Enforce Development Fund Commitments with a Legal Charter Obsolete
1008 Fund ECC for Two More Years Obsolete
1009 Five-Entity Strategic Council Obsolete
1010 Compromise Dev Fund Proposal With Diverse Funding Streams Obsolete
1011 Decentralize the Dev Fee Obsolete
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
2001 Lockbox Funding Streams Proposed
guide-markdown {Something Short and To the Point} Draft
guide {Something Short and To the Point} Draft
-
- - \ No newline at end of file diff --git a/rendered/protocol/blossom.pdf b/rendered/protocol/blossom.pdf deleted file mode 100644 index bd6601412..000000000 Binary files a/rendered/protocol/blossom.pdf and /dev/null differ diff --git a/rendered/protocol/canopy.pdf b/rendered/protocol/canopy.pdf deleted file mode 100644 index a2cc318da..000000000 Binary files a/rendered/protocol/canopy.pdf and /dev/null differ diff --git a/rendered/protocol/heartwood.pdf b/rendered/protocol/heartwood.pdf deleted file mode 100644 index a380d6cfa..000000000 Binary files a/rendered/protocol/heartwood.pdf and /dev/null differ diff --git a/rendered/protocol/nu5.pdf b/rendered/protocol/nu5.pdf deleted file mode 100644 index f5a6655c1..000000000 Binary files a/rendered/protocol/nu5.pdf and /dev/null differ diff --git a/rendered/protocol/protocol.pdf b/rendered/protocol/protocol.pdf deleted file mode 100644 index 0e58d8841..000000000 Binary files a/rendered/protocol/protocol.pdf and /dev/null differ diff --git a/rendered/protocol/sapling.pdf b/rendered/protocol/sapling.pdf deleted file mode 100644 index 0939d0a14..000000000 Binary files a/rendered/protocol/sapling.pdf and /dev/null differ diff --git a/rendered/protocol/sprout.pdf b/rendered/protocol/sprout.pdf deleted file mode 100644 index 5f6daac92..000000000 Binary files a/rendered/protocol/sprout.pdf and /dev/null differ diff --git a/rendered/zip-0000.html b/rendered/zip-0000.html deleted file mode 100644 index a0be30265..000000000 --- a/rendered/zip-0000.html +++ /dev/null @@ -1,439 +0,0 @@ - - - - ZIP 0: ZIP Process - - - -
-
ZIP: 0
-Title: ZIP Process
-Owners: Jack Grigg <str4d@electriccoin.co>
-        Conrado Gouvêa <conrado@zfnd.org>
-        Arya <arya@zfnd.org>
-        Kris Nuttycombe <kris@nutty.land>
-Original-Authors: Daira-Emma Hopwood
-                  Josh Cincinnati
-                  George Tankersley
-                  Deirdre Connolly
-                  teor
-                  Aditya Bharadwaj
-Credits: Luke Dashjr
-Status: Active
-Category: Process
-Created: 2019-02-16
-License: BSD-2-Clause
-

Terminology

-

The key words "MUST", "MUST NOT", "SHOULD", "SHOULD NOT", "MAY", "RECOMMENDED", "OPTIONAL", and "REQUIRED" 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. 3

-
-

Abstract

-

A Zcash Improvement Proposal (ZIP) is a design document providing information to the Zcash community, or describing a new feature for Zcash or its processes or environment. The ZIP should provide a concise technical specification of the feature and a rationale for the feature.

-

We intend ZIPs to be the primary mechanism for proposing new features, for collecting community input on an issue, and for documenting the design decisions that have gone into Zcash. The Owner(s) of the ZIP (usually the authors(s)) are responsible for building consensus within the community and documenting dissenting opinions.

-

Because the ZIPs are maintained as text files in a versioned repository, their revision history is the historical record of the feature proposal.

-

This document is based partly on the work done by Luke Dashjr with BIP 2.

-
-

ZIP Workflow

-

The ZIP process begins with a new idea for Zcash. Each potential ZIP must have Owners — one or more people who write the ZIP using the style and format described below, shepherd the discussions in the appropriate forums, and attempt to build community consensus around the idea. The ZIP Owners should first attempt to ascertain whether the idea is ZIP-able. Small enhancements or patches to a particular piece of software often don't require standardisation between multiple projects; these don't need a ZIP and should be injected into the relevant project-specific development workflow with a patch submission to the applicable issue tracker. Additionally, many ideas have been brought forward for changing Zcash that have been rejected for various reasons. The first step should be to search past discussions to see if an idea has been considered before, and if so, what issues arose in its progression. After investigating past work, the best way to proceed is by posting about the new idea to the Zcash Community Forum.

-

Vetting an idea publicly before going as far as writing a ZIP is meant to save both the potential Owners and the wider community time. Asking the Zcash community first if an idea is original helps prevent too much time being spent on something that is guaranteed to be rejected based on prior discussions (searching the internet does not always do the trick). It also helps to make sure the idea is applicable to the entire community and not just the Owners. Just because an idea sounds good to the Owners does not mean it will work for most people in most areas where Zcash is used.

-

Once the Owners have asked the Zcash community as to whether an idea has any chance of acceptance, a draft ZIP should be presented to the Zcash Community Forum. This gives the Owners a chance to flesh out the draft ZIP to make it properly formatted, of high quality, and to address additional concerns about the proposal. Following a discussion, the proposal should be submitted to the ZIPs git repository 9 as a pull request. This draft must be written in ZIP style as described below, and named with an alias such as draft-zatoshizakamoto-42millionzec until the ZIP Editors have assigned it a ZIP number (Owners MUST NOT self-assign ZIP numbers).

-

ZIP Owners are responsible for collecting community feedback on both the initial idea and the ZIP before submitting it for review. However, wherever possible, long open-ended discussions on forums should be avoided.

-

It is highly recommended that a single ZIP contain a single key proposal or new idea. The more focused the ZIP, the more successful it tends to be. If in doubt, split your ZIP into several well-focused ones.

-

When the ZIP draft is complete, the ZIP Editors will assign the ZIP a number (if that has not already been done) and one or more Categories, and merge the pull request to the ZIPs git repository. The ZIP Editors will not unreasonably reject a ZIP. Reasons for rejecting ZIPs include duplication of effort, disregard for formatting rules, being too unfocused or too broad, being technically unsound, not providing proper motivation or not in keeping with the Zcash philosophy. For a ZIP to be accepted it must meet certain minimum criteria. It must be a clear and complete description of the proposed enhancement. The enhancement must represent a net improvement. The proposed implementation, if applicable, must be solid and must not complicate the protocol unduly.

-

The ZIP Owners may update the draft as necessary in the git repository. Updates to drafts should also be submitted by the Owners as pull requests.

-

ZIP Numbering Conventions

-

The ZIP Editors currently use the following conventions when numbering ZIPs:

-
    -
  • if a ZIP directly corresponds to a BIP (Bitcoin Improvement Proposal), and the number doesn't clash, assign the same number;
  • -
  • if it affects the consensus layer or the core protocol, assign a number in the range 200..299;
  • -
  • if it affects only higher layers but is needed for interoperability between node implementations or other parts of the ecosystem, assign a number in the range 300..399;
  • -
  • if it is specific to an implementation (e.g. zcashd or zebra), assign a number in the range 400..499;
  • -
  • if it concerns Consensus Process, assign a number in the range 0..9 or above 1000;
  • -
  • try to number ZIPs that should or will be deployed together consecutively (subject to the above conventions), and in a coherent reading order.
  • -
-

These conventions are subject to change by consensus of the ZIP Editors.

-
-

Transferring ZIP Ownership

-

It occasionally becomes necessary to transfer ownership of ZIPs to a new Owner. In general, we'd like to retain the original Owner as a co-Owner of the transferred ZIP, but that's really up to the original Owner. A good reason to transfer ownership is because the original Owner no longer has the time or interest in updating it or following through with the ZIP process, or has fallen off the face of the 'net (i.e. is unreachable or not responding to email). A bad reason to transfer ownership is because you don't agree with the direction of the ZIP. We try to build consensus around a ZIP, but if that's not possible, you can always submit a competing ZIP.

-

If you are interested in assuming ownership of a ZIP, send a message asking to take over, addressed to all of the current Owner(s) and the ZIP Editors. If the Owner(s) who are proposed to be removed don't respond in a timely manner, the ZIP Editors and any remaining current Owners will make a decision (such decisions may be reversed).

-

If an author of a ZIP is no longer an Owner, an Original-Authors: field SHOULD be added to the ZIP metadata indicating the original authorship (without email addresses), unless the original author(s) request otherwise.

-
-

ZIP Editors

-

The current ZIP Editors are:

-
    -
  • Jack Grigg and Kris Nuttycombe, associated with the Electric Coin Company;
  • -
  • Conrado Gouvêa and Arya, associated with the Zcash Foundation.
  • -
-

All can be reached at zips@z.cash. The current design of the ZIP Process dictates that there are always at least two ZIP Editors: at least one from the Electric Coin Company and at least one from the Zcash Foundation.

-

ZIP Editors MUST declare any potential or perceived conflict of interest they have relating to their responsibilities as ZIP Editors.

-

ZIP Editors MUST be publicly transparent about any external influence or constraints that have been placed or attempted to be placed on their actions as ZIP Editors (including from the Electric Coin Company, Zcash Foundation, or other organizations with which the Editors are associated), whether or not it affects those actions. This should not be interpreted as requiring ZIP Editors to reveal knowledge of undisclosed security vulnerabilities or mitigations.

-

Additional Editors may be selected, with their consent, by consensus among the current Editors.

-

An Editor may be removed or replaced by consensus among the current Editors. However, if the other ZIP Editors have consensus, an Editor can not prevent their own removal.

-

Any Editor can resign by informing the other Editors in writing.

-

Whenever the ZIP Editors change, the new ZIP Editors SHOULD:

-
    -
  • review this ZIP to make sure it reflects current practice,
  • -
  • update the Owners of this ZIP,
  • -
  • review access to the ZIPs repository,
  • -
  • update the <zips@z.cash> email alias, and
  • -
  • invite new Editors to the Zcash Community Forum, and the #zips channel on Discord.
  • -
-

If it has been at least 12 months since the last ZIP Editor change, the ZIP Editors SHOULD:

-
    -
  • review this ZIP to make sure it reflects current practice.
  • -
-
-

ZIP Editor Responsibilities

-

The ZIP Editors subscribe to the Zcash Community Forum.

-

Each new ZIP SHOULD be submitted as a "pull request" to the ZIPs git repository 9. It SHOULD NOT contain a ZIP number unless one had already been assigned by the ZIP Editors. The pull request SHOULD initially be marked as a Draft. The ZIP content SHOULD be submitted in reStructuredText 6 or Markdown 7 format. Generating HTML for a ZIP is OPTIONAL.

-

For each new ZIP that comes in, the ZIP Editors SHOULD:

-
    -
  • Read the ZIP to check if it is ready: sound and complete. The ideas must make technical sense, even if they don't seem likely to be accepted.
  • -
  • Check that the title accurately describes the content.
  • -
  • Ensure that the ZIP draft has been sent to the Zcash Community Forum and as a PR to the ZIPs git repository 9.
  • -
  • Ensure that motivation and backward compatibility have been addressed, if applicable.
  • -
  • Check that the licensing terms are acceptable for ZIPs.
  • -
-
-

Reviewing a ZIP

-

Any ZIP Editor can suggest changes to a ZIP. These suggestions are the opinion of the individual ZIP Editor. Any technical or process review that ZIP Editors perform is expected to be independent of their contractual or other relationships.

-

ZIP Owners are free to clarify, modify, or decline suggestions from ZIP Editors. If the ZIP Editors make a change to a ZIP that the Owners disagree with, then the Editors SHOULD revert the change.

-

Typically, the ZIP Editors suggest changes in two phases:

-
    -
  • content review: multiple ZIP Editors discuss the ZIP, and suggest changes to the overall content. This is a "big picture" review.
  • -
  • format review: two ZIP Editors do a detailed review of the structure and format of the ZIP. This ensures the ZIP is consistent with other Zcash specifications.
  • -
-

If the ZIP isn't ready, the Editors will send it back to the Owners for revision, with specific instructions. This decision is made by consensus among the current Editors.

-

When a ZIP is ready, the ZIP Editors will:

-
    -
  • Ensure that a unique ZIP number has been assigned in the pull request.
  • -
  • Regenerate the corresponding HTML documents, if required.
  • -
  • Remove Draft status and merge the pull request.
  • -
-

The ZIP editors monitor ZIP changes and update ZIP headers as appropriate.

-
-

Rejecting a ZIP or update

-

The ZIP Editors MAY reject a new ZIP or an update to an existing ZIP, by consensus among the current Editors. Rejections can be based on any of the following reasons:

-
    -
  • it violates the Zcash Code of Conduct 4 ;
  • -
  • it appears too unfocused or broad;
  • -
  • it duplicates effort in other ZIPs without sufficient technical justification (however, alternative proposals to address similar or overlapping problems are not excluded for this reason);
  • -
  • it has manifest security flaws (including being unrealistically dependent on user vigilance to avoid security weaknesses);
  • -
  • it disregards compatibility with the existing Zcash blockchain or ecosystem;
  • -
  • it is manifestly unimplementable;
  • -
  • it includes buggy code, pseudocode, or algorithms;
  • -
  • it manifestly violates common expectations of a significant portion of the Zcash community;
  • -
  • it updates a ZIP's status, or fails to make a needed status update, in a way inconsistent with the requirements in Specification of Status Workflow;
  • -
  • in the case of a Proposed, Active, Implemented, or Final ZIP, the update makes a substantive change to which there is significant community opposition;
  • -
  • it is dependent on a patent that could potentially be an obstacle to adoption of the ZIP;
  • -
  • it includes commercial advertising or spam;
  • -
  • it disregards formatting rules;
  • -
  • it makes non-editorial edits to previous entries in a ZIP's Change history, if there is one;
  • -
  • an update to an existing ZIP extends or changes its scope to an extent that would be better handled as a separate ZIP;
  • -
  • a new ZIP has a category that does not reflect its content, or an update would change a ZIP to an inappropriate category;
  • -
  • it violates any specific "MUST" or "MUST NOT" rule in this document;
  • -
  • the expressed political views of a Owner of the document are inimical to the Zcash Code of Conduct 4 (except in the case of an update removing that Owner);
  • -
  • it is not authorized by the stated ZIP Owners;
  • -
  • it removes an Owner without their consent (unless the reason for removal is directly related to a breach of the Code of Conduct by that Owner);
  • -
  • it violates a conformance requirement of any Active Process ZIP (including this ZIP).
  • -
-

The ZIP Editors MUST NOT unreasonably deny publication of a ZIP proposal or update that does not violate any of these criteria. If they refuse a proposal or update, they MUST give an explanation of which of the criteria were violated, with the exception that spam may be deleted without an explanation.

-

Note that it is not the primary responsibility of the ZIP Editors to review proposals for security, correctness, or implementability.

-
-

Communicating with the ZIP Editors

-

Please send all ZIP-related communications either:

- -

All communications should abide by the Zcash Code of Conduct 4 and follow the GNU Kind Communication Guidelines 5.

-
-

ZIP Editor Meeting Practices

-

The ZIP Editors SHOULD meet on a regular basis to review draft changes to ZIPs. Meeting times are agreed by consensus among the current ZIP Editors. A ZIP Editor meeting can be held even if some ZIP Editors are not available, but all Editors SHOULD be informed of significant decisions that are likely to be made at upcoming meetings.

-

The ZIP Editors will appoint a ZIP Secretary, which can be a shared or rotating role. The ZIP Secretary will:

-
    -
  • share a draft agenda with the ZIP Editors at least 24 hours before each ZIP Editors' meeting;
  • -
  • share draft minutes of significant decisions with the ZIP Editors in the week after the ZIP Editors' meeting; and
  • -
  • share significant ZIP changes, including significant changes of status (in particular, progression of a ZIP to Proposed status), on the Zcash Community Forum.
  • -
-

If the draft agenda is empty, any ZIP Editor MAY submit agenda items, or suggest that the meeting is cancelled.

-
-
-

ZIP format and structure

-

ZIPs SHOULD be written in reStructuredText 6, Markdown 7, or LaTeX 8. For ZIPs written in LaTeX, a Makefile MUST be provided to build (at least) a PDF version of the document.

-

Each ZIP SHOULD have the following parts:

-
    -
  • Preamble — Headers containing metadata about the ZIP (see below). The License field of the preamble indicates the licensing terms, which MUST be acceptable according to the ZIP licensing requirements.
  • -
  • Terminology — Definitions of technical or non-obvious terms used in the document.
  • -
  • Abstract — A short (~200 word) description of the technical issue being addressed.
  • -
  • Motivation — The motivation is critical for ZIPs that want to change the Zcash protocol. It should clearly explain why the existing protocol is inadequate to address the problem that the ZIP solves.
  • -
  • Specification — The technical specification should describe the interface and semantics of any new feature. The specification should be detailed enough to allow competing, interoperable implementations for any of the current Zcash platforms.
  • -
  • Rationale — The rationale fleshes out the specification by describing what motivated the design and why particular design decisions were made. It should describe alternate designs that were considered and related work. The rationale should provide evidence of consensus within the community and discuss important objections or concerns raised during discussion. -

    For longer ZIPs it can potentially be easier to have inline Rationale subsections interspersed throughout the Specification part. When taking this approach, the content of these subsections should be annotated with HTML tags to make it collapsible (so the rationale is available for review but doesn't get in the way of reading the specification). ZIPs written in Markdown can use the following syntax (note the newline after the <summary> tag):

    -
    # Specification
    -
    -## Foobar
    -
    -Important details.
    -
    -<details>
    -<summary>
    -
    -### Rationale for foobar
    -</summary>
    -
    -Important but hidden rationale!
    -</details>
    -

    ZIPs written in reStructuredText can use the following syntax:

    -
    Specification
    -=============
    -
    -Foobar
    -------
    -
    -Important details.
    -
    -Rationale for foobar
    -''''''''''''''''''''
    -
    -.. raw:: html
    -
    -   <details>
    -   <summary>Click to show/hide</summary>
    -
    -Important but hidden rationale!
    -
    -.. raw:: html
    -
    -   </details>
    -
  • -
  • Security and privacy considerations — If applicable, security and privacy considerations should be explicitly described, particularly if the ZIP makes explicit trade-offs or assumptions. For guidance on this section consider RFC 3552 2 as a starting point.
  • -
  • Reference implementation — Literal code implementing the ZIP's specification, and/or a link to the reference implementation of the ZIP's specification. The reference implementation MUST be completed before any ZIP is given status “Implemented” or “Final”, but it generally need not be completed before the ZIP is accepted into “Proposed”.
  • -
-

ZIP stubs

-

A ZIP stub records that the ZIP Editors have reserved a number for a ZIP that is under development. It is not a ZIP, but exists in the ZIPs git repository 9 at the same path that will be used for the corresponding ZIP if and when it is published. It consists only of a preamble, which MUST use Reserved as the value of the Status field.

-

ZIP stubs can be added and removed, or replaced by the corresponding ZIP, at the discretion of the ZIP Editors. If a ZIP stub is removed then its number MAY be reused, possibly for an entirely different ZIP.

-
-

ZIP header preamble

-

Each ZIP or ZIP stub MUST begin with a RFC 822-style header preamble. For ZIPs and ZIP stubs written in reStructuredText, this is represented as :: on the first line, followed by a blank line, then the preamble indented by 2 spaces.

-

The following header fields are REQUIRED for ZIPs:

-
ZIP:
-Title:
-Owners:
-Status:
-Category:
-Created:
-License:
-

The following additional header fields are OPTIONAL for ZIPs:

-
Credits:
-Original-Authors:
-Discussions-To:
-Pull-Request:
-Obsoleted-By:
-Updated-By:
-Obsoletes:
-Updates:
-

For ZIP stubs, only the ZIP:, Title:, Status:, and Category: fields are REQUIRED. Typically the other fields applicable to ZIP stubs are Credits:, Discussions-To: and Pull-Request:, which are OPTIONAL.

-

The Owners header lists the names and email addresses of all the Owners of the ZIP. The format of the Owners header value SHOULD be:

-
Random J. User <address@dom.ain>
-

If there are multiple Owners, each should be on a separate line.

-

Credits: and Original-Authors: fields SHOULD NOT include email addresses.

-

The "Owners", "Credits", and "Original-Authors" headers always use these plural spellings even there is only one Owner, one person to be credited, or one original author.

-

While a ZIP is in public discussions (usually during the initial Draft phase), a Discussions-To header will indicate the URL where the ZIP is being discussed. No Discussions-To header is necessary if the ZIP is being discussed privately with the Owner.

-

The Pull-Request header, if present, gives an URL to a Pull Request for the ZIP.

-

The Category header specifies the type of ZIP, as described in ZIP categories. Multiple categories MAY be specified, separated by " / ".

-

The Created header records the date that the ZIP was submitted. Dates should be in yyyy-mm-dd format, e.g. 2001-08-14.

-

For ZIPs written in reStructuredText, URLs in header fields SHOULD be surrounded by < >; this ensures that the link is rendered correctly.

-
-

Auxiliary Files

-

ZIPs may include auxiliary files such as diagrams. Auxiliary files should be included in a subdirectory for that ZIP; that is, for any ZIP that requires more than one file, all of the files SHOULD be in a subdirectory named zip-XXXX.

-
-
-

ZIP categories

-

Each ZIP is in one or more of the following categories, as specified in the Category header:

-
-
Consensus
-
Rules that affect the consensus protocol followed by all Zcash implementations.
-
Standards
-
Non-consensus changes affecting most or all Zcash implementations, or the interoperability of applications using Zcash.
-
Process
-
A Process ZIP describes a process surrounding Zcash, or proposes a change to (or an event in) a process. They may propose an implementation, but not to Zcash's codebase; they often require community consensus; unlike Informational ZIPs, they are more than recommendations, and users are typically not free to ignore them. Examples include procedures, guidelines, changes to the decision-making process, and changes to the tools or environment used in Zcash development.
-
Consensus Process
-
A subcategory of Process ZIP that specifies requirements and processes that are to be realized by one or more Consensus ZIPs, and/or by social consensus of the Zcash community.
-
Informational
-
An Informational ZIP describes non-consensus Zcash design issues, or general guidelines or information for the Zcash community. These ZIPs do not necessarily represent a Zcash community consensus or recommendation, so users and implementors are free to ignore Informational ZIPs or follow their advice.
-
Network
-
Specifications of peer-to-peer networking behaviour.
-
RPC
-
Specifications of the RPC interface provided by zcashd nodes.
-
Wallet
-
Specifications affecting wallets (e.g. non-consensus changes to how transactions, addresses, etc. are constructed or interpreted).
-
Ecosystem
-
Specifications otherwise useful to the Zcash ecosystem.
-
-

New categories may be added by consensus among the ZIP Editors.

-

Consensus and Standards ZIPs SHOULD have a Reference Implementation section, which includes or (more often) links to an implementation.

-

Consensus ZIPs SHOULD have a Deployment section, describing how and when the consensus change is planned to be deployed (for example, in a particular network upgrade).

-
-

ZIP Status Field

-
    -
  • Reserved: The ZIP Editors have reserved this ZIP number, and there MAY be a Pull Request for it, but no ZIP has been published. The ZIP Editors SHOULD publish a stub header so that the reservation appears in the ZIP index. This status MUST only be used for ZIP stubs.
  • -
  • Draft: All initial ZIP submissions have this status.
  • -
  • Withdrawn: The Owners of a ZIP MAY remove it from consideration by the community, by changing its status to Withdrawn (in a PR or by request to the ZIP Editors).
  • -
  • Active: Typically only used for Process or Informational ZIPs, achieved once rough consensus on a Proposed ZIP is reached in PR/forum posts.
  • -
  • Proposed: Typically the stage after Draft, added to a ZIP after consideration, feedback, and rough consensus from the community.
  • -
  • Rejected: If no progress on a Draft or Proposed ZIP has been made for one year, the ZIP Editors SHOULD move it to Rejected status. It can revert back to Draft or Proposed if the Owners resume work or resolve issues preventing consensus.
  • -
  • Implemented: When a Consensus or Standards ZIP has a working reference implementation but before activation on the Zcash network. The status MAY indicate which node implementation has implemented the ZIP, e.g. "Implemented (zcashd)" or "Implemented (zebra)".
  • -
  • Final: When a Consensus or Standards ZIP is both implemented and activated on the Zcash network.
  • -
  • Obsolete: The status when a ZIP is no longer relevant (typically when superseded by another ZIP).
  • -
-

Specification of Status Workflow

-

Owners of a ZIP MAY decide on their own to change the status between Draft or Withdrawn. All other changes in status MUST be approved by consensus among the current ZIP Editors.

-

A ZIP SHOULD only change status from Draft (or Rejected) to Proposed, when the Owner deems it is complete and there is rough consensus on the forums, validated by consensus among the current ZIP Editors. If it's a Consensus ZIP, a Deployment section MUST be present in order for the ZIP to change status to Proposed. Typically, although not necessarily, this will specify a network upgrade in which the consensus change is to activate.

-

A ZIP's status is Released if it is Proposed, Active, Implemented, or Final (i.e. not Draft, Rejected, Obsolete, or Withdrawn).

-

A ZIP SHOULD NOT be changed from a non-Released status to a Released status if there is significant community opposition to its content. (However, Draft ZIPs explicitly MAY describe proposals to which there is, or could be expected, significant community opposition.)

-

A Released ZIP MUST NOT be changed to a non-Released status if the specification is already implemented and is in common use, or where a Process ZIP still reflects a consensus of the community.

-

A Standards ZIP SHOULD only change status from Proposed to Implemented once the Owners provide an associated reference implementation. For Consensus ZIPs, an implementation MUST have been merged into at least one consensus node codebase (currently zcashd and/or zebra), typically in the period after the network upgrade's specification freeze but before the implementation audit. If the Owners miss this deadline, the Editors or Owners MAY choose to update the Deployment section of the ZIP to target another upgrade, at their discretion.

-

A Process or Informational ZIP SHOULD change status from Proposed to Active when it achieves rough consensus on the forum or PR. Such a proposal is said to have rough consensus if it has been substantially complete and open to discussion on the forum or GitHub PR for at least one month, has been in Proposed status for at least one week, and no person maintains any unaddressed substantiated objections to it. Addressed or obstructive objections can be ignored/overruled by general agreement that they have been sufficiently addressed, but clear reasoning MUST be given in such circumstances.

-

When an Active, Implemented, or Final ZIP is no longer relevant –for example because its implementation has fallen out of use or its process is no longer followed– its status SHOULD be changed to Obsolete. This change MUST also be objectively verifiable and/or discussed. Final ZIPs MAY be updated; the specification is still in force but modified by another specified ZIP or ZIPs (check the optional Updated-By header).

-

If a non-editorial update is made to an Obsolete, Withdrawn, or Rejected ZIP, its status MUST be changed appropriately.

-
-
-

ZIP Comments

-

Comments from the community on the ZIP should occur on the Zcash Community Forum and the comment fields of the pull requests in any open ZIPs. Editors will use these sources to judge rough consensus.

-
-

ZIP Licensing

-

New ZIPs may be accepted with the following licenses. Each new ZIP MUST identify at least one acceptable license in its preamble. Each license MUST be referenced by their respective abbreviation given below.

-

For example, a preamble might include the following License header:

-
License: BSD-2-Clause
-         GNU-All-Permissive
-

In this case, the ZIP text is fully licensed under both the OSI-approved BSD 2-clause license as well as the GNU All-Permissive License, and anyone may modify and redistribute the text provided they comply with the terms of either license. In other words, the license list is an "OR choice", not an "AND also" requirement.

-

It is also possible to license source code differently from the ZIP text. This case SHOULD be indicated in the Reference Implementation section of the ZIP. Again, each license MUST be referenced by its respective abbreviation given below.

-

Statements of code licenses in ZIPs are only advisory; anyone intending to use the code should look for license statements in the code itself.

-

ZIPs are not required to be exclusively licensed under approved terms, and MAY also be licensed under unacceptable licenses in addition to at least one acceptable license. In this case, only the acceptable license(s) should be listed in the License header.

- - -

Not acceptable licenses

-

All licenses not explicitly included in the above lists are not acceptable terms and MUST NOT be used for a Zcash Improvement Proposal.

-
-

Rationale

-

Bitcoin's BIP 1 allowed the Open Publication License or releasing into the public domain; was this insufficient?

-
    -
  • The OPL is generally regarded as obsolete, and not a license suitable for new publications.
  • -
  • The OPL license terms allowed for the author to prevent publication and derived works, which was widely considered inappropriate.
  • -
  • In some jurisdictions, releasing a work to the public domain is not recognised as a legitimate legal action, leaving the ZIP simply copyrighted with no redistribution or modification allowed at all.
  • -
-

Why are there software licenses included?

-
    -
  • Some ZIPs, especially in the Consensus category, may include literal code in the ZIP itself which may not be available under the exact license terms of the ZIP.
  • -
  • Despite this, not all software licenses would be acceptable for content included in ZIPs.
  • -
-
-
-

See Also

- -
-

Acknowledgements

-

We thank George Tankersley, Deirdre Connolly, Daira-Emma Hopwood, teor, and Aditya Bharadwaj for their past contributions as ZIP Editors.

-
-

References

- - - - - - - -
1Information 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"
- - - - - - - -
2RFC 3552: Guidelines for Writing RFC Text on Security Considerations
- - - - - - - -
3ZIP 200: Network Upgrade Mechanism
- - - - - - - -
4Zcash Code of Conduct
- - - - - - - -
5GNU Kind Communication Guidelines
- - - - - - - -
6reStructuredText documentation
- - - - - - - -
7The Markdown Guide
- - - - - - - -
8LaTeX — a document preparation system
- - - - - - - -
9ZIPs git repository
-
-
- - \ No newline at end of file diff --git a/rendered/zip-0001.html b/rendered/zip-0001.html deleted file mode 100644 index 5068a86f6..000000000 --- a/rendered/zip-0001.html +++ /dev/null @@ -1,16 +0,0 @@ - - - - ZIP 1: Network Upgrade Policy and Scheduling - - - -
-
ZIP: 1
-Title: Network Upgrade Policy and Scheduling
-Status: Reserved
-Category: Consensus Process
-Discussions-To: <https://github.com/zcash/zips/issues/343>
-
- - \ No newline at end of file diff --git a/rendered/zip-0002.html b/rendered/zip-0002.html deleted file mode 100644 index af0f59e4c..000000000 --- a/rendered/zip-0002.html +++ /dev/null @@ -1,16 +0,0 @@ - - - - ZIP 2: Design Considerations for Network Upgrades - - - -
-
ZIP: 2
-Title: Design Considerations for Network Upgrades
-Status: Reserved
-Category: Informational
-Discussions-To: <https://github.com/zcash/zips/issues/362>
-
- - \ No newline at end of file diff --git a/rendered/zip-0022.html b/rendered/zip-0022.html deleted file mode 100644 index feb2b7cd0..000000000 --- a/rendered/zip-0022.html +++ /dev/null @@ -1,16 +0,0 @@ - - - - ZIP 22: Specification of getblocktemplate for Zcash - - - -
-
ZIP: 22
-Title: Specification of getblocktemplate for Zcash
-Status: Reserved
-Category: RPC
-Discussions-To: <https://github.com/zcash/zips/issues/349>
-
- - \ No newline at end of file diff --git a/rendered/zip-0032.html b/rendered/zip-0032.html deleted file mode 100644 index 432702ad2..000000000 --- a/rendered/zip-0032.html +++ /dev/null @@ -1,1258 +0,0 @@ - - - - ZIP 32: Shielded Hierarchical Deterministic Wallets - - - - -
-
ZIP: 32
-Title: Shielded Hierarchical Deterministic Wallets
-Owners: Jack Grigg <str4d@electriccoin.co>
-        Daira-Emma Hopwood <daira-emma@electriccoin.co>
-Credits: Sean Bowe
-         Kris Nuttycombe
-         Ying Tong Lai
-         Pieter Wuille
-         Marek Palatinus
-         Pavol Rusnak
-Status: Final
-Category: Standards / Wallet
-Created: 2018-05-22
-License: MIT
-

- \(% 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

-

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

-

"Jubjub" refers to the elliptic curve defined in 15.

-

A "chain code" is a cryptovalue that is needed, in addition to a spending key, in order to derive descendant keys and addresses of that key.

-

The terms "Testnet" and "Mainnet" are to be interpreted as described in section 3.12 of the Zcash Protocol Specification 10.

-
-

Abstract

-

This proposal defines a mechanism for extending hierarchical deterministic wallets, as described in BIP 32 2, to support Zcash's shielded addresses.

-

The initial parts of the specification define (mostly) equivalent, but independent, systems for deriving a tree of key components from a single seed, for the following shielded pools (which have different internal key structures):

-
    -
  • Sapling
  • -
  • Orchard
  • -
-

Previous versions of this document also defined a similar derivation system for the Sprout shielded pool. This has been removed since it was never used, and is unlikely to be used given that zcashd no longer generates Sprout addresses (and neither Zebra nor the mobile SDKs have ever done so).

-

The last part shows how to use these trees in the context of existing BIP 44 5 wallets.

-

This specification complements the existing use by some Zcash wallets of BIP 32 and BIP 44 for transparent Zcash addresses, and is not intended to deprecate that usage (privacy risks of using transparent addresses notwithstanding).

-
-

Motivation

-

BIP 32 2 is the standard mechanism by which wallets for Bitcoin and its derivatives (including Zcash's transparent addresses 6) generate keys and addresses deterministically. This has several advantages over random generation:

-
    -
  • Wallets only need to store a single seed (particularly useful for hardware wallets).
  • -
  • A one-time backup of the seed (usually stored as a word phrase 3) can be used to recover funds from all future addresses.
  • -
  • Keys are arranged into a tree of chains, enabling wallets to represent "accounts" or other high-level structures.
  • -
  • Viewing authority or spending authority can be delegated independently for sub-trees without compromising the master seed.
  • -
-

At present, no such equivalent exists for Zcash's shielded addresses. This is of particular concern for hardware wallets; all currently-marketed devices only store a seed internally, and have trained their users to only backup that seed. Given that the Sapling upgrade will make it feasible to use hardware wallets with shielded addresses, it is desirable to have a standard mechanism for deriving them.

-
-

Conventions

-

Most of the notation and functions used in this ZIP are defined in the Zcash protocol specification 9. They are reproduced here for convenience:

-
    -
  • - \(\mathsf{truncate}_k(S)\) - means the sequence formed from the first - \(k\) - elements of - \(S\) - .
  • -
  • - \(a\,||\,b\) - means the concatenation of sequences - \(a\) - then - \(b\) - .
  • -
  • - \([k] P\) - means scalar multiplication of the elliptic curve point - \(P\) - by the scalar - \(k\) - .
  • -
  • - \(\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\) - .
  • -
  • - \(\mathsf{I2LEBSP}_\ell(k)\) - is the sequence of - \(\ell\) - bits representing - \(k\) - in little-endian order.
  • -
  • - \(\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.
  • -
  • - \(\mathsf{repr}_\mathbb{J}(P)\) - is the representation of the Jubjub elliptic curve point - \(P\) - as a bit sequence, defined in 15.
  • -
  • - \(\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\) - .
  • -
  • - \(\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\) - .
  • -
  • - \(\mathsf{PRF^{expand}}(\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.
  • -
  • - \(r_\mathbb{P}\) - is the order of the Pallas curve.
  • -
  • - \(\mathsf{ToScalar^{Sapling}}(x) :=\) - \(\mathsf{LEOS2IP}_{512}(x) \pmod{r_\mathbb{J}}\) - .
  • -
  • - \(\mathsf{ToScalar^{Orchard}}(x) :=\) - \(\mathsf{LEOS2IP}_{512}(x) \pmod{r_\mathbb{P}}\) - .
  • -
  • - \(\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 13.
  • -
-

The following algorithm standardized in 22 is used:

-
    -
  • - \(\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:

-
    -
  • - \(\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 2 to describe shielded HD paths, using prime marks ( - \('\) - ) to indicate hardened derivation ( - \(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\) - .
  • -
-
-

Specification: Sapling key derivation

-

Sapling extended keys

-

BIP 32 defines a method to derive a number of child keys from a parent key. In order to prevent these from depending solely on the parent key itself, both the private and public keys are extended with a 32-byte chain code. We similarly extend Sapling keys with a chain code here. However, the concepts of "private" and "public" keys in BIP 32 do not map cleanly to Sapling's key components. We take the following approach:

-
    -
  • We derive child Sapling expanded spending keys, rather than Sapling spending keys. This enables us to implement both hardened and non-hardened derivation modes (the latter being incompatible with Sapling spending keys).
  • -
  • 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})\) - , 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 - \((\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

-
    -
  • - \(\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 - \(S\) - 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)\) - .
  • -
  • 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 11: -
      -
    • - \(\mathsf{ask}_m = \mathsf{ToScalar^{Sapling}}(\mathsf{PRF^{expand}}(\mathsf{sk}_m, [\texttt{0x00}]))\) -
    • -
    • - \(\mathsf{nsk}_m = \mathsf{ToScalar^{Sapling}}(\mathsf{PRF^{expand}}(\mathsf{sk}_m, [\texttt{0x01}]))\) -
    • -
    • - \(\mathsf{ovk}_m = \mathsf{truncate}_{32}(\mathsf{PRF^{expand}}(\mathsf{sk}_m, [\texttt{0x02}]))\) - .
    • -
    -
  • -
  • Calculate - \(\mathsf{dk}_m\) - similarly: -
      -
    • - \(\mathsf{dk}_m = \mathsf{truncate}_{32}(\mathsf{PRF^{expand}}(\mathsf{sk}_m, [\texttt{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}\) - .
  • -
-

Note that the master extended key is invalid if - \(\mathsf{ask}_m\) - is - \(0\) - , or if the corresponding - \(\mathsf{ivk}\) - derived as specified in 11 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 - \(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}]\) - \(||\,\mathsf{EncodeExtSKParts}(\mathsf{ask}_{par}, \mathsf{nsk}_{par}, \mathsf{ovk}_{par}, \mathsf{dk}_{par})\) - \(||\,\mathsf{I2LEOSP}_{32}(i))\) - .
    • -
    • If not (normal child): let - \(I = \mathsf{PRF^{expand}}(\mathsf{c}_{par}, [\texttt{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 11.
    • -
    -
  • -
  • Split - \(I\) - into two 32-byte sequences, - \(I_L\) - and - \(I_R\) - .
  • -
  • Let - \(I_\mathsf{ask} = \mathsf{ToScalar^{Sapling}}(\mathsf{PRF^{expand}}(I_L, [\texttt{0x13}]))\) - .
  • -
  • Let - \(I_\mathsf{nsk} = \mathsf{ToScalar^{Sapling}}(\mathsf{PRF^{expand}}(I_L, [\texttt{0x14}]))\) - .
  • -
  • Return: -
      -
    • - \(\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, [\texttt{0x15}]\) - \(||\,\mathsf{ovk}_{par}))\) -
    • -
    • - \(\mathsf{dk}_i = \mathsf{truncate}_{32}(\mathsf{PRF^{expand}}(I_L, [\texttt{0x16}]\) - \(||\,\mathsf{dk}_{par}))\) -
    • -
    • - \(\mathsf{c}_i = I_R\) - .
    • -
    -
  • -
-

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

-
-

Deriving a child extended full viewing key

-

Let - \(\mathcal{G}^\mathsf{Sapling}\) - be as defined in 14 and let - \(\mathcal{H}^\mathsf{Sapling}\) - be as defined in 11.

-

- \(\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}\) - (whether the child is a hardened key). -
      -
    • If so (hardened child): return failure.
    • -
    • If not (normal child): let - \(I = \mathsf{PRF^{expand}}(\mathsf{c}_{par}, [\texttt{0x12}]\) - \(||\,\mathsf{EncodeExtFVKParts}(\mathsf{ak}_{par}, \mathsf{nk}_{par}, \mathsf{ovk}_{par}, \mathsf{dk}_{par})\) - \(||\,\mathsf{I2LEOSP}_{32}(i))\) - .
    • -
    -
  • -
  • Split - \(I\) - into two 32-byte sequences, - \(I_L\) - and - \(I_R\) - .
  • -
  • Let - \(I_\mathsf{ask} = \mathsf{ToScalar^{Sapling}}(\mathsf{PRF^{expand}}(I_L, [\texttt{0x13}]))\) - .
  • -
  • Let - \(I_\mathsf{nsk} = \mathsf{ToScalar^{Sapling}}(\mathsf{PRF^{expand}}(I_L, [\texttt{0x14}]))\) - .
  • -
  • Return: -
      -
    • - \(\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, [\texttt{0x15}]\) - \(||\,\mathsf{ovk}_{par}))\) -
    • -
    • - \(\mathsf{dk}_i = \mathsf{truncate}_{32}(\mathsf{PRF^{expand}}(I_L, [\texttt{0x16}]\) - \(||\,\mathsf{dk}_{par}))\) -
    • -
    • - \(\mathsf{c}_i = I_R\) - .
    • -
    -
  • -
-

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 11 is - \(0\) - .

-
-
-

Sapling internal key derivation

-

The above derivation mechanisms produce external addresses suitable for giving out to senders. We also want to be able to produce another address derived from a given external address, for use by wallets for internal operations such as change and auto-shielding. Unlike BIP 44 that allows deriving a stream of external and internal addresses in the same hierarchical derivation tree 5, for any external full viewing key we only need to be able to derive a single internal full viewing 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.

-

Deriving a Sapling internal spending key

-

Let - \((\mathsf{ask}, \mathsf{nsk}, \mathsf{ovk}, \mathsf{dk})\) - be the external spending key.

-
    -
  • Derive the corresponding - \(\mathsf{ak}\) - and - \(\mathsf{nk}\) - as specified in 11.
  • -
  • 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 - \(\mathsf{ak}\) - is the zero point of Jubjub, or if the corresponding - \(\mathsf{ivk}\) - derived as specified in 11 is - \(0\) - .

-
-

Deriving a Sapling internal full viewing key

-

Let - \(\mathcal{H}^\mathsf{Sapling}\) - be as defined in 11.

-

Let - \((\mathsf{ak}, \mathsf{nk}, \mathsf{ovk}, \mathsf{dk})\) - be the external full viewing key.

-
    -
  • 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 - \(\mathsf{ak}\) - ) as the original, but viewing authority only for internal transfers.

-

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:

-
- -
Diagram of Sapling internal key derivation
-
-

(For simplicity, the proof authorizing key is not shown.)

-

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 8.

-

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 11 is - \(0\) - .

-
-
-

Sapling diversifier derivation

-

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 - \(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 - \(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 - \(d_j\) - , where - \(j\) - is the least nonnegative integer yielding a valid diversifier.

-
-
-

Specification: Hardened-only key derivation

-

The derivation mechanism for Sapling addresses specified above incurs significant complexity to support non-hardened derivation. In the several years since Sapling was deployed, we have seen no use cases for non-hardened derivation appear. With that in mind, we now have a general hardened-only derivation process that retains compatibility with existing derivation path semantics (to enable deriving the same path across multiple contexts).

-

Instantiation

-

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:

-
    -
  • - \(\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.
  • -
  • - \(\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}}\) - .
  • -
-
-

Hardened-only master key generation

-

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.

-

- \(\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})\) - .
  • -
  • 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

-

- \(\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))\) - .
    • -
    • If not (normal child): return failure.
    • -
    -
  • -
  • 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

-

We only support hardened key derivation for Orchard. We instantiate the hardened key generation process with the following constants:

-
    -
  • - \(\mathsf{Orchard.MKGDomain} = \texttt{“ZcashIP32Orchard”}\) -
  • -
  • - \(\mathsf{Orchard.CKDDomain} = \texttt{0x81}\) -
  • -
-

Orchard extended keys

-

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 - \(S\) - be a seed byte sequence of a chosen length, which MUST be at least 32 and at most 252 bytes.

-
    -
  • Return - \(\mathsf{MKGh}^\mathsf{Orchard}(S)\) - as the master extended spending key - \(m_\mathsf{Orchard}\) - .
  • -
-
-

Orchard child key derivation

-

- \(\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)\) -
  • -
-

Note that the resulting child spending key may produce an invalid external FVK, as specified in 12, with small probability. The corresponding internal FVK derived as specified in the next section may also be invalid with small probability.

-
-

Orchard internal key derivation

-

As in the case of Sapling, for a given external address, we want to produce another address for use by wallets for internal operations such as change and auto-shielding. That is, for any external full viewing key we need to be able to derive a single internal full viewing 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 - \(\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 12.

-

Define - \(\mathsf{DeriveInternalFVK^{Orchard}}(\mathsf{ak}, \mathsf{nk}, \mathsf{rivk})\) - as follows:

-
    -
  • 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 - \(\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}})\) - ,

-

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{ivk_{internal}}\) - and - \(\mathsf{ovk_{internal}}\) - fields being derived, as specified in 12 and shown in the following diagram:

-
- -
Diagram of Orchard internal key derivation, also showing derivation from the parent extended spending key
-
-

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 8.

-

Note that the resulting FVK may be invalid, as specified in 12.

-
-

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)\) - :

-
    -
  • 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, [\texttt{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 - \(j\) - yield valid diversifiers.

-

The default diversifier for - \((\mathsf{sk}_i, \mathsf{c}_i)\) - is defined to be - \(d_{i,0}.\) -

-
-
-

Specification: Arbitrary key derivation

-

In some contexts there is a need for deriving arbitrary keys with the same derivation path as existing key material (for example, deriving an arbitrary account-level key), without the need for ecosystem-wide coordination. The following instantiation of the hardened key generation process may be used for this purpose.

-

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:

-
    -
  • - \(\mathsf{Arbitrary.MKGDomain} = \texttt{“ZcashArbitraryKD”}\) -
  • -
  • - \(\mathsf{Arbitrary.CKDDomain} = \texttt{0xAB}\) -
  • -
-

Arbitrary master key generation

-

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:

-

- \(m_\mathsf{Arbitrary} = \mathsf{MKGh}^\mathsf{Arbitrary}([\mathsf{length}(\mathsf{ContextString})]\,||\,\mathsf{ContextString}\,||\,[\mathsf{length}(S)]\,||\,S)\!\) - .

-
-

Arbitrary child key derivation

-

- \(\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)\!\) - .
  • -
-

If the context requires a 64-byte key (for example, to avoid an entropy bottleneck in its particular 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

-

Existing Zcash-supporting HD wallets all use BIP 44 5 to organize their derived keys. In order to more easily mesh with existing user experiences, we broadly follow BIP 44's design here. However, we have altered the design where it makes sense to leverage features of shielded addresses.

-

Key path levels

-

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

-
    -
  • - \(purpose\) - : a constant set to - \(32'\) - (or - \(\texttt{0x80000020}\) - ) following the BIP 43 recommendation. It indicates that the subtree of this node is used according to this specification.
  • -
  • - \(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\) - .
  • -
  • - \(account\) - : numbered from index - \(0\) - in sequentially increasing manner. Defined as in BIP 44 5.
  • -
-

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 using a change address.

-
-

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 \}\) - :

-
    -
  • - \(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 - \(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 - \(address\_index\) - path level as in 5:

-
    -
  • - \(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}\) - , using hardened derivation for - \(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 \}\) - :

-
    -
  • - \(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 - \(2^{88}\) - payment addresses (unlike Sapling, all Orchard diversifiers are valid).

-
-
-

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 - \(\mathit{FVK}\) - (as specified in 18) is given by:

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

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

-

A "Sapling full viewing key tag" is the first 4 bytes of the corresponding Sapling full viewing key fingerprint. It is intended for optimizing performance of key lookups, and MUST NOT be assumed to 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 - \(\mathit{FVK}\) - (as specified in 20) is given by:

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

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

-

An "Orchard full viewing key tag" is the first 4 bytes of the corresponding Orchard full viewing key fingerprint. It is intended for optimizing performance of key lookups, and MUST NOT be assumed to uniquely identify a particular key.

-
-

Seed Fingerprints

-

A "seed fingerprint" for the master seed - \(S\) - of a hierarchical deterministic wallet is given by:

-
    -
  • - \(\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.

-

No corresponding short tag is defined.

-

Note: a previous version of this specification did not have the length byte prefixing the seed. The current specification reflects the implementation in zcashd.

-
-
-

Specification: Key Encodings

-

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})\) - , at depth - \(depth\) - , with parent full viewing key tag - \(parent\_fvk\_tag\) - and child number - \(i\) - , is represented as a byte sequence:

-
    -
  • - \(\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, - \(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.

-
-

Sapling extended full viewing keys

-

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:

-
    -
  • - \(\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, - \(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.

-
-

Orchard extended spending keys

-

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:

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

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.

-

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.

-
-
-

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 - \(\mathsf{BLAKE2b}\text{-}\mathsf{512}\) - personalization - \(\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”}\) - , formerly specified for generation of Sprout address fingerprints;
  • -
  • the - \(\mathsf{PRF^{expand}}\) - prefix - \(\texttt{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.
  • -
-
-

Test Vectors

-

TBC

-
-

Reference Implementation

- -
-

References

- - - - - - - -
1Information 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"
- - - - - - - -
2BIP 32: Hierarchical Deterministic Wallets
- - - - - - - -
3BIP 39: Mnemonic code for generating deterministic keys
- - - - - - - -
4BIP 43: Purpose Field for Deterministic Wallets
- - - - - - - -
5BIP 44: Multi-Account Hierarchy for Deterministic Wallets
- - - - - - - -
6SLIP 44: Registered coin types for BIP-0044
- - - - - - - -
7BIP 173: Base32 address format for native v0-16 witness outputs
- - - - - - - -
8ZIP 316: Unified Addresses and Unified Viewing Keys
- - - - - - - -
9Zcash Protocol Specification, Version 2022.2.19 or later [NU5 proposal]
- - - - - - - -
10Zcash Protocol Specification, Version 2022.2.19. Section 3.12: Mainnet and Testnet
- - - - - - - -
11Zcash Protocol Specification, Version 2022.2.19. Section 4.2.2: Sapling Key Components
- - - - - - - -
12Zcash Protocol Specification, Version 2022.2.19. Section 4.2.3: Orchard Key Components
- - - - - - - -
13Zcash Protocol Specification, Version 2022.2.19. Section 5.4.1.6: DiversifyHash^Sapling and DiversifyHash^Orchard Hash Functions
- - - - - - - -
14Zcash Protocol Specification, Version 2022.2.19. Section 5.4.6.1: Spend Authorization Signature
- - - - - - - -
15Zcash Protocol Specification, Version 2022.2.19. Section 5.4.9.3: Jubjub
- - - - - - - -
16Zcash Protocol Specification, Version 2022.2.19. Section 5.6.2.1: Sprout Payment Addresses
- - - - - - - -
17Zcash Protocol Specification, Version 2022.2.19. Section 5.6.2.3: Sprout Spending Keys
- - - - - - - -
18Zcash Protocol Specification, Version 2022.2.19. Section 5.6.3.3: Sapling Full Viewing Keys
- - - - - - - -
19Zcash Protocol Specification, Version 2022.2.19. Section 5.6.3.4: Sapling Spending Keys
- - - - - - - -
20Zcash Protocol Specification, Version 2022.2.19. Section 5.6.4.4: Orchard Raw Full Viewing Keys
- - - - - - - -
21Zcash Protocol Specification, Version 2022.2.19. Section 5.6.4.5: Orchard Spending Keys
- - - - - - - -
22NIST Special Publication 800-38G — Recommendation for Block Cipher Modes of Operation: Methods for Format-Preserving Encryption
-
-
- - \ No newline at end of file diff --git a/rendered/zip-0068.html b/rendered/zip-0068.html deleted file mode 100644 index 1971b9626..000000000 --- a/rendered/zip-0068.html +++ /dev/null @@ -1,246 +0,0 @@ - - - - ZIP 68: Relative lock-time using consensus-enforced sequence numbers - - - -
-
ZIP: 68
-Title: Relative lock-time using consensus-enforced sequence numbers
-Credits: Mark Friedenbach <mark@friedenbach.org>
-         BtcDrak <btcdrak@gmail.com>
-         Nicolas Dorier <nicolas.dorier@gmail.com>
-         kinoshitajona <kinoshitajona@gmail.com>
-Category: Consensus
-Status: Draft
-Created: 2016-06-06
-

Terminology

-

The key words "MUST" and "MAY" in this document are to be interpreted as described in RFC 2119. 1

-

The "Median Time Past" of a block in this document is to be interpreted as described in 4.

-
-

Abstract

-

This ZIP introduces relative lock-time (RLT) consensus-enforced semantics of the sequence number field, to enable a signed transaction input to remain invalid for a defined period of time after confirmation of its corresponding outpoint.

-
-

Motivation

-

Zcash transactions have a sequence number field for each input, inherited from Bitcoin. The original idea in Bitcoin appears to have been that a transaction in the mempool would be replaced by using the same input with a higher sequence value. Although this was not properly implemented, it assumes miners would prefer higher sequence numbers even if the lower ones were more profitable to mine. However, a miner acting on profit motives alone would break that assumption completely. The change described by this ZIP repurposes the sequence number for new use cases without breaking existing functionality. It also leaves room for future expansion and other use cases.

-

The transaction nLockTime is used to prevent the mining of a transaction until a certain date. nSequence will be repurposed to prevent mining of a transaction until a certain age of the spent output in blocks or timespan. This, among other uses, allows bi-directional payment channels as used in 5 and 3.

-
-

Specification

-

This specification defines the meaning of sequence numbers for transactions in blocks after this proposal has activated.

-

If bit (1 << 31) of the sequence number is set, then no consensus meaning is applied to the sequence number and can be included in any block under all currently possible circumstances.

-

If bit (1 << 31) of the sequence number is not set, then the sequence number is interpreted as an encoded relative lock-time.

-

The sequence number encoding MUST be interpreted as follows:

-

Bit (1 << 22) determines if the relative lock-time is time-based or block based: If the bit is set, the relative lock-time specifies a timespan in units of 32 seconds granularity. The timespan starts from the Median Time Past of the output’s previous block, and ends at the Median Time Past of the previous block. If the bit is not set, the relative lock-time specifies a number of blocks.

-

Note: the 64-second time unit differs from Bitcoin's BIP 68, which uses a 512-second time unit.

-

The flag (1 << 22) is the highest order bit in a 3-byte signed integer for use in Zcash scripts as a 3-byte PUSHDATA with OP_CHECKSEQUENCEVERIFY 3.

-

This specification only interprets 22 bits of the sequence number as relative lock-time, so a mask of 0x003FFFFF MUST be applied to the sequence field to extract the relative lock-time. The 22-bit specification allows for over 8.5 years of relative lock-time.

-
- -
A 32-bit field with 'Disable Flag' at bit (1 << 31), 'Type Flag' at bit (1 << 22), and 'Value' in the low 22 bits.
-
-

For time-based relative lock-time, 64-second granularity was chosen because the block target spacing for Zcash, after activation of the Blossom network upgrade, is 75 seconds. So when using block-based or time-based, roughly the same amount of time can be encoded with the available number of bits. Converting from a sequence number to seconds is performed by multiplying by 64.

-

When the relative lock-time is time-based, it is interpreted as a minimum block-time constraint over the input's age. A relative time-based lock-time of zero indicates an input which can be included in any block. More generally, a relative time-based lock-time n can be included into any block produced 64 * n seconds after the mining date of the output it is spending, or any block thereafter. The mining date of the output is equal to the Median Time Past of the previous block that mined it.

-

The block produced time is equal to the Median Time Past of its previous block.

-

When the relative lock-time is block-based, it is interpreted as a minimum block-height constraint over the input's age. A relative block-based lock-time of zero indicates an input that can be included in any block. More generally, a relative block lock-time n MAY be included n blocks after the mining date of the output it is spending, or any block thereafter.

-

The new rules are not applied to the nSequence field of the input of the coinbase transaction.

-
-

Reference Implementation

- -
-

Acknowledgments

-

This ZIP is based on BIP 68, authored by Mark Friedenbach, BtcDrak, Nicolas Dorier, and kinoshitajona.

-

Credit goes to Gregory Maxwell for providing a succinct and clear description of the behavior of this change, which became the basis of the BIP text.

-
-

Deployment

-

At the time of writing it has not been decided which network upgrade (if any) will implement this proposal.

-

This ZIP is designed to be deployed simultaneously with 3 and 4.

-
-

Compatibility

-

The only use of sequence numbers by the zcashd reference client software is to disable checking the nLockTime constraints in a transaction. The semantics of that application are preserved by this ZIP.

-

As can be seen from the specification section, a number of bits are undefined by this ZIP to allow for other use cases by setting bit (1 << 31) as the remaining 31 bits have no meaning under this ZIP. Additionally, bits (1 << 23) through (1 << 30) inclusive have no meaning at all when bit (1 << 31) is unset.

-

Unlike BIP 68 in Bitcoin, all of the low 22 bits are used for the value. This reflects the fact that blocks are more frequent (75 seconds instead of 600 seconds), and so more bits are needed to obtain approximately the same range of time.

-

The most efficient way to calculate sequence number from relative lock-time is with bit masks and shifts:

- -
-

References

- - - - - - - -
1Key words for use in RFCs to Indicate Requirement Levels
- - - - - - - -
2Bitcoin mailing list discussion
- - - - - - - -
3ZIP 112: CHECKSEQUENCEVERIFY
- - - - - - - -
4ZIP 113: Median Time Past as endpoint for lock-time calculations
- - - - - - - -
5Reaching The Ground With Lightning (draft 0.2)
-
-
- - \ No newline at end of file diff --git a/rendered/zip-0076.html b/rendered/zip-0076.html deleted file mode 100644 index 627643358..000000000 --- a/rendered/zip-0076.html +++ /dev/null @@ -1,18 +0,0 @@ - - - - ZIP 76: Transaction Signature Validation before Overwinter - - - -
-
ZIP: 76
-Title: Transaction Signature Validation before Overwinter
-Owners: Jack Grigg <str4d@electriccoin.co>
-        Daira-Emma Hopwood <daira-emma@electriccoin.co>
-Status: Reserved
-Category: Consensus
-Discussions-To: <https://github.com/zcash/zips/issues/130>
-
- - \ No newline at end of file diff --git a/rendered/zip-0112.html b/rendered/zip-0112.html deleted file mode 100644 index 9203b6ff1..000000000 --- a/rendered/zip-0112.html +++ /dev/null @@ -1,309 +0,0 @@ - - - - ZIP 112: CHECKSEQUENCEVERIFY - - - -
-
ZIP: 112
-Title: CHECKSEQUENCEVERIFY
-Author: Daira Hopwood <daira@electriccoin.co>
-Credits: BtcDrak <btcdrak@gmail.com>
-         Mark Friedenbach <mark@friedenbach.org>
-         Eric Lombrozo <elombrozo@gmail.com>
-Category: Consensus
-Status: Draft
-Created: 2019-06-06
-License: MIT
-

Terminology

-

The key word "MUST" in this document is to be interpreted as described in RFC 2119. 1

-
-

Abstract

-

This ZIP describes a new opcode (CHECKSEQUENCEVERIFY) for the Zcash scripting system, that in combination with ZIP 68 allows execution pathways of a script to be restricted based on the age of the output being spent.

-
-

Motivation

-

ZIP 68 repurposes the transaction nSequence field meaning by giving sequence numbers new consensus-enforced semantics as a relative lock-time. However, there is no way to build Zcash scripts to make decisions based on this field.

-

By making the nSequence field accessible to script, it becomes possible to construct code pathways that only become accessible some minimum time after proof-of-publication. This enables a wide variety of applications in phased protocols such as escrow, payment channels, or bidirectional pegs.

-
-

Specification

-

CHECKSEQUENCEVERIFY redefines the existing NOP3 opcode. When executed, if any of the following conditions are true, the script interpreter MUST terminate with an error:

-
    -
  • the stack is empty; or
  • -
  • the top item on the stack is less than 0; or
  • -
  • the top item on the stack has the disable flag (1 << 31) unset; and any of the following hold: -
      -
    • the transaction version is less than 2; or
    • -
    • the transaction input sequence number disable flag (1 << 31) is set; or
    • -
    • the relative lock-time type is not the same; or
    • -
    • the top stack item is greater than the transaction input sequence (when masked according to 4;
    • -
    -
  • -
-

Otherwise, script execution MUST continue as if a NOP had been executed.

-

ZIP 68 prevents a non-final transaction from being selected for inclusion in a block until the corresponding input has reached the specified age, as measured in block-height or block-time. By comparing the argument to CHECKSEQUENCEVERIFY against the nSequence field, we indirectly verify a desired minimum age of the the output being spent; until that relative age has been reached any script execution pathway including the CHECKSEQUENCEVERIFY will fail to validate, causing the transaction not to be selected for inclusion in a block.

-
-

Use cases

-

Contracts With Expiration Deadlines

-

Escrow with Timeout

-

An escrow that times out automatically 30 days after being funded can be established in the following way. Alice, Bob and Escrow create a 2-of-3 address with the following redeem script:

-
IF
-    2 <Alice's pubkey> <Bob's pubkey> <Escrow's pubkey> 3 CHECKMULTISIG
-ELSE
-    "30d" CHECKSEQUENCEVERIFY DROP
-    <Alice's pubkey> CHECKSIG
-ENDIF
-

At any time funds can be spent using signatures from any two of Alice, Bob or the Escrow.

-

After 30 days Alice can sign alone.

-

The clock does not start ticking until the payment to the escrow address confirms.

-
-
-

Retroactive Invalidation

-

In many instances, we would like to create contracts that can be revoked in case of some future event. However, given the immutable nature of the block chain, it is practically impossible to retroactively invalidate a previous commitment that has already confirmed. The only mechanism we really have for retroactive invalidation is block chain reorganization which, for fundamental security reasons, is designed to be very hard and very expensive to do.

-

Despite this limitation, we do have a way to provide something functionally similar to retroactive invalidation while preserving irreversibility of past commitments using CHECKSEQUENCEVERIFY. By constructing scripts with multiple branches of execution where one or more of the branches are delayed we provide a time window in which someone can supply an invalidation condition that allows the output to be spent, effectively invalidating the would-be delayed branch and potentially discouraging another party from broadcasting the transaction in the first place. If the invalidation condition does not occur before the timeout, the delayed branch becomes spendable, honoring the original contract.

-

Some more specific applications of this idea:

-

Hash Time-Locked Contracts

-

Hash Time-Locked Contracts (HTLCs) provide a general mechanism for off-chain contract negotiation. An execution pathway can be made to require knowledge of a secret (a hash preimage) that can be presented within an invalidation time window. By sharing the secret it is possible to guarantee to the counterparty that the transaction will never be broadcast since this would allow the counterparty to claim the output immediately while one would have to wait for the time window to pass. If the secret has not been shared, the counterparty will be unable to use the instant pathway and the delayed pathway must be used instead.

-
-

Bidirectional Payment Channels

-

Scriptable relative locktime provides a predictable amount of time to respond in the event a counterparty broadcasts a revoked transaction: Absolute locktime necessitates closing the channel and reopening it when getting close to the timeout, whereas with relative locktime, the clock starts ticking the moment the transaction confirms in a block. It also provides a means to know exactly how long to wait (in number of blocks) before funds can be pulled out of the channel in the event of a noncooperative counterparty.

-
-

Lightning Network

-

The lightning network protocol 6 extends the bidirectional payment channel idea to allow for payments to be routed over multiple bidirectional payment channel hops.

-

These channels are based on an anchor transaction that requires a 2-of-2 multisig from Alice and Bob, and a series of revocable commitment transactions that spend the anchor transaction. The commitment transaction splits the funds from the anchor between Alice and Bob and the latest commitment transaction may be published by either party at any time, finalising the channel.

-

Ideally then, a revoked commitment transaction would never be able to be successfully spent; and the latest commitment transaction would be able to be spent very quickly.

-

To allow a commitment transaction to be effectively revoked, Alice and Bob have slightly different versions of the latest commitment transaction. In Alice's version, any outputs in the commitment transaction that pay Alice also include a forced delay, and an alternative branch that allows Bob to spend the output if he knows that transaction's revocation code. In Bob's version, payments to Bob are similarly encumbered. When Alice and Bob negotiate new balances and new commitment transactions, they also reveal the old revocation code, thus committing to not relaying the old transaction.

-

A simple output, paying to Alice might then look like:

-
HASH160 <revokehash> EQUAL
-IF
-    <Bob's pubkey>
-ELSE
-    "24h" CHECKSEQUENCEVERIFY DROP
-    <Alice's pubkey>
-ENDIF
-CHECKSIG
-

This allows Alice to publish the latest commitment transaction at any time and spend the funds after 24 hours, but also ensures that if Alice relays a revoked transaction, that Bob has 24 hours to claim the funds.

-

With CHECKLOCKTIMEVERIFY, this would look like:

-
HASH160 <revokehash> EQUAL
-IF
-    <Bob's pubkey>
-ELSE
-    "2015/12/15" CHECKLOCKTIMEVERIFY DROP
-    <Alice's pubkey>
-ENDIF
-CHECKSIG
-

This form of transaction would mean that if the anchor is unspent on 2015/12/16, Alice can use this commitment even if it has been revoked, simply by spending it immediately, giving no time for Bob to claim it.

-

This means that the channel has a deadline that cannot be pushed back without hitting the blockchain; and also that funds may not be available until the deadline is hit. CHECKSEQUENCEVERIFY allows you to avoid making such a tradeoff.

-

Hashed Time-Lock Contracts (HTLCs) make this slightly more complicated, since in principle they may pay either Alice or Bob, depending on whether Alice discovers a secret R, or a timeout is reached, but the same principle applies -- the branch paying Alice in Alice's commitment transaction gets a delay, and the entire output can be claimed by the other party if the revocation secret is known. With CHECKSEQUENCEVERIFY, a HTLC payable to Alice might look like the following in Alice's commitment transaction:

-
HASH160 DUP <R-HASH> EQUAL
-IF
-    "24h" CHECKSEQUENCEVERIFY
-    2DROP
-    <Alice's pubkey>
-ELSE
-    <Commit-Revocation-Hash> EQUAL
-    NOTIF
-        "2015/10/20 10:33" CHECKLOCKTIMEVERIFY DROP
-    ENDIF
-    <Bob's pubkey>
-ENDIF
-CHECKSIG
-

and correspondingly in Bob's commitment transaction:

-
HASH160 DUP <R-HASH> EQUAL
-SWAP <Commit-Revocation-Hash> EQUAL ADD
-IF
-    <Alice's pubkey>
-ELSE
-    "2015/10/20 10:33" CHECKLOCKTIMEVERIFY
-    "24h" CHECKSEQUENCEVERIFY
-    2DROP
-    <Bob's pubkey>
-ENDIF
-CHECKSIG
-

Note that both CHECKSEQUENCEVERIFY and CHECKLOCKTIMEVERIFY are used in the final branch above to ensure Bob cannot spend the output until after both the timeout is complete and Alice has had time to reveal the revocation secret.

-

See also the 'Deployable Lightning' paper 5.

-
-
-

2-Way Pegged Sidechains

-

The 2-way pegged sidechain requires a new REORGPROOFVERIFY opcode, the semantics of which are outside the scope of this ZIP. CHECKSEQUENCEVERIFY is used to make sure that sufficient time has passed since the return peg was posted to publish a reorg proof:

-
IF
-    lockTxHeight <lockTxHash> nlocktxOut [<workAmount>] reorgBounty Hash160(<...>) <genesisHash> REORGPROOFVERIFY
-ELSE
-    withdrawLockTime CHECKSEQUENCEVERIFY DROP HASH160 p2shWithdrawDest EQUAL
-ENDIF
-
-
-

Reference Implementation

- -
-

Deployment

-

At the time of writing it has not been decided which network upgrade (if any) will implement this proposal.

-

This ZIP must be deployed simultaneously with ZIP 68 4.

-
-

Acknowledgements

-

This ZIP is closely based on BIP 112, authored by BtcDrak.

-

Mark Friedenbach invented the application of sequence numbers to achieve relative lock-time, and wrote the reference implementation of CHECKSEQUENCEVERIFY for Bitcoin.

-

The Bitcoin reference implementation and BIP 112 was based heavily on work done by Peter Todd for the closely related BIP 65. Eric Lombrozo and Anthony Towns contributed example use cases.

-
-

References

- - - - - - - -
1Key words for use in RFCs to Indicate Requirement Levels
- - - - - - - -
2Zcash Protocol Specification, Version 2019.0.1 or later [Overwinter+Sapling]
- - - - - - - -
3BIP 65: OP_CHECKLOCKTIMEVERIFY
- - - - - - - -
4ZIP 68: Relative lock-time through consensus-enforced sequence numbers
- - - - - - - -
5Deployable Lightning
- - - - - - - -
6Lightning Network paper
- - - - - - - -
7HTLCs using OP_CHECKSEQUENCEVERIFY/OP_LOCKTIMEVERIFY and revocation hashes
- - - - - - - -
8Scaling Bitcoin to Billions of Transactions Per Day
- - - - - - - -
9Jeremy Spilman, Micropayment Channels
-
-
- - \ No newline at end of file diff --git a/rendered/zip-0113.html b/rendered/zip-0113.html deleted file mode 100644 index 5a6b70156..000000000 --- a/rendered/zip-0113.html +++ /dev/null @@ -1,97 +0,0 @@ - - - - ZIP 113: Median Time Past as endpoint for lock-time calculations - - - -
-
ZIP: 113
-Title: Median Time Past as endpoint for lock-time calculations
-Author: Daira Hopwood <daira@electriccoin.co>
-Credits: Thomas Kerin <me@thomaskerin.io>
-         Mark Friedenbach <mark@friedenbach.org>
-         Gregory Maxwell
-Category: Consensus
-Status: Draft
-Created: 2019-06-07
-License: MIT
-

Terminology

-

The key words "MUST" and "MAY" in this document are to be interpreted as described in RFC 2119. 1

-
-

Abstract

-

This ZIP is a proposal to redefine the semantics used in determining a time-locked transaction's eligibility for inclusion in a block. The median of the last PoWMedianBlockSpan (11) blocks is used instead of the block's timestamp, ensuring that it increases monotonically with each block.

-
-

Motivation

-

At present, transactions are excluded from inclusion in a block if the present time or block height is less than or equal to that specified in the locktime. Since the consensus rules do not mandate strict ordering of block timestamps, this has the unfortunate outcome of creating a perverse incentive for miners to lie about the time of their blocks in order to collect more fees by including transactions that by wall clock determination have not yet matured.

-

This ZIP proposes comparing the locktime against the median of the past PoWMedianBlockSpan blocks' timestamps, rather than the timestamp of the block including the transaction. Existing consensus rules guarantee this value to monotonically advance, thereby removing the capability for miners to claim more transaction fees by lying about the timestamps of their block.

-

This proposal seeks to ensure reliable behaviour in locktime calculations as required by 3 (CHECKLOCKTIMEVERIFY) and matching the behavior of 5 (CHECKSEQUENCEVERIFY). This also matches the use of Median Time Past in difficulty adjustment as specified in section 7.6.3 of 2.

-
-

Specification

-

Let PoWMedianBlockSpan be as defined in 2 section 5.3, and let the median function be as defined in 2 section 7.6.3.

-

The Median Time Past of a block is specified as the median of the timestamps of the prior PoWMedianBlockSpan blocks, as calculated by MedianTime(height) in 2 section 7.6.3.

-

The values for transaction locktime remain unchanged. The difference is only in the calculation determining whether a transaction can be included. After activation of this ZIP, lock-time constraints of a transaction MUST be checked according to the Median Time Past of the transaction's block.

-

[FIXME make this a proper specification, independent of the zcashd implementation.]

-

Lock-time constraints are checked by the consensus method IsFinalTx(). This method takes the block time as one parameter. This ZIP proposes that after activation calls to IsFinalTx() within consensus code use the return value of GetMedianTimePast(pindexPrev) instead.

-

The new rule applies to all transactions, including the coinbase transaction.

-
-

Reference Implementation

-

This will be based on Bitcoin PR 6566.

-
-

Acknowledgements

-

This ZIP is based on BIP 113, authored by Thomas Kerin and Mark Friedenbach.

-

Mark Friedenbach designed and authored the reference implementation for Bitcoin.

-

Gregory Maxwell came up with the original idea, in #bitcoin-wizards on 2013-07-16 and 2013-07-17.

-
-

Deployment

-

At the time of writing it has not been decided which network upgrade (if any) will implement this proposal.

-

This ZIP is designed to be deployed simultaneously with 4 and 5.

-
-

Compatibility

-

At the post-Blossom block target spacing of 75 seconds, transactions generated using time-based lock-time will take approximately 7.5 minutes longer to confirm than would be expected under the old rules. This is not known to introduce any compatibility concerns with existing protocols. This delay is less than in Bitcoin due to the faster block target spacing in Zcash.

-
-

References

- - - - - - - -
1Key words for use in RFCs to Indicate Requirement Levels
- - - - - - - -
2Zcash Protocol Specification, Version 2019.0.1 or later [Overwinter+Sapling+Blossom]
- - - - - - - -
3BIP 65: OP_CHECKLOCKTIMEVERIFY
- - - - - - - -
4ZIP 68: Consensus-enforced transaction replacement signaled via sequence numbers
- - - - - - - -
5ZIP 112: CHECKSEQUENCEVERIFY
-
-
- - \ No newline at end of file diff --git a/rendered/zip-0143.html b/rendered/zip-0143.html deleted file mode 100644 index 5adb479d7..000000000 --- a/rendered/zip-0143.html +++ /dev/null @@ -1,480 +0,0 @@ - - - - ZIP 143: Transaction Signature Validation for Overwinter - - - -
-
ZIP: 143
-Title: Transaction Signature Validation for Overwinter
-Owners: Jack Grigg <str4d@electriccoin.co>
-        Daira-Emma Hopwood <daira-emma@electriccoin.co>
-Credits: Johnson Lau
-         Pieter Wuille
-         Bitcoin-ABC
-Status: Final
-Category: Consensus
-Created: 2017-12-27
-License: MIT
-

Terminology

-

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

-

The terms "consensus branch", "epoch", and "network upgrade" in this document are to be interpreted as described in ZIP 200. 10

-

The term "Overwinter" in this document is to be interpreted as described in ZIP 201. 11

-
-

Abstract

-

This proposal defines a new transaction digest algorithm for signature validation from the Overwinter network upgrade, in order to minimize redundant data hashing in validation, and to cover the input value by the signature.

-
-

Motivation

-

There are 4 ECDSA signature validation operations in the original Zcash script system: CHECKSIG, CHECKSIGVERIFY, CHECKMULTISIG, CHECKMULTISIGVERIFY ("sigops"). According to the sighash type (ALL, NONE, or SINGLE, possibly modified by ANYONECANPAY), a transaction digest is generated with a double SHA256 of a serialized subset of the transaction, and the signature is validated against this digest with a given public key. The detailed procedure is described in a Bitcoin Wiki article. 3 The transaction digest is additionally used for the JoinSplit signature (solely with sighash type ALL). 2

-

Unfortunately, there are at least 2 weaknesses in the original SignatureHash transaction digest algorithm:

-
    -
  • For the validation of each signature, the amount of data hashing is proportional to the size of the transaction. Therefore, data hashing grows in O(n2) as the number of sigops in a transaction increases. While a 1 MB block would normally take 2 seconds to validate with an average computer in 2015, a 1MB transaction with 5569 sigops may take 25 seconds to validate. This could be fixed by optimizing the digest algorithm by introducing some reusable "midstate", so the time complexity becomes O(n). 4
  • -
  • The algorithm does not involve the value being spent by the input. This is usually not a problem for online network nodes as they could request for the specified transaction to acquire the output value. For an offline transaction signing device ("cold wallet"), however, the lack of knowledge of input amount makes it impossible to calculate the exact amount being spent and the transaction fee. To cope with this problem a cold wallet must also acquire the full transaction being spent, which could be a big obstacle in the implementation of a lightweight, air-gapped wallet. By including the input value of part of the transaction digest, a cold wallet may safely sign a transaction by learning the value from an untrusted source. In the case that a wrong value is provided and signed, the signature would be invalid and no funds would be lost. 5
  • -
-

Deploying the aforementioned fixes in the original script system is not a simple task.

-
-

Specification

-

A new transaction digest algorithm is defined:

-
BLAKE2b-256 hash of the serialization of:
-  1. header of the transaction (4-byte little endian)
-  2. nVersionGroupId of the transaction (4-byte little endian)
-  3. hashPrevouts (32-byte hash)
-  4. hashSequence (32-byte hash)
-  5. hashOutputs (32-byte hash)
-  6. hashJoinSplits (32-byte hash)
-  7. nLockTime of the transaction (4-byte little endian)
-  8. nExpiryHeight of the transaction (4-byte little endian)
-  9. sighash type of the signature (4-byte little endian)
- 10. If we are computing a transaction digest for a transparent input (i.e. this is not a JoinSplit
-     signature hash):
-     a. outpoint (32-byte hash + 4-byte little endian)
-     b. scriptCode of the input (serialized as scripts inside CTxOuts)
-     c. value of the output spent by this input (8-byte little endian)
-     d. nSequence of the input (4-byte little endian)
-

The new algorithm is based on the Bitcoin transaction digest algorithm defined in BIP 143, 6 with replay protection inspired by BUIP-HF v1.2. 7

-

The new algorithm MUST be used for signatures created over the Overwinter transaction format. 12 Combined with the new consensus rule that v1 and v2 transaction formats will be invalid from the Overwinter upgrade, 12 this effectively means that all transaction signatures from the Overwinter activation height will use the new algorithm. 11

-

The BLAKE2b-256 personalization field 8 is set to:

-
"ZcashSigHash" || CONSENSUS_BRANCH_ID
-

CONSENSUS_BRANCH_ID is the 4-byte little-endian encoding of the consensus branch ID for the epoch of the block containing the transaction. 10 Domain separation of the signature hash across parallel consensus branches provides replay protection: transactions targeted for one consensus branch will have invalid signatures on other consensus branches.

-

Transaction creators MUST specify the epoch they want their transaction to be mined in. Across a network upgrade, this means that if a transaction is not mined before the activation height, it will never be mined.

-

Semantics of the original sighash types remain unchanged, except the following:

-
    -
  1. The serialization format is changed;
  2. -
  3. All sighash types commit to the amount being spent by the signed input;
  4. -
  5. SINGLE does not commit to the input index. When ANYONECANPAY is not set, the semantics are unchanged since hashPrevouts and outpoint together implictly commit to the input index. When SINGLE is used with ANYONECANPAY, omission of the index commitment allows permutation of the input-output pairs, as long as each pair is located at an equivalent index.
  6. -
-

Field definitions

-

The items 7, 9, 10a, 10d have the same meaning as the original algorithm from Bitcoin. 3

- -

2: nVersionGroupId

-

Provides domain separation of nVersion. It is only defined if fOverwintered is set, which means that it is always defined for transactions that use this algorithm. 12

-
-

3: hashPrevouts

-
    -
  • If the ANYONECANPAY flag is not set, hashPrevouts is the BLAKE2b-256 hash of the serialization of all input outpoints; -
      -
    • The BLAKE2b-256 personalization field is set to ZcashPrevoutHash.
    • -
    -
  • -
  • Otherwise, hashPrevouts is a uint256 of 0x0000......0000.
  • -
-
-

4: hashSequence

-
    -
  • If none of the ANYONECANPAY, SINGLE, NONE sighash type is set, hashSequence is the BLAKE2b-256 hash of the serialization of nSequence of all inputs; -
      -
    • The BLAKE2b-256 personalization field is set to ZcashSequencHash.
    • -
    -
  • -
  • Otherwise, hashSequence is a uint256 of 0x0000......0000.
  • -
-

Note: the encoding of the sighash type is masked with 0x1F when checking whether or not the SINGLE and NONE flags are set.

-
-

5: hashOutputs

-
    -
  • If the sighash type is neither SINGLE nor NONE, hashOutputs is the BLAKE2b-256 hash of the serialization of all output amount (8-byte little endian) with scriptPubKey (serialized as scripts inside CTxOuts);
  • -
  • If sighash type is SINGLE and the input index is smaller than the number of outputs, hashOutputs is the BLAKE2b-256 hash of the output (serialized as above) with the same index as the input; -
      -
    • The BLAKE2b-256 personalization field is set to ZcashOutputsHash in both cases above.
    • -
    -
  • -
  • Otherwise, hashOutputs is a uint256 of 0x0000......0000. 9
  • -
-

Note: the encoding of the sighash type is masked with 0x1F when checking whether or not the SINGLE and NONE flags are set.

-
-

6: hashJoinSplits

-
    -
  • If vjoinsplits is non-empty, hashJoinSplits is the BLAKE2b-256 hash of the serialization of all JoinSplits (in their canonical transaction serialization format) concatenated with the joinSplitPubKey; -
      -
    • The BLAKE2b-256 personalization field is set to ZcashJSplitsHash.
    • -
    • Note that while signatures are omitted, the JoinSplit proofs are included in the signature hash, as with v1 and v2 transactions.
    • -
    -
  • -
  • Otherwise, hashJoinSplits is a uint256 of 0x0000......0000.
  • -
-
-

8: nExpiryHeight

-

The block height after which the transaction becomes unilaterally invalid, and can never be mined. 13

-
-

10b: scriptCode

-

The script being currently executed: redeemScript for P2SH, or scriptPubKey in the general case. This is the same script as serialized in the Sprout transaction digest algorithm.

-
-

10c: value

-

An 8-byte little-endian value of the amount, in zatoshi, spent in this input.

-
-
-

Notes

-

The hashPrevouts, hashSequence, hashOutputs, and hashJoinSplits calculated in an earlier validation can be reused in other inputs of the same transaction, so that the time complexity of the whole hashing process reduces from O(n2) to O(n).

-

Refer to the reference implementation, reproduced below, for the precise algorithm:

-
const unsigned char ZCASH_PREVOUTS_HASH_PERSONALIZATION[16] =
-    {'Z','c','a','s','h','P','r','e','v','o','u','t','H','a','s','h'};
-const unsigned char ZCASH_SEQUENCE_HASH_PERSONALIZATION[16] =
-    {'Z','c','a','s','h','S','e','q','u','e','n','c','H','a','s','h'};
-const unsigned char ZCASH_OUTPUTS_HASH_PERSONALIZATION[16] =
-    {'Z','c','a','s','h','O','u','t','p','u','t','s','H','a','s','h'};
-const unsigned char ZCASH_JOINSPLITS_HASH_PERSONALIZATION[16] =
-    {'Z','c','a','s','h','J','S','p','l','i','t','s','H','a','s','h'};
-
-// The default values are zeroes
-uint256 hashPrevouts;
-uint256 hashSequence;
-uint256 hashOutputs;
-uint256 hashJoinSplits;
-
-if (!(nHashType & SIGHASH_ANYONECANPAY)) {
-    CBLAKE2bWriter ss(SER_GETHASH, 0, ZCASH_PREVOUTS_HASH_PERSONALIZATION);
-    for (unsigned int n = 0; n < txTo.vin.size(); n++) {
-        ss << txTo.vin[n].prevout;
-    }
-    hashPrevouts = ss.GetHash();
-}
-
-if (!(nHashType & SIGHASH_ANYONECANPAY) && (nHashType & 0x1f) != SIGHASH_SINGLE && (nHashType & 0x1f) != SIGHASH_NONE) {
-    CBLAKE2bWriter ss(SER_GETHASH, 0, ZCASH_SEQUENCE_HASH_PERSONALIZATION);
-    for (unsigned int n = 0; n < txTo.vin.size(); n++) {
-        ss << txTo.vin[n].nSequence;
-    }
-    hashSequence = ss.GetHash();
-}
-
-if ((nHashType & 0x1f) != SIGHASH_SINGLE && (nHashType & 0x1f) != SIGHASH_NONE) {
-    CBLAKE2bWriter ss(SER_GETHASH, 0, ZCASH_OUTPUTS_HASH_PERSONALIZATION);
-    for (unsigned int n = 0; n < txTo.vout.size(); n++) {
-        ss << txTo.vout[n];
-    }
-    hashOutputs = ss.GetHash();
-} else if ((nHashType & 0x1f) == SIGHASH_SINGLE && nIn < txTo.vout.size()) {
-    CBLAKE2bWriter ss(SER_GETHASH, 0, ZCASH_OUTPUTS_HASH_PERSONALIZATION);
-    ss << txTo.vout[nIn];
-    hashOutputs = ss.GetHash();
-}
-
-if (!txTo.vjoinsplit.empty()) {
-    CBLAKE2bWriter ss(SER_GETHASH, 0, ZCASH_JOINSPLITS_HASH_PERSONALIZATION);
-    for (unsigned int n = 0; n < txTo.vjoinsplit.size(); n++) {
-        ss << txTo.vjoinsplit[n];
-    }
-    ss << txTo.joinSplitPubKey;
-    hashJoinSplits = ss.GetHash();
-}
-
-uint32_t leConsensusBranchId = htole32(consensusBranchId);
-unsigned char personalization[16] = {};
-memcpy(personalization, "ZcashSigHash", 12);
-memcpy(personalization+12, &leConsensusBranchId, 4);
-
-CBLAKE2bWriter ss(SER_GETHASH, 0, personalization);
-// fOverwintered and nVersion
-ss << txTo.GetHeader();
-// Version group ID
-ss << txTo.nVersionGroupId;
-// Input prevouts/nSequence (none/all, depending on flags)
-ss << hashPrevouts;
-ss << hashSequence;
-// Outputs (none/one/all, depending on flags)
-ss << hashOutputs;
-// JoinSplits
-ss << hashJoinSplits;
-// Locktime
-ss << txTo.nLockTime;
-// Expiry height
-ss << txTo.nExpiryHeight;
-// Sighash type
-ss << nHashType;
-
-if (nIn != NOT_AN_INPUT) {
-    // The input being signed (replacing the scriptSig with scriptCode + amount)
-    // The prevout may already be contained in hashPrevout, and the nSequence
-    // may already be contained in hashSequence.
-    ss << txTo.vin[nIn].prevout;
-    ss << static_cast<const CScriptBase&>(scriptCode);
-    ss << amount;
-    ss << txTo.vin[nIn].nSequence;
-}
-
-return ss.GetHash();
-
-
-

Example

-

To ensure consistency in consensus-critical behaviour, developers should test their implementations against the ZIP 143 test vectors 14. The first two test vectors are broken out below for clarity. Note that 32-byte values below are exactly as the hash function returns, and are not reversed. Further examples can be found in the SignatureHash test data 15.

-

The test vectors below should be verified with the Overwinter consensus branch ID (0x5ba81b19) 11.

-

Test vector 1

-

Raw transaction:

-
030000807082c4030002e7719811893e0000095200ac6551ac636565b2835a0805750200025151481cdd86b3cc431800
-
-header:          03000080
-nVersionGroupId: 7082c403
-vin:             00
-vout:            02 e7719811893e0000 095200ac6551ac636565
-                    b2835a0805750200 025151
-nLockTime:       481cdd86
-nExpiryHeight:   b3cc4318
-vJoinSplits:     00
-

Transaction digest with nIn = NOT_AN_INPUT and nHashType = 1 (SIGHASH_ALL):

-
hashPrevouts:
-  BLAKE2b-256('ZcashPrevoutHash', b'')
-= d53a633bbecf82fe9e9484d8a0e727c73bb9e68c96e72dec30144f6a84afa136
-
-hashSequence:
-  BLAKE2b-256('ZcashSequencHash', b'')
-= a5f25f01959361ee6eb56a7401210ee268226f6ce764a4f10b7f29e54db37272
-
-hashOutputs:
-  BLAKE2b-256('ZcashOutputsHash', e7719811893e0000095200ac6551ac636565b2835a0805750200025151)
-= ab6f7f6c5ad6b56357b5f37e16981723db6c32411753e28c175e15589172194a
-
-Preimage:
-030000807082c403d53a633bbecf82fe9e9484d8a0e727c73bb9e68c96e72dec30144f6a84afa136a5f25f01959361ee6eb56a7401210ee268226f6ce764a4f10b7f29e54db37272ab6f7f6c5ad6b56357b5f37e16981723db6c32411753e28c175e15589172194a0000000000000000000000000000000000000000000000000000000000000000481cdd86b3cc431801000000
-
-  header:          03000080
-  nVersionGroupId: 7082c403
-  hashPrevouts:    d53a633bbecf82fe9e9484d8a0e727c73bb9e68c96e72dec30144f6a84afa136
-  hashSequence:    a5f25f01959361ee6eb56a7401210ee268226f6ce764a4f10b7f29e54db37272
-  hashOutputs:     ab6f7f6c5ad6b56357b5f37e16981723db6c32411753e28c175e15589172194a
-  hashJoinSplits:  0000000000000000000000000000000000000000000000000000000000000000
-  nLockTime:       481cdd86
-  nExpiryHeight:   b3cc4318
-  nHashType:       01000000
-
-sighash: a1f1a4e5cd9bd522322d661edd2af1bf2a7019cfab94ece18f4ba935b0a19073
-
-

Test vector 2

-

Raw transaction:

-
030000807082c403024201cfb1cd8dbf69b8250c18ef41294ca97993db546c1fe01f7e9c8e36d6a5e29d4e30a703ac6a0098421c69378af1e40f64e125946f62c2fa7b2fecbcb64b6968912a6381ce3dc166d56a1d62f5a8d7056363635353e8c7203d02d2da86387ae60100080063656a63ac5200a7622997f4ff0400075151005353656597b0e4e4c705fc05020000000000000000000000000000000076495c222f7fba1e31defa3d5a57efc2e1e9b01a035587d5fb1a38e01d94903d3c3e0ad3360c1d3710acd20b183e31d49f25c9a138f49b1a537edcf04be34a9851a7af9db6990ed83dd64af3597c04323ea51b0052ad8084a8b9da948d320dadd64f5431e61ddf658d24ae67c22c8d1309131fc00fe7f235734276d38d47f1e191e00c7a1d48af046827591e9733a97fa6b679f3dc601d008285edcbdae69ce8fc1be4aac00ff2711ebd931de518856878f73476f21a482ec9378365c8f7393c94e2885315eb4671098b79535e790fe53e29fef2b3766697ac32b4f473f468a008e72389fc03880d780cb07fcfaabe3f1a84b27db59a4a153d882d2b2103596555ed9494c6ac893c49723833ec8926c1039586a7afcf4a0d9c731e985d99589c03b838e8aaf745533ed9e8ae3a1cd074a51a20da8aba18d1dbebbc862ded42435e02476930d069896cff30eb414f727b89e001afa2fb8dc3436d75a4a6f26572504b0b2232ecb9f0c02411e52596bc5e90457e745939ffedbd12863ce71a02af117d417adb3d15cc54dcb1fce467500c6b8fb86b12b56da9c382857deecc40a98d5f2903395ee4762dd21afdbb5d47fa9a6dd984d567db2857b927b7fae2db587105415d0242789d38f50b8dbcc129cab3d17d19f3355bcf73cecb8cb8a5da01307152f13902a270572670dc82d39026c6cb4cd4b0f7f5aa2a4f5a5341ec5dd715406f2fdd2a02733f5f641c8c21862a1bafce2609d9eecfa158cfb5cd79f88008e315dc7d8388036c1782fd2795d18a763624c25fa959cc97489ce75745824b77868c53239cfbdf73caec65604037314faaceb56218c6bd30f8374ac13386793f21a9fb80ad03bc0cda4a44946c00e1b1a1df0e5b87b5bece477a709649e950060591394812951e1fe3895b8cc3d14d2cf6556df6ed4b4ddd3d9a69f53357d7767f4f5ccbdbc596631277f8fecd08cb056b95e3025b9792fff7f244fc716269b926d62e9596fa825c6bf21aff9e68625a192440ea06828123d97884806f15fa08da52754a1095e3ff1abd5ce4fddfccfc3a6128aef784a64610a89d1a7099216d0814d3a2d452431c32d411ac1cce82ad0229407bbc48985675e3f874a4533f1d63a84dfa3e0f460fe2f57e34fbc75423c3737f5b2a0615f5722db041a3ef66fa483afd3c2e19e59444a64add6df1d963f5dd5b5010d3d025f0287c4cf19c75f33d51ddddba5d657b43ee8da645443814cc7329f3e9b4e54c236c29af3923101756d9fa4bd0f7d2ddaacb6b0f86a2658e0a07a05ac5b950051cd24c47a88d13d659ba2a46ca1830816d09cd7646f76f716abec5de07fe9b523410806ea6f288f8736c23357c85f45791e1708029d9824d90704607f387a03e49bf9836574431345a7877efaa8a08e73081ef8d62cb780ab6883a50a0d470190dfba10a857f82842d3825b3d6da0573d316eb160dc0b716c48fbd467f75b780149ae8808f4e68f50c0536acddf6f1aeab016b6bc1ec144b4e553acfd670f77e755fc88e0677e31ba459b44e307768958fe3789d41c2b1ff434cb30e15914f01bc6bc2307b488d2556d7b7380ea4ffd712f6b02fe806b94569cd4059f396bf29b99d0a40e5e1711ca944f72d436a102fca4b97693da0b086fe9d2e7162470d02e0f05d4bec9512bfb3f38327296efaa74328b118c27402c70c3a90b49ad4bbc68e37c0aa7d9b3fe17799d73b841e751713a02943905aae0803fd69442eb7681ec2a05600054e92eed555028f21b6a155268a2dd6640a69301a52a38d4d9f9f957ae35af7167118141ce4c9be0a6a492fe79f1581a155fa3a2b9dafd82e650b386ad3a08cb6b83131ac300b0846354a7eef9c410e4b62c47c5426907dfc6685c5c99b7141ac626ab4761fd3f41e728e1a28f89db89ffdeca364dd2f0f0739f0534556483199c71f189341ac9b78a269164206a0ea1ce73bfb2a942e7370b247c046f8e75ef8e3f8bd821cf577491864e20e6d08fd2e32b555c92c661f19588b72a89599710a88061253ca285b6304b37da2b5294f5cb354a894322848ccbdc7c2545b7da568afac87ffa005c312241c2d57f4b45d6419f0d2e2c5af33ae243785b325cdab95404fc7aed70525cddb41872cfcc214b13232edc78609753dbff930eb0dc156612b9cb434bc4b693392deb87c530435312edcedc6a961133338d786c4a3e103f60110a16b1337129704bf4754ff6ba9fbe65951e610620f71cda8fc877625f2c5bb04cbe1228b1e886f4050afd8fe94e97d2e9e85c6bb748c0042d3249abb1342bb0eebf62058bf3de080d94611a3750915b5dc6c0b3899d41222bace760ee9c8818ded599e34c56d7372af1eb86852f2a732104bdb750739de6c2c6e0f9eb7cb17f1942bfc9f4fd6ebb6b4cdd4da2bca26fac4578e9f543405acc7d86ff59158bd0cba3aef6f4a8472d144d99f8b8d1dedaa9077d4f01d4bb27bbe31d88fbefac3dcd4797563a26b1d61fcd9a464ab21ed550fe6fa09695ba0b2f10e00000000000000000000000000000000ea6468cc6e20a66f826e3d14c5006f0563887f5e1289be1b2004caca8d3f34d6e84bf59c1e04619a7c23a996941d889e4622a9b9b1d59d5e319094318cd405ba27b7e2c084762d31453ec4549a4d97729d033460fcf89d6494f2ffd789e98082ea5ce9534b3acd60fe49e37e4f666931677319ed89f85588741b3128901a93bd78e4be0225a9e2692c77c969ed0176bdf9555948cbd5a332d045de6ba6bf4490adfe7444cd467a09075417fcc0062e49f008c51ad4227439c1b4476ccd8e97862dab7be1e8d399c05ef27c6e22ee273e15786e394c8f1be31682a30147963ac8da8d41d804258426a3f70289b8ad19d8de13be4eebe3bd4c8a6f55d6e0c373d456851879f5fbc282db9e134806bff71e11bc33ab75dd6ca067fb73a043b646a70339cab4928386786d2f24141ee120fdc34d6764eafc66880ee0204f53cc1167ed02b43a52dea3ca7cff8ef35cd8e6d7c111a68ef44bcd0c1513ad47ca61c659cc5d0a5b440f6b9f59aff66879bb6688fd2859362b182f207b3175961f6411a493bffd048e7d0d87d82fe6f990a2b0a25f5aa0111a6e68f37bf6f3ac2d26b84686e569038d99c1383597fad81193c4c1b16e6a90e2d507cdfe6fbdaa86163e9cf5de310003ca7e8da047b090db9f37952fbfee76af61668190bd52ed490e677b515d0143840307219c7c0ee7fc7bfc79f325644e4df4c0d7db08e9f0bd024943c705abff899403a605cfbc7ed746a7d3f7c37d9e8bdc433b7d79e08a12f738a8f0dbddfef2f26502f3e47d1b0fd11e6a13311fb799c79c641d9da43b33e7ad012e28255398789262275f1175be8462c01491c4d842406d0ec4282c9526174a09878fe8fdde33a29604e5e5e7b2a025d6650b97dbb52befb59b1d30a57433b0a351474444099daa371046613260cf3354cfcdada663ece824ffd7e44393886a86165ddddf2b4c41773554c86995269408b11e6737a4c447586f69173446d8e48bf84cbc000a807899973eb93c5e819aad669413f8387933ad1584aa35e43f4ecd1e2d0407c0b1b89920ffdfdb9bea51ac95b557af71b89f903f5d9848f14fcbeb1837570f544d6359eb23faf38a0822da36ce426c4a2fbeffeb0a8a2e297a9d19ba15024590e3329d9fa9261f9938a4032dd34606c9cf9f3dd33e576f05cd1dd6811c6298757d77d9e810abdb226afcaa4346a6560f8932b3181fd355d5d391976183f8d99388839632d6354f666d09d3e5629ea19737388613d38a34fd0f6e50ee5a0cc9677177f50028c141378187bd2819403fc534f80076e9380cb4964d3b6b45819d3b8e9caf54f051852d671bf8c1ffde2d1510756418cb4810936aa57e6965d6fb656a760b7f19adf96c173488552193b147ee58858033dac7cd0eb204c06490bbdedf5f7571acb2ebe76acef3f2a01ee987486dfe6c3f0a5e234c127258f97a28fb5d164a8176be946b8097d0e317287f33bf9c16f9a545409ce29b1f4273725fc0df02a04ebae178b3414fb0a82d50deb09fcf4e6ee9d180ff4f56ff3bc1d3601fc2dc90d814c3256f4967d3a8d64c83fea339c51f5a8e5801fbb97835581b602465dee04b5922c2761b54245bec0c9eef2db97d22b2b3556cc969fbb13d06509765a52b3fac54b93f421bf08e18d52ddd52cc1c8ca8adfaccab7e5cc2f4573fbbf8239bb0b8aedbf8dad16282da5c9125dba1c059d0df8abf621078f02d6c4bc86d40845ac1d59710c45f07d585eb48b32fc0167ba256e73ca3b9311c62d109497957d8dbe10aa3e866b40c0baa2bc492c19ad1e6372d9622bf163fbffeaeee796a3cd9b6fbbfa4d792f34d7fd6e763cd5859dd26833d21d9bc5452bd19515dff9f4995b35bc0c1f876e6ad11f2452dc9ae85aec01fc56f8cbfda75a7727b75ebbd6bbffb43b63a3b1b671e40feb0db002974a3c3b1a788567231bf6399ff89236981149d423802d2341a3bedb9ddcbac1fe7b6435e1479c72e7089d029e7fbbaf3cf37e9b9a6b776791e4c5e6fda57e8d5f14c8c35a2d270846b9dbe005cda16af4408f3ab06a916eeeb9c9594b70424a4c1d171295b6763b22f47f80b53ccbb904bd68fd65fbd3fbdea1035e98c21a7dbc91a9b5bc7690f05ec317c97f8764eb48e911d428ec8d861b708e8298acb62155145155ae95f0a1d1501034753146e22d05f586d7f6b4fe12dad9a17f5db70b1db96b8d9a83edadc966c8a5466b61fc998c31f1070d9a5c9a6d268d304fe6b8fd3b4010348611abdcbd49fe4f85b623c7828c71382e1034ea67bc8ae97404b0c50b2a04f559e49950afcb0ef462a2ae024b0f0224dfd73684b88c7fbe92d02b68f759c4752663cd7b97a14943649305521326bde085630864629291bae25ff8822a14c4b666a9259ad0dc42a8290ac7bc7f53a16f379f758e5de750f04fd7cad47701c8597f97888bea6fa0bf2999956fbfd0ee68ec36e4688809ae231eb8bc4369f5fe1573f57e099d9c09901bf39caac48dc11956a8ae905ead86954547c448ae43d315e669c4242da565938f417bf43ce7b2b30b1cd4018388e1a910f0fc41fb0877a5925e466819d375b0a912d4fe843b76ef6f223f0f7c894f38f7ab780dfd75f669c8c06cffa43eb47565a50e3b1fa45ad61ce9a1c4727b7aaa53562f523e73952
-
-header:          03000080
-nVersionGroupId: 7082c403
-vin:             02 4201cfb1cd8dbf69b8250c18ef41294ca97993db546c1fe01f7e9c8e36d6a5e2 9d4e30a7 03ac6a00 98421c69
-                    378af1e40f64e125946f62c2fa7b2fecbcb64b6968912a6381ce3dc166d56a1d 62f5a8d7 056363635353 e8c7203d
-vout:            02 d2da86387ae60100 080063656a63ac5200
-                    a7622997f4ff0400 0751510053536565
-nLockTime:       97b0e4e4
-nExpiryHeight:   c705fc05
-vJoinSplit:      02
-  vpub_old:     0000000000000000
-  vpub_new:     0000000000000000
-  anchor:       76495c222f7fba1e31defa3d5a57efc2e1e9b01a035587d5fb1a38e01d94903d
-  nullifiers:   3c3e0ad3360c1d3710acd20b183e31d49f25c9a138f49b1a537edcf04be34a98 51a7af9db6990ed83dd64af3597c04323ea51b0052ad8084a8b9da948d320dad
-  commitments:  d64f5431e61ddf658d24ae67c22c8d1309131fc00fe7f235734276d38d47f1e1 91e00c7a1d48af046827591e9733a97fa6b679f3dc601d008285edcbdae69ce8
-  ephemeralKey: fc1be4aac00ff2711ebd931de518856878f73476f21a482ec9378365c8f7393c
-  randomSeed:   94e2885315eb4671098b79535e790fe53e29fef2b3766697ac32b4f473f468a0
-  macs:         08e72389fc03880d780cb07fcfaabe3f1a84b27db59a4a153d882d2b21035965 55ed9494c6ac893c49723833ec8926c1039586a7afcf4a0d9c731e985d99589c
-  proof:        03b838e8aaf745533ed9e8ae3a1cd074a51a20da8aba18d1dbebbc862ded42435e02476930d069896cff30eb414f727b89e001afa2fb8dc3436d75a4a6f26572504b0b2232ecb9f0c02411e52596bc5e90457e745939ffedbd12863ce71a02af117d417adb3d15cc54dcb1fce467500c6b8fb86b12b56da9c382857deecc40a98d5f2903395ee4762dd21afdbb5d47fa9a6dd984d567db2857b927b7fae2db587105415d0242789d38f50b8dbcc129cab3d17d19f3355bcf73cecb8cb8a5da01307152f13902a270572670dc82d39026c6cb4cd4b0f7f5aa2a4f5a5341ec5dd715406f2fdd2a02733f5f641c8c21862a1bafce2609d9eecfa158cfb5cd79f88008e315dc7d8388036c1782fd2795d18a763624c25fa959cc97489ce75745824b77868c53239cfbdf
-  ciphertexts:
-    73caec65604037314faaceb56218c6bd30f8374ac13386793f21a9fb80ad03bc0cda4a44946c00e1b1a1df0e5b87b5bece477a709649e950060591394812951e1fe3895b8cc3d14d2cf6556df6ed4b4ddd3d9a69f53357d7767f4f5ccbdbc596631277f8fecd08cb056b95e3025b9792fff7f244fc716269b926d62e9596fa825c6bf21aff9e68625a192440ea06828123d97884806f15fa08da52754a1095e3ff1abd5ce4fddfccfc3a6128aef784a64610a89d1a7099216d0814d3a2d452431c32d411ac1cce82ad0229407bbc48985675e3f874a4533f1d63a84dfa3e0f460fe2f57e34fbc75423c3737f5b2a0615f5722db041a3ef66fa483afd3c2e19e59444a64add6df1d963f5dd5b5010d3d025f0287c4cf19c75f33d51ddddba5d657b43ee8da645443814cc7329f3e9b4e54c236c29af3923101756d9fa4bd0f7d2ddaacb6b0f86a2658e0a07a05ac5b950051cd24c47a88d13d659ba2a46ca1830816d09cd7646f76f716abec5de07fe9b523410806ea6f288f8736c23357c85f45791e1708029d9824d90704607f387a03e49bf9836574431345a7877efaa8a08e73081ef8d62cb780ab6883a50a0d470190dfba10a857f82842d3825b3d6da0573d316eb160dc0b716c48fbd467f75b780149ae8808f4e68f50c0536acddf6f1aeab016b6bc1ec144b4e553acfd670f77e755fc88e0677e31ba459b44e307768958fe3789d41c2b1ff434cb30e15914f01bc6bc2307b488d2556d7b7380ea4ffd712f6b02fe806b94569cd4059f396bf29b99d0a40e5e1711ca944f72d436a102fca4b97693da0b086fe9d2e7162470d02e0f05d4bec9512bf
-    b3f38327296efaa74328b118c27402c70c3a90b49ad4bbc68e37c0aa7d9b3fe17799d73b841e751713a02943905aae0803fd69442eb7681ec2a05600054e92eed555028f21b6a155268a2dd6640a69301a52a38d4d9f9f957ae35af7167118141ce4c9be0a6a492fe79f1581a155fa3a2b9dafd82e650b386ad3a08cb6b83131ac300b0846354a7eef9c410e4b62c47c5426907dfc6685c5c99b7141ac626ab4761fd3f41e728e1a28f89db89ffdeca364dd2f0f0739f0534556483199c71f189341ac9b78a269164206a0ea1ce73bfb2a942e7370b247c046f8e75ef8e3f8bd821cf577491864e20e6d08fd2e32b555c92c661f19588b72a89599710a88061253ca285b6304b37da2b5294f5cb354a894322848ccbdc7c2545b7da568afac87ffa005c312241c2d57f4b45d6419f0d2e2c5af33ae243785b325cdab95404fc7aed70525cddb41872cfcc214b13232edc78609753dbff930eb0dc156612b9cb434bc4b693392deb87c530435312edcedc6a961133338d786c4a3e103f60110a16b1337129704bf4754ff6ba9fbe65951e610620f71cda8fc877625f2c5bb04cbe1228b1e886f4050afd8fe94e97d2e9e85c6bb748c0042d3249abb1342bb0eebf62058bf3de080d94611a3750915b5dc6c0b3899d41222bace760ee9c8818ded599e34c56d7372af1eb86852f2a732104bdb750739de6c2c6e0f9eb7cb17f1942bfc9f4fd6ebb6b4cdd4da2bca26fac4578e9f543405acc7d86ff59158bd0cba3aef6f4a8472d144d99f8b8d1dedaa9077d4f01d4bb27bbe31d88fbefac3dcd4797563a26b1d61fcd9a464ab21ed550fe6fa09695ba0b2f10e
-
-  vpub_old:     0000000000000000
-  vpub_new:     0000000000000000
-  anchor:       ea6468cc6e20a66f826e3d14c5006f0563887f5e1289be1b2004caca8d3f34d6
-  nullifiers:   e84bf59c1e04619a7c23a996941d889e4622a9b9b1d59d5e319094318cd405ba 27b7e2c084762d31453ec4549a4d97729d033460fcf89d6494f2ffd789e98082
-  commitments:  ea5ce9534b3acd60fe49e37e4f666931677319ed89f85588741b3128901a93bd 78e4be0225a9e2692c77c969ed0176bdf9555948cbd5a332d045de6ba6bf4490
-  ephemeralKey: adfe7444cd467a09075417fcc0062e49f008c51ad4227439c1b4476ccd8e9786
-  randomSeed:   2dab7be1e8d399c05ef27c6e22ee273e15786e394c8f1be31682a30147963ac8
-  macs:         da8d41d804258426a3f70289b8ad19d8de13be4eebe3bd4c8a6f55d6e0c373d4 56851879f5fbc282db9e134806bff71e11bc33ab75dd6ca067fb73a043b646a7
-  proof:        0339cab4928386786d2f24141ee120fdc34d6764eafc66880ee0204f53cc1167ed02b43a52dea3ca7cff8ef35cd8e6d7c111a68ef44bcd0c1513ad47ca61c659cc5d0a5b440f6b9f59aff66879bb6688fd2859362b182f207b3175961f6411a493bffd048e7d0d87d82fe6f990a2b0a25f5aa0111a6e68f37bf6f3ac2d26b84686e569038d99c1383597fad81193c4c1b16e6a90e2d507cdfe6fbdaa86163e9cf5de310003ca7e8da047b090db9f37952fbfee76af61668190bd52ed490e677b515d0143840307219c7c0ee7fc7bfc79f325644e4df4c0d7db08e9f0bd024943c705abff899403a605cfbc7ed746a7d3f7c37d9e8bdc433b7d79e08a12f738a8f0dbddfef2f26502f3e47d1b0fd11e6a13311fb799c79c641d9da43b33e7ad012e28255398789262
-  ciphertexts:
-    275f1175be8462c01491c4d842406d0ec4282c9526174a09878fe8fdde33a29604e5e5e7b2a025d6650b97dbb52befb59b1d30a57433b0a351474444099daa371046613260cf3354cfcdada663ece824ffd7e44393886a86165ddddf2b4c41773554c86995269408b11e6737a4c447586f69173446d8e48bf84cbc000a807899973eb93c5e819aad669413f8387933ad1584aa35e43f4ecd1e2d0407c0b1b89920ffdfdb9bea51ac95b557af71b89f903f5d9848f14fcbeb1837570f544d6359eb23faf38a0822da36ce426c4a2fbeffeb0a8a2e297a9d19ba15024590e3329d9fa9261f9938a4032dd34606c9cf9f3dd33e576f05cd1dd6811c6298757d77d9e810abdb226afcaa4346a6560f8932b3181fd355d5d391976183f8d99388839632d6354f666d09d3e5629ea19737388613d38a34fd0f6e50ee5a0cc9677177f50028c141378187bd2819403fc534f80076e9380cb4964d3b6b45819d3b8e9caf54f051852d671bf8c1ffde2d1510756418cb4810936aa57e6965d6fb656a760b7f19adf96c173488552193b147ee58858033dac7cd0eb204c06490bbdedf5f7571acb2ebe76acef3f2a01ee987486dfe6c3f0a5e234c127258f97a28fb5d164a8176be946b8097d0e317287f33bf9c16f9a545409ce29b1f4273725fc0df02a04ebae178b3414fb0a82d50deb09fcf4e6ee9d180ff4f56ff3bc1d3601fc2dc90d814c3256f4967d3a8d64c83fea339c51f5a8e5801fbb97835581b602465dee04b5922c2761b54245bec0c9eef2db97d22b2b3556cc969fbb13d06509765a52b3fac54b93f421bf08e18d52ddd52cc1c8ca8adfaccab7e5cc2
-    f4573fbbf8239bb0b8aedbf8dad16282da5c9125dba1c059d0df8abf621078f02d6c4bc86d40845ac1d59710c45f07d585eb48b32fc0167ba256e73ca3b9311c62d109497957d8dbe10aa3e866b40c0baa2bc492c19ad1e6372d9622bf163fbffeaeee796a3cd9b6fbbfa4d792f34d7fd6e763cd5859dd26833d21d9bc5452bd19515dff9f4995b35bc0c1f876e6ad11f2452dc9ae85aec01fc56f8cbfda75a7727b75ebbd6bbffb43b63a3b1b671e40feb0db002974a3c3b1a788567231bf6399ff89236981149d423802d2341a3bedb9ddcbac1fe7b6435e1479c72e7089d029e7fbbaf3cf37e9b9a6b776791e4c5e6fda57e8d5f14c8c35a2d270846b9dbe005cda16af4408f3ab06a916eeeb9c9594b70424a4c1d171295b6763b22f47f80b53ccbb904bd68fd65fbd3fbdea1035e98c21a7dbc91a9b5bc7690f05ec317c97f8764eb48e911d428ec8d861b708e8298acb62155145155ae95f0a1d1501034753146e22d05f586d7f6b4fe12dad9a17f5db70b1db96b8d9a83edadc966c8a5466b61fc998c31f1070d9a5c9a6d268d304fe6b8fd3b4010348611abdcbd49fe4f85b623c7828c71382e1034ea67bc8ae97404b0c50b2a04f559e49950afcb0ef462a2ae024b0f0224dfd73684b88c7fbe92d02b68f759c4752663cd7b97a14943649305521326bde085630864629291bae25ff8822a14c4b666a9259ad0dc42a8290ac7bc7f53a16f379f758e5de750f04fd7cad47701c8597f97888bea6fa0bf2999956fbfd0ee68ec36e4688809ae231eb8bc4369f5fe1573f57e099d9c09901bf39caac48dc11956a8ae905ead86954547c448ae43d31
-
-joinSplitPubKey: 5e669c4242da565938f417bf43ce7b2b30b1cd4018388e1a910f0fc41fb0877a
-joinSplitSig:    5925e466819d375b0a912d4fe843b76ef6f223f0f7c894f38f7ab780dfd75f669c8c06cffa43eb47565a50e3b1fa45ad61ce9a1c4727b7aaa53562f523e73952
-(joinSplitPubKey is a potentially-invalid public key; joinSplitSig is invalid random data)
-

Transaction digest with nIn = 1 and nHashType = 3 (SIGHASH_SINGLE):

-
hashPrevouts:
-  BLAKE2b-256('ZcashPrevoutHash', 4201cfb1cd8dbf69b8250c18ef41294ca97993db546c1fe01f7e9c8e36d6a5e29d4e30a7378af1e40f64e125946f62c2fa7b2fecbcb64b6968912a6381ce3dc166d56a1d62f5a8d7)
-= 92b8af1f7e12cb8de105af154470a2ae0a11e64a24a514a562ff943ca0f35d7f
-
-hashOutputs:
-  BLAKE2b-256('ZcashOutputsHash', 23752997f4ff04000751510053536565)
-= e03b74bc5187184406285bb9f03b4be510f5700c5859738434cf7b8f5bdb6772
-
-hashJoinSplits:
-  BLAKE2b-256('ZcashJSplitsHash', 0000000000000000000000000000000076495c222f7fba1e31defa3d5a57efc2e1e9b01a035587d5fb1a38e01d94903d3c3e0ad3360c1d3710acd20b183e31d49f25c9a138f49b1a537edcf04be34a9851a7af9db6990ed83dd64af3597c04323ea51b0052ad8084a8b9da948d320dadd64f5431e61ddf658d24ae67c22c8d1309131fc00fe7f235734276d38d47f1e191e00c7a1d48af046827591e9733a97fa6b679f3dc601d008285edcbdae69ce8fc1be4aac00ff2711ebd931de518856878f73476f21a482ec9378365c8f7393c94e2885315eb4671098b79535e790fe53e29fef2b3766697ac32b4f473f468a008e72389fc03880d780cb07fcfaabe3f1a84b27db59a4a153d882d2b2103596555ed9494c6ac893c49723833ec8926c1039586a7afcf4a0d9c731e985d99589c03b838e8aaf745533ed9e8ae3a1cd074a51a20da8aba18d1dbebbc862ded42435e02476930d069896cff30eb414f727b89e001afa2fb8dc3436d75a4a6f26572504b0b2232ecb9f0c02411e52596bc5e90457e745939ffedbd12863ce71a02af117d417adb3d15cc54dcb1fce467500c6b8fb86b12b56da9c382857deecc40a98d5f2903395ee4762dd21afdbb5d47fa9a6dd984d567db2857b927b7fae2db587105415d0242789d38f50b8dbcc129cab3d17d19f3355bcf73cecb8cb8a5da01307152f13902a270572670dc82d39026c6cb4cd4b0f7f5aa2a4f5a5341ec5dd715406f2fdd2a02733f5f641c8c21862a1bafce2609d9eecfa158cfb5cd79f88008e315dc7d8388036c1782fd2795d18a763624c25fa959cc97489ce75745824b77868c53239cfbdf73caec65604037314faaceb56218c6bd30f8374ac13386793f21a9fb80ad03bc0cda4a44946c00e1b1a1df0e5b87b5bece477a709649e950060591394812951e1fe3895b8cc3d14d2cf6556df6ed4b4ddd3d9a69f53357d7767f4f5ccbdbc596631277f8fecd08cb056b95e3025b9792fff7f244fc716269b926d62e9596fa825c6bf21aff9e68625a192440ea06828123d97884806f15fa08da52754a1095e3ff1abd5ce4fddfccfc3a6128aef784a64610a89d1a7099216d0814d3a2d452431c32d411ac1cce82ad0229407bbc48985675e3f874a4533f1d63a84dfa3e0f460fe2f57e34fbc75423c3737f5b2a0615f5722db041a3ef66fa483afd3c2e19e59444a64add6df1d963f5dd5b5010d3d025f0287c4cf19c75f33d51ddddba5d657b43ee8da645443814cc7329f3e9b4e54c236c29af3923101756d9fa4bd0f7d2ddaacb6b0f86a2658e0a07a05ac5b950051cd24c47a88d13d659ba2a46ca1830816d09cd7646f76f716abec5de07fe9b523410806ea6f288f8736c23357c85f45791e1708029d9824d90704607f387a03e49bf9836574431345a7877efaa8a08e73081ef8d62cb780ab6883a50a0d470190dfba10a857f82842d3825b3d6da0573d316eb160dc0b716c48fbd467f75b780149ae8808f4e68f50c0536acddf6f1aeab016b6bc1ec144b4e553acfd670f77e755fc88e0677e31ba459b44e307768958fe3789d41c2b1ff434cb30e15914f01bc6bc2307b488d2556d7b7380ea4ffd712f6b02fe806b94569cd4059f396bf29b99d0a40e5e1711ca944f72d436a102fca4b97693da0b086fe9d2e7162470d02e0f05d4bec9512bfb3f38327296efaa74328b118c27402c70c3a90b49ad4bbc68e37c0aa7d9b3fe17799d73b841e751713a02943905aae0803fd69442eb7681ec2a05600054e92eed555028f21b6a155268a2dd6640a69301a52a38d4d9f9f957ae35af7167118141ce4c9be0a6a492fe79f1581a155fa3a2b9dafd82e650b386ad3a08cb6b83131ac300b0846354a7eef9c410e4b62c47c5426907dfc6685c5c99b7141ac626ab4761fd3f41e728e1a28f89db89ffdeca364dd2f0f0739f0534556483199c71f189341ac9b78a269164206a0ea1ce73bfb2a942e7370b247c046f8e75ef8e3f8bd821cf577491864e20e6d08fd2e32b555c92c661f19588b72a89599710a88061253ca285b6304b37da2b5294f5cb354a894322848ccbdc7c2545b7da568afac87ffa005c312241c2d57f4b45d6419f0d2e2c5af33ae243785b325cdab95404fc7aed70525cddb41872cfcc214b13232edc78609753dbff930eb0dc156612b9cb434bc4b693392deb87c530435312edcedc6a961133338d786c4a3e103f60110a16b1337129704bf4754ff6ba9fbe65951e610620f71cda8fc877625f2c5bb04cbe1228b1e886f4050afd8fe94e97d2e9e85c6bb748c0042d3249abb1342bb0eebf62058bf3de080d94611a3750915b5dc6c0b3899d41222bace760ee9c8818ded599e34c56d7372af1eb86852f2a732104bdb750739de6c2c6e0f9eb7cb17f1942bfc9f4fd6ebb6b4cdd4da2bca26fac4578e9f543405acc7d86ff59158bd0cba3aef6f4a8472d144d99f8b8d1dedaa9077d4f01d4bb27bbe31d88fbefac3dcd4797563a26b1d61fcd9a464ab21ed550fe6fa09695ba0b2f10e00000000000000000000000000000000ea6468cc6e20a66f826e3d14c5006f0563887f5e1289be1b2004caca8d3f34d6e84bf59c1e04619a7c23a996941d889e4622a9b9b1d59d5e319094318cd405ba27b7e2c084762d31453ec4549a4d97729d033460fcf89d6494f2ffd789e98082ea5ce9534b3acd60fe49e37e4f666931677319ed89f85588741b3128901a93bd78e4be0225a9e2692c77c969ed0176bdf9555948cbd5a332d045de6ba6bf4490adfe7444cd467a09075417fcc0062e49f008c51ad4227439c1b4476ccd8e97862dab7be1e8d399c05ef27c6e22ee273e15786e394c8f1be31682a30147963ac8da8d41d804258426a3f70289b8ad19d8de13be4eebe3bd4c8a6f55d6e0c373d456851879f5fbc282db9e134806bff71e11bc33ab75dd6ca067fb73a043b646a70339cab4928386786d2f24141ee120fdc34d6764eafc66880ee0204f53cc1167ed02b43a52dea3ca7cff8ef35cd8e6d7c111a68ef44bcd0c1513ad47ca61c659cc5d0a5b440f6b9f59aff66879bb6688fd2859362b182f207b3175961f6411a493bffd048e7d0d87d82fe6f990a2b0a25f5aa0111a6e68f37bf6f3ac2d26b84686e569038d99c1383597fad81193c4c1b16e6a90e2d507cdfe6fbdaa86163e9cf5de310003ca7e8da047b090db9f37952fbfee76af61668190bd52ed490e677b515d0143840307219c7c0ee7fc7bfc79f325644e4df4c0d7db08e9f0bd024943c705abff899403a605cfbc7ed746a7d3f7c37d9e8bdc433b7d79e08a12f738a8f0dbddfef2f26502f3e47d1b0fd11e6a13311fb799c79c641d9da43b33e7ad012e28255398789262275f1175be8462c01491c4d842406d0ec4282c9526174a09878fe8fdde33a29604e5e5e7b2a025d6650b97dbb52befb59b1d30a57433b0a351474444099daa371046613260cf3354cfcdada663ece824ffd7e44393886a86165ddddf2b4c41773554c86995269408b11e6737a4c447586f69173446d8e48bf84cbc000a807899973eb93c5e819aad669413f8387933ad1584aa35e43f4ecd1e2d0407c0b1b89920ffdfdb9bea51ac95b557af71b89f903f5d9848f14fcbeb1837570f544d6359eb23faf38a0822da36ce426c4a2fbeffeb0a8a2e297a9d19ba15024590e3329d9fa9261f9938a4032dd34606c9cf9f3dd33e576f05cd1dd6811c6298757d77d9e810abdb226afcaa4346a6560f8932b3181fd355d5d391976183f8d99388839632d6354f666d09d3e5629ea19737388613d38a34fd0f6e50ee5a0cc9677177f50028c141378187bd2819403fc534f80076e9380cb4964d3b6b45819d3b8e9caf54f051852d671bf8c1ffde2d1510756418cb4810936aa57e6965d6fb656a760b7f19adf96c173488552193b147ee58858033dac7cd0eb204c06490bbdedf5f7571acb2ebe76acef3f2a01ee987486dfe6c3f0a5e234c127258f97a28fb5d164a8176be946b8097d0e317287f33bf9c16f9a545409ce29b1f4273725fc0df02a04ebae178b3414fb0a82d50deb09fcf4e6ee9d180ff4f56ff3bc1d3601fc2dc90d814c3256f4967d3a8d64c83fea339c51f5a8e5801fbb97835581b602465dee04b5922c2761b54245bec0c9eef2db97d22b2b3556cc969fbb13d06509765a52b3fac54b93f421bf08e18d52ddd52cc1c8ca8adfaccab7e5cc2f4573fbbf8239bb0b8aedbf8dad16282da5c9125dba1c059d0df8abf621078f02d6c4bc86d40845ac1d59710c45f07d585eb48b32fc0167ba256e73ca3b9311c62d109497957d8dbe10aa3e866b40c0baa2bc492c19ad1e6372d9622bf163fbffeaeee796a3cd9b6fbbfa4d792f34d7fd6e763cd5859dd26833d21d9bc5452bd19515dff9f4995b35bc0c1f876e6ad11f2452dc9ae85aec01fc56f8cbfda75a7727b75ebbd6bbffb43b63a3b1b671e40feb0db002974a3c3b1a788567231bf6399ff89236981149d423802d2341a3bedb9ddcbac1fe7b6435e1479c72e7089d029e7fbbaf3cf37e9b9a6b776791e4c5e6fda57e8d5f14c8c35a2d270846b9dbe005cda16af4408f3ab06a916eeeb9c9594b70424a4c1d171295b6763b22f47f80b53ccbb904bd68fd65fbd3fbdea1035e98c21a7dbc91a9b5bc7690f05ec317c97f8764eb48e911d428ec8d861b708e8298acb62155145155ae95f0a1d1501034753146e22d05f586d7f6b4fe12dad9a17f5db70b1db96b8d9a83edadc966c8a5466b61fc998c31f1070d9a5c9a6d268d304fe6b8fd3b4010348611abdcbd49fe4f85b623c7828c71382e1034ea67bc8ae97404b0c50b2a04f559e49950afcb0ef462a2ae024b0f0224dfd73684b88c7fbe92d02b68f759c4752663cd7b97a14943649305521326bde085630864629291bae25ff8822a14c4b666a9259ad0dc42a8290ac7bc7f53a16f379f758e5de750f04fd7cad47701c8597f97888bea6fa0bf2999956fbfd0ee68ec36e4688809ae231eb8bc4369f5fe1573f57e099d9c09901bf39caac48dc11956a8ae905ead86954547c448ae43d315e669c4242da565938f417bf43ce7b2b30b1cd4018388e1a910f0fc41fb0877a)
-= f59e41b40f3a60be90bee2be11b0956dfff06a6d8e22668c4f215bd87b20d514
-
-Preimage:
-030000807082c40392b8af1f7e12cb8de105af154470a2ae0a11e64a24a514a562ff943ca0f35d7f0000000000000000000000000000000000000000000000000000000000000000edc32cce530f836f7c31c53656f859f514c3ff8dcae642d3e17700fdc6e829a4f59e41b40f3a60be90bee2be11b0956dfff06a6d8e22668c4f215bd87b20d51497b0e4e4c705fc0503000000378af1e40f64e125946f62c2fa7b2fecbcb64b6968912a6381ce3dc166d56a1d62f5a8d701532f6e04963b4c0100e8c7203d
-
-header:          03000080
-nVersionGroupId: 7082c403
-hashPrevouts:    92b8af1f7e12cb8de105af154470a2ae0a11e64a24a514a562ff943ca0f35d7f
-hashSequence:    0000000000000000000000000000000000000000000000000000000000000000
-hashOutputs:     edc32cce530f836f7c31c53656f859f514c3ff8dcae642d3e17700fdc6e829a4
-hashJoinSplits:  f59e41b40f3a60be90bee2be11b0956dfff06a6d8e22668c4f215bd87b20d514
-nLockTime:       97b0e4e4
-nExpiryHeight:   c705fc05
-nHashType:       03000000
-
-Input:
-  prevout:    378af1e40f64e125946f62c2fa7b2fecbcb64b6968912a6381ce3dc166d56a1d 62f5a8d7
-  scriptCode: 0153
-  amount:     2f6e04963b4c0100
-  nSequence:  e8c7203d
-
-sighash: 23652e76cb13b85a0e3363bb5fca061fa791c40c533eccee899364e6e60bb4f7
-
-
-

Deployment

-

This proposal is deployed with the Overwinter network upgrade. 11

-
-

Backward compatibility

-

This proposal is backwards-compatible with old UTXOs. It is not backwards-compatible with older software. All transactions will be required to use this transaction digest algorithm for signatures, and so transactions created by older software will be rejected by the network.

-
-

Reference Implementation

-

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

-
-

References

- - - - - - - -
1Information 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"
- - - - - - - -
2Zcash Protocol Specification, Version 2021.2.16. Section 4.7.1: Sending Notes (Sprout)
- - - - - - - -
3OP_CHECKSIG. Bitcoin Wiki
- - - - - - - -
4 - -
- - - - - - - -
5SIGHASH_WITHINPUTVALUE: Super-lightweight HW wallets and offline data
- - - - - - - -
6BIP 143: Transaction Signature Verification for Version 0 Witness Program
- - - - - - - -
7BUIP-HF Digest for replay protected signature verification across hard forks, version 1.2
- - - - - - - -
8"BLAKE2: simpler, smaller, fast as MD5", Section 2.8
- - - - - - - -
9In the original algorithm, a uint256 of 0x0000......0001 is committed if the input index for a SINGLE signature is greater than or equal to the number of outputs. In this ZIP a 0x0000......0000 is commited, without changing the semantics.
- - - - - - - -
10ZIP 200: Network Upgrade Mechanism
- - - - - - - -
11ZIP 201: Network Peer Management for Overwinter
- - - - - - - -
12ZIP 202: Version 3 Transaction Format for Overwinter
- - - - - - - -
13ZIP 203: Transaction Expiry
- - - - - - - -
14ZIP 143 Test Vectors
- - - - - - - -
15SignatureHash Test Vectors
-
-
- - \ No newline at end of file diff --git a/rendered/zip-0155.html b/rendered/zip-0155.html deleted file mode 100644 index a28ada2c4..000000000 --- a/rendered/zip-0155.html +++ /dev/null @@ -1,287 +0,0 @@ - - - - ZIP 155: addrv2 message - - - -
-
ZIP: 155
-Title: addrv2 message
-Owners: Daira-Emma Hopwood <daira-emma@electriccoin.co>
-Credits: Wladimir J. van der Laan
-         Zancas Wilcox
-Status: Proposed
-Category: Network
-Created: 2021-08-13
-License: BSD-2-Clause
-Discussions-To: <https://github.com/zcash/zips/issues/542>
-Pull-Request: <https://github.com/zcash/zips/pull/543>
-

Terminology

-

The key words "MUST", "MUST NOT", "SHOULD", "SHOULD NOT", 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. 4

-

The terms "Testnet" and "Mainnet" are to be interpreted as described in section 3.12 of the Zcash Protocol Specification 2.

-

"P2P network" means the Zcash peer-to-peer network.

-

uint8, uint16, and uint32 denote unsigned integer data types of the corresponding length (8, 16, or 32 bits respectively).

-
-

Abstract

-

This document proposes a new P2P message to gossip longer node addresses over the P2P network. This is required to support new-generation onion addresses, I2P, and potentially other networks that have longer endpoint addresses than fit in the 128 bits of the current addr message.

-
-

Motivation

-

Tor v3 onion services are part of the stable release of Tor since version 0.3.2.9. They have various advantages compared to the old v2 onion services, among which better encryption and privacy 9. These services have 256-bit addresses and thus do not fit in the existing addr message (unchanged from Bitcoin 7), which encapsulates onion addresses in OnionCat IPv6 addresses.

-

Other transport-layer protocols such as I2P have always used longer addresses. This change would make it possible to gossip such addresses over the P2P network, so that other peers can connect to them.

-
-

Specification

-

The addrv2 message is defined as a message where the command field is (NUL-padded) "addrv2". It is serialized in the standard encoding for P2P messages. Its format is similar to the current addr message format described in 7, with the difference that the fixed 16-byte IP address is replaced by a network ID and a variable-length address, and the services format has been changed to 8.

-

This means that the message contains a serialized vector of the following structure:

-
- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
BytesNameData TypeDescription
4timeuint32Time that this node was last seen as connected to the network. A time in Unix epoch time format.
variesservicesCompactSizeService bits. A CompactSize-encoded bit field that is 64 bits wide.
1networkIDuint8Network identifier. An 8-bit value that specifies which network is addressed.
variessizeAddrCompactSizeThe length in bytes of addr.
sizeAddraddruint8[sizeAddr]Network address. The interpretation depends on networkID.
2portuint16Network port. If not relevant for the network this MUST be 0.
-
-

One message can contain up to 1,000 addresses. Clients MUST reject messages with more addresses.

-

Field addr has a variable length, with a maximum of 512 bytes (4096 bits). Clients MUST reject messages with a longer addr field, irrespective of the network ID.

-

The list of reserved network IDs is as follows:

-
- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
Network IDEnumerationAddress length (bytes)Description
0x01IPV44IPv4 address (globally routed internet)
0x02IPV616IPv6 address (globally routed internet)
0x04TORV332Tor v3 onion service address
0x05I2P32I2P overlay network address
0x06CJDNS16Cjdns overlay network address
-
-

Network ID 0x03 is intentionally not assigned. In BIP 155 3 it was assigned to Tor v2 onion addresses, but those addresses are no longer supported by the latest Tor client code, and MUST NOT be used once this ZIP is deployed.

-

Clients SHOULD gossip valid, potentially routable addresses from all known networks, even if they are currently not connected to some of them. That could help multi-homed nodes and make it more difficult for an observer to tell which networks a node is connected to.

-

Clients MUST NOT gossip addresses from unknown networks, because they have no means to validate those addresses and so can be tricked to gossip invalid addresses.

-

Clients MUST reject messages that contain addresses that have a different length than specified in this table for a specific network ID, as these are meaningless.

-

Network address encodings

-

The IPV4 and IPV6 network IDs use addresses encoded in the usual way for binary IPv4 and IPv6 addresses in network byte order (big endian).

-

Tor v3 address encoding

-

According to the spec 9, version 3 .onion addresses are encoded as follows:

-
onion_address = base32(PUBKEY || CHECKSUM || VERSION) + ".onion"
-CHECKSUM = H(".onion checksum" || PUBKEY || VERSION)[:2]  // first 2 bytes
-

where:

-
    -
  • PUBKEY is the 32-byte Ed25519 master pubkey of the onion service;
  • -
  • VERSION is a one-byte version field (default value 0x03);
  • -
  • ".onion" and ".onion checksum" are constant strings;
  • -
  • CHECKSUM is truncated to two bytes before inserting it in onion_address;
  • -
  • H() is the SHA3-256 cryptographic hash function. 10
  • -
-

Tor v3 addresses MUST be sent with the TORV3 network ID, with the 32-byte PUBKEY part in the addr field. As VERSION will always be 0x03 in the case of v3 addresses, this is enough to reconstruct the onion address.

-
-

I2P address encoding

-

Like Tor, I2P naming uses a base32-encoded address format 11.

-

I2P uses 52 characters (256 bits) to represent the full SHA-256 hash, followed by .b32.i2p. The base32 encoding does not include "=" padding characters.

-

I2P addresses MUST be sent with the I2P network ID, with the decoded SHA-256 hash as address field.

-
-

Cjdns address encoding

-

Cjdns addresses are simply IPv6 addresses in the fc00::/8 range 12. They MUST be sent with the CJDNS network ID. They are encoded in network byte order (big endian) as for the IPV6 network ID.

-
-
-

Deployment

-

TODO: change ${PLACEHOLDER} to a specific peer protocol version.

-

Support for this specification is signalled by peer protocol version ${PLACEHOLDER} (on both Testnet and Mainnet). Note that this is the same peer protocol version that signals support for NU5 on Mainnet 6.

-

Nodes that have not negotiated peer protocol version ${PLACEHOLDER} or higher on a given connection, MUST NOT send addrv2 messages on that connection.

-

A node that has negotiated peer protocol version ${PLACEHOLDER} or higher on a given connection, MAY still send addr messages on the connection, and MUST handle received addr messages as it would have done prior to this ZIP.

-
-
-

Rationale

-

This ZIP is closely based on BIP 155 3, with the following changes:

-
    -
  • Deployment: support for the addrv2 message is signalled by advertising a peer protocol version of ${PLACEHOLDER} or higher, not by sending a sendaddrv2 message. This is motivated by a desire to avoid an exponential explosion in the space of possible feature configurations in a given peer-to-peer connection. In Zcash, unlike Bitcoin, the space of such configurations is effectively constant no matter how many peer-to-peer protocol changes are made, because nodes that do not support a given peer protocol version will drop off the network over time if they do not support the latest Network Upgrade. The feature configuration for a given connection is also established at version negotiation, and cannot change after that point without reconnecting. Other peer-to-peer protocol changes ported from the Bitcoin peer-to-peer protocol, for example the MSG_WTX inv type defined in ZIP 239 5, have taken the same approach to signalling.
  • -
  • No Network ID for Tor v2 onion addresses: the Tor network is expected to have removed support for these addresses in the timeframe for deployment of this ZIP.
  • -
  • Clients MUST, rather than SHOULD, reject addrv2 messages with more than 1,000 addresses. Making this a consistent requirement promotes interoperability.
  • -
  • Clients MUST NOT, rather than SHOULD NOT, gossip addresses from unknown networks.
  • -
  • Clients MUST, rather than SHOULD, reject messages that contain addresses that have a different length than specified for a known network ID, or a length greater than the 512-byte maximum for an unknown network ID.
  • -
-
-

Reference implementation

-

TBD.

-
-

Acknowledgements

-

This ZIP is closely based on BIP 155 3, written by Wladimir J. van der Laan. Zancas Wilcox ported the implementation for Zcashd.

-

Acknowledgements for BIP 155:

-
    -
  • Jonas Schnelli: change services field to CompactSize, to make the message more compact in the likely case instead of always using 8 bytes.
  • -
  • Gregory Maxwell: various suggestions regarding extensibility.
  • -
-
-

References

- - - - - - - -
1Information 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"
- - - - - - - -
2Zcash Protocol Specification, Version 2021.2.16 [NU5 proposal]. Section 3.12 Mainnet and Testnet
- - - - - - - -
3BIP 155: addrv2 message
- - - - - - - -
4ZIP 200: Network Upgrade Mechanism
- - - - - - - -
5ZIP 239: Relay of Version 5 Transactions
- - - - - - - -
6ZIP 252: Deployment of the NU5 Network Upgrade
- - - - - - - -
7Protocol documentation: addr. Bitcoin Wiki
- - - - - - - -
8Variable length integer. Bitcoin Wiki
- - - - - - - -
9Tor Rendezvous Specification - Version 3
- - - - - - - -
10NIST FIPS 202 - SHA-3 Standard: Permutation-Based Hash and Extendable-Output Functions
- - - - - - - -
11I2P: Naming and address book
- - - - - - - -
12Cjdns whitepaper: Pulling It All Together
-
-
- - \ No newline at end of file diff --git a/rendered/zip-0173.html b/rendered/zip-0173.html deleted file mode 100644 index 52e120c7a..000000000 --- a/rendered/zip-0173.html +++ /dev/null @@ -1,417 +0,0 @@ - - - - ZIP 173: Bech32 Format - - - -
-
ZIP: 173
-Title: Bech32 Format
-Owners: Daira-Emma Hopwood <daira-emma@electriccoin.co>
-Credits: Pieter Wuille <pieter.wuille@gmail.com>
-         Greg Maxwell <greg@xiph.org>
-         Rusty Russell
-         Mark Friedenbach
-Status: Final
-Category: Standards / Wallet
-Created: 2018-06-13
-License: MIT
-

Terminology

-

The key words "MUST", "MUST NOT", "SHOULD", and "SHOULD NOT" 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. 4

-

The term "Sapling" in this document is to be interpreted as described in ZIP 205. 5

-
-

Abstract

-

This document proposes a checksummed base32 format, "Bech32", and a standard for Sapling addresses and keys using it.

-
-

Motivation

-

Since launch, Zcash has relied on Base58 addresses with a truncated double-SHA256 checksum, inherited from Bitcoin. They were part of the original Bitcoin software and their scope was extended in BIP 13 6 for P2SH (Pay-to-Script-Hash) addresses. However, both the character set and the checksum algorithm have limitations:

-
    -
  • Base58 needs a lot of space in QR codes, as it cannot use the ''alphanumeric mode''.
  • -
  • The mixed case in Base58 makes it inconvenient to reliably write down, type on mobile keyboards, or read out loud.
  • -
  • The double-SHA256 checksum is slow and has no error-detection guarantees.
  • -
  • Most of the research on error-detecting codes only applies to character-set sizes that are a prime power, which 58 is not.
  • -
  • Base58 decoding is complicated and relatively slow.
  • -
-

To address these issues, Bitcoin adopted a new encoding called Bech32 7, for use with address types added by its Segregated Witness proposal. Zcash does not implement Segregated Witness, but it reuses Bech32 with address and key types introduced by the Sapling network upgrade 5.

-

Since the description of Bech32 in 7 is partially entangled with Segregated Witness address formats, we have found it clearer to write this ZIP to specify Bech32 separately. This specification should be read in conjunction with section 5.6 ("Encodings of Addresses and Keys") of the Zcash Sapling protocol specification 2, and with ZIP 32 which specifies additional key types for support of shielded hierarchical deterministic wallets 3.

-
-

Specification

-

We describe the general checksummed base32 format called ''Bech32''. Its use for Sapling payment addresses and keys is defined in the Sapling protocol specification 2.

-

A Bech32 string consists of:

-
    -
  • The human-readable part, which is intended to convey the type of data, or anything else that is relevant to the reader. This part MUST contain 1 to 83 US-ASCII characters, with each character having a value in the range [33-126]. HRP validity may be further restricted by specific applications.
  • -
  • The separator, which is always "1". In case "1" is allowed inside the human-readable part, the last one in the string is the separator.
  • -
  • The data part, which is at least 6 characters long and only consists of alphanumeric characters excluding "1", "b", "i", and "o".
  • -
- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
01234567
+0qpzry9x8
+8gf2tvdw0
+16s3jn54kh
+24ce6mua7l
-

Checksum

-

The last six characters of the data part form a checksum and contain no information. Valid strings MUST pass the criteria for validity specified by the Python3 code snippet below. The checksum is defined so that the function bech32_verify_checksum returns true when its arguments are:

-
    -
  • hrp: the human-readable part as a string;
  • -
  • data: the data part as a list of integers representing the characters after conversion using the table above.
  • -
-
def bech32_polymod(values):
-  GEN = [0x3b6a57b2, 0x26508e6d, 0x1ea119fa, 0x3d4233dd, 0x2a1462b3]
-  chk = 1
-  for v in values:
-    b = (chk >> 25)
-    chk = (chk & 0x1ffffff) << 5 ^ v
-    for i in range(5):
-    chk ^= GEN[i] if ((b >> i) & 1) else 0
-  return chk
-
-def bech32_hrp_expand(s):
-  return [ord(x) >> 5 for x in s] + [0] + [ord(x) & 31 for x in s]
-
-def bech32_verify_checksum(hrp, data):
-  return bech32_polymod(bech32_hrp_expand(hrp) + data) == 1
-

This implements a BCH code; in the case where the encoded string is at most 90 characters, this code guarantees detection of any error affecting at most 4 characters and has less than a 1 in 109 chance of failing to detect more errors. More details about the properties can be found in the Checksum Design section. The human-readable part is processed by first feeding the higher 3 bits of each character's US-ASCII value into the checksum calculation followed by a zero and then the lower 5 bits of each US-ASCII value.

-

To construct a valid checksum given the human-readable part and (non-checksum) values of the data-part characters, the code below can be used:

-
def bech32_create_checksum(hrp, data):
-  values = bech32_hrp_expand(hrp) + data
-  polymod = bech32_polymod(values + [0,0,0,0,0,0]) ^ 1
-  return [(polymod >> 5 * (5 - i)) & 31 for i in range(6)]
-

Error correction

-

One of the properties of these BCH codes is that they can be used for error correction. An unfortunate side effect of error correction is that it erodes error detection: correction changes invalid inputs into valid inputs, but if more than a few errors were made then the valid input may not be the correct input. Use of an incorrect but valid input can cause funds to be lost irrecoverably. Because of this, implementations SHOULD NOT implement correction beyond potentially suggesting to the user where in the string an error might be found, without suggesting the correction to make.

-
-

Uppercase/lowercase

-

The lowercase form is used when determining a character's value for checksum purposes.

-

Encoders MUST always output an all-lowercase Bech32 string. If an uppercase version of the encoding result is desired (e.g. for presentation purposes, or QR code use), then an uppercasing procedure can be performed external to the encoding process.

-

Decoders MUST NOT accept strings where some characters are uppercase and some are lowercase (such strings are referred to as mixed-case strings).

-

For presentation, lowercase is usually preferable, but inside QR codes uppercase SHOULD be used, as those permit the use of alphanumeric mode, which is 45% more compact than the byte mode that would otherwise be used.

-
-

Encoding

-
    -
  • Start with the bits of the raw encoding of the appropriate address or key type, most significant bit per byte first.
  • -
  • Re-arrange those bits into groups of 5, and pad with zeroes at the end if needed.
  • -
  • Translate those bits, most significant bit first, to characters using the table above.
  • -
-
-

Decoding

-

Software interpreting a Bech32-encoded address MUST first verify that the human-readable part matches that of a specified address type, and similarly for keys.

-

If this check passes, convert the rest of the data to bytes:

-
    -
  • Translate the values using the table above to 5 bits, most significant bit first.
  • -
  • Re-arrange those bits into groups of 8 bits. Any incomplete group at the end MUST be 4 bits or fewer, MUST be all zeroes, and is discarded.
  • -
  • The resulting groups are interpreted as the raw encoding of the appropriate address or key type, with the most significant bit first in each byte.
  • -
-

Decoders SHOULD enforce known-length restrictions on address and key types.

-

For example, 2 specifies that the length of the raw encoding of a Sapling payment address is 43 bytes (88 + 256 bits). This results in a Bech32-encoded Sapling payment address being 78 characters long.

-
-
-
-

Compatibility

-

Only software supporting the Sapling network upgrade is able to use these addresses.

-

There is no effect on support for transparent addresses and keys, or for Sprout z-addresses and keys; these will continue to be encoded using Base58Check, and MUST NOT be encoded using Bech32.

-
-

Rationale

-

Why use base32 at all?

-

The lack of mixed case makes it more efficient to read out loud or to put into QR codes. It does come with a 15% length increase. However, the length of a Bech32-encoded Sapling payment address remains below 80 characters, which reduces the likelihood of line splitting in terminals or email. Thus, cutting-and-pasting of addresses is still reliable.

-
-

Why call it Bech32?

-

"Bech" contains the characters BCH (the error detection algorithm used) and sounds a bit like "base". The term Bech32 is established for Bitcoin and there was no reason to use a different name for it in Zcash Sapling.

-
-

Why not support Bech32 encoding of Sprout or transparent addresses?

-

This was not considered to be sufficiently well-motivated given the compatibility issues that would arise from having two formats for these address types, with pre-Sapling software not supporting the new format.

-
-

Why include a separator in addresses?

-

That way the human-readable part is unambiguously separated from the data part, avoiding potential collisions with other human-readable parts that share a prefix. It also allows us to avoid having character-set restrictions on the human-readable part. The separator is ''1'' because using a non-alphanumeric character would complicate copy-pasting of addresses (with no double-click selection in several applications). Therefore an alphanumeric character outside the normal character set was chosen.

-
-

Why not use an existing base32 character set?

-

Existing character sets for base-32 encodings include RFC 3548 and z-base-32. The set used for Bech32 was chosen to minimize ambiguity according to this visual similarity data, and the ordering is chosen to minimize the number of pairs of similar characters (according to the same data) that differ in more than 1 bit. As the checksum is chosen to maximize detection capabilities for low numbers of bit errors, this choice improves its performance under some error models.

-
-

Why are the high bits of the human-readable part processed first?

-

This design choice had a rationale for Bitcoin Segregated Witness addresses (see 7) that does not apply to Zcash Sapling addresses. It is retained for compatibility with Bech32 encoders/decoders written for Bitcoin.

-
-
-

Reference implementations

- -

Note that the encoders written for Bitcoin may make assumptions specific to Segregated Witness address formats that do not apply to Zcash. Only the Python one has been tested with Zcash at the time of writing.

-
-

Examples

-

TODO: add valid Sapling payment addresses and keys, and their corresponding raw encodings.

-
-

Test vectors

-

The following strings are valid Bech32:

-
    -
  • A12UEL5L
  • -
  • a12uel5l
  • -
  • an83characterlonghumanreadablepartthatcontainsthenumber1andtheexcludedcharactersbio1tt5tgs
  • -
  • abcdef1qpzry9x8gf2tvdw0s3jn54khce6mua7lmqqqxw
  • -
  • 11qqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqc8247j
  • -
  • split1checkupstagehandshakeupstreamerranterredcaperred2y9e3w
  • -
  • ?1ezyfcl
  • -
-

The following strings are not valid Bech32 (with reason for invalidity):

-
    -
  • 0x20 + 1nwldj5: HRP character out of range
  • -
  • 0x7F + 1axkwrx: HRP character out of range
  • -
  • 0x80 + 1eym55h: HRP character out of range
  • -
  • pzry9x0s0muk: No separator character
  • -
  • 1pzry9x0s0muk: Empty HRP
  • -
  • x1b4n0q5v: Invalid data character
  • -
  • li1dgmt3: Too short checksum
  • -
  • de1lg7wt + 0xFF: Invalid character in checksum
  • -
  • A1G7SGD8: checksum calculated with uppercase form of HRP
  • -
  • 10a06t8: empty HRP
  • -
  • 1qzzfhee: empty HRP
  • -
  • bc1qw508d6qejxtdg4y5r3zarvary0c5xw7kv8f3t5: Invalid checksum
  • -
  • tb1qrp33g0q5c5txsp9arysrx4k6zdkfs4nce4xj0gdcccefvpysxf3q0sL5k7: Mixed case
  • -
  • bc1zw508d6qejxtdg4y5r3zarvaryvqyzf3du: Zero padding of more than 4 bits
  • -
  • tb1qrp33g0q5c5txsp9arysrx4k6zdkfs4nce4xj0gdcccefvpysxf3pjxtptv: Non-zero padding in 8-to-5 conversion
  • -
-
-

Checksum design

-

Design choices

-

BCH codes can be constructed over any prime-power alphabet and can be chosen to have a good trade-off between size and error-detection capabilities. Unlike Reed-Solomon codes, they are not restricted in length to one less than the alphabet size. While they also support efficient error correction, the implementation of just error detection is very simple.

-

We pick 6 checksum characters as a trade-off between length of the addresses and the error-detection capabilities, as 6 characters is the lowest number sufficient for a random failure chance below 1 per billion. For the length of data we're most interested in protecting (up to 77 bytes excluding the separator, for a Sapling payment address), BCH codes can be constructed that guarantee detecting up to 4 errors. Longer data is also supported with slightly weaker error detection.

-

Selected properties

-

Many of these codes perform badly when dealing with more errors than they are designed to detect, but not all. For that reason, we consider codes that are designed to detect only 3 errors as well as 4 errors, and analyse how well they perform in practice.

-

The specific code chosen here is the result of:

-
    -
  • Starting with an exhaustive list of 159605 BCH codes designed to detect 3 or 4 errors up to length 93, 151, 165, 341, 1023, and 1057.
  • -
  • From those, requiring the detection of 4 errors up to length 71, resulting in 28825 remaining codes.
  • -
  • From those, choosing the codes with the best worst-case window for 5-character errors, resulting in 310 remaining codes.
  • -
  • From those, picking the code with the lowest chance for not detecting small numbers of ''bit'' errors.
  • -
-

As a naive search would require over 6.5 * 1019 checksum evaluations, a collision-search approach was used for analysis. The code can be found here.

-
-

Properties

-

The following table summarizes the chances for detection failure (as multiples of 1 in 109).

- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
Window lengthNumber of wrong characters
LengthDescription≤45678≥9
8Longest detecting 6 errors01.1270.909n/a
18Longest detecting 5 errors00.9650.9290.9320.931
19Worst case for 6 errors00.0930.9720.9280.931
39Length ≤ 39 characters00.7560.9350.9320.931
59Length ≤ 59 characters00.8050.9330.931
71Length ≤ 71 characters00.8300.9340.931
89Longest detecting 4 errors00.8670.9330.931
-

TODO: fill in table for a Sapling payment address, and check the following paragraph.

-

This means that when 5 changed characters occur randomly distributed in the 77 characters (excluding the separator) of a Sapling payment address, there is a chance of at most 0.867 per billion that it will go undetected. When those 5 changes occur randomly within a 19-character window, that chance goes down to 0.093 per billion. As the number of errors goes up, the chance converges towards 1 in 230 = 0.931 per billion.

-

The chosen code performs reasonably well up to 1023 characters, but is best for lengths up to 89 characters (excluding the separator). Since the search for suitable codes was based on the requirements for Bitcoin P2WPKH and P2WSH addresses, it is not quite optimal for the address lengths used by Sapling, but the advantages of compatibility with existing Bitcoin libraries were considered to outweigh this consideration.

-
-
-
-

Acknowledgements

-

This document is closely based on BIP 173 written by Pieter Wuille and Greg Maxwell, which was inspired by the address proposal by Rusty Russell and the base32 proposal by Mark Friedenbach. BIP 173 also had input from Luke Dashjr, Johnson Lau, Eric Lombrozo, Peter Todd, and various other reviewers.

-
-

References

- - - - - - - -
1Information 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"
- - - - - - - -
2Zcash Protocol Specification, Version 2021.2.16 or later
- - - - - - - -
3ZIP 32: Shielded Hierarchical Deterministic Wallets
- - - - - - - -
4ZIP 200: Network Upgrade Mechanism
- - - - - - - -
5ZIP 205: Deployment of the Sapling Network Upgrade
- - - - - - - -
6BIP 13: Address Format for pay-to-script-hash
- - - - - - - -
7BIP 173: Base32 address format for native v0-16 witness outputs
-
-
- - \ No newline at end of file diff --git a/rendered/zip-0200.html b/rendered/zip-0200.html deleted file mode 100644 index 6e5259b96..000000000 --- a/rendered/zip-0200.html +++ /dev/null @@ -1,176 +0,0 @@ - - - - ZIP 200: Network Upgrade Mechanism - - - -
-
ZIP: 200
-Title: Network Upgrade Mechanism
-Owners: Jack Grigg <str4d@electriccoin.co>
-Status: Final
-Category: Consensus
-Created: 2018-01-08
-License: MIT
-

Terminology

-

The key words "MUST", "SHOULD", "SHOULD NOT", 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 terms below are to be interpreted as follows:

-
-
Block chain
-
A sequence of blocks starting at the genesis block, where the header of each block refers to the previous block in the sequence.
-
Consensus rule set
-
A set of validation rules that determine which block chains are considered valid.
-
Consensus rule change
-
A change in the consensus rule set of the network, such that nodes that do not recognize the new rules will follow a different block chain.
-
Consensus branch
-
A block chain with a common consensus rule set, where the first block in the chain is either the genesis block, or the child of a parent block created under an older set of consensus rules (i.e. the parent block is a member of a different consensus branch). By definition, every block belongs to at most one consensus branch.
-
Network upgrade
-
An intentional consensus rule change undertaken by the community in order to improve the network.
-
-
-

Abstract

-

This proposal defines a mechanism for coordinating upgrades of the Zcash network, in order to remove ambiguity about when network upgrades will activate, provide defined periods in which users should upgrade their local software, and minimize the risks to both the upgrading network and any users opting out of the changes.

-
-

Motivation

-

Zcash is a consensual currency: nobody is ever going to force someone to use a specific software implementation or a specific consensus branch of Zcash. 2 As such, different sub-communities will always have the freedom to choose different variants or branches which offer different design trade-offs.

-

The current Zcash software includes an End-of-Service halt feature, causing nodes running a particular version to automatically shut down approximately 16 weeks after that version was released (specifically, at the block height DEPRECATION_HEIGHT defined in the source code for that version). This was implemented for several reasons: 3

-
    -
  • It gives the same systemic advantage of removing old software as auto-upgrade behavior.
  • -
  • It requires users to individually choose one of the following options: -
      -
    • Upgrade to a more recent software release from the main network.
    • -
    • Upgrade to an alternative release.
    • -
    • Modify their node in order to keep running the older software.
    • -
    -
  • -
-

Developers can rely on this cadence for coordinating network upgrades. Once the last pre-upgrade software version has been deprecated, they can reasonably assume that all node operators on the network either support the upgraded rules, or have explicitly chosen not to follow them.

-

However, this behaviour is not sufficient for performing network upgrades. A globally-understood on-chain activation mechanism is necessary so that nodes can unambiguously know at what point the changes from an upgrade come into effect (and can enforce consensus rule changes, for example).

-
-

Specification

-

The following constants are defined for every network upgrade:

-
-
CONSENSUS_BRANCH_ID
-
-

A globally-unique non-zero 32-bit identifier.

-

Implementations MAY use a value of zero in consensus branch ID fields to indicate the absence of any upgrade (i.e. that the Sprout consensus rules apply).

-
-
ACTIVATION_HEIGHT
-
-

The non-zero block height at which the network upgrade rules will come into effect, and be enforced as part of the block chain consensus.

-

For removal of ambiguity, the block at height ACTIVATION_HEIGHT - 1 is subject to the pre-upgrade consensus rules, and would be the last common block in the event of a persistent pre-upgrade consensus branch.

-

It MUST be greater than the value of DEPRECATION_HEIGHT in the last software version that will not contain support for the network upgrade. It SHOULD be chosen to be reached approximately three months after the first software version containing support for the network upgrade is released, for the following reason:

-
    -
  • As of the time of writing (the 1.0.15 release), the release cycle is six weeks long, and nodes undergo End-of-Service halt 16 weeks after release. Thus, if version X contains support for a network upgrade, version X-1 will be deprecated 10 weeks after the release of version X, which is about 2.3 months. A three-month window provides ample time for users to upgrade their nodes after End-of-Service halt, and re-integrate into the network prior to activation of the network upgrade.
  • -
-
-
-

The relationship between CONSENSUS_BRANCH_ID and ACTIVATION_HEIGHT is many-to-one: it is possible for many distinct consensus branches to descend from the same parent block (and thus have the same ACTIVATION_HEIGHT), but a specific consensus branch can only have one parent block. Concretely, this means that if the ACTIVATION_HEIGHT of a network upgrade is changed for any reason (e.g. security vulnerabilities or consensus bugs are discovered), the CONSENSUS_BRANCH_ID MUST also be changed.

-

Activation mechanism

-

The Zcash block chain is broken into "epochs" of block height intervals [ACTIVATION_HEIGHT_N, ACTIVATION_HEIGHT_{N+1}) (i.e. including ACTIVATION_HEIGHT_N and excluding ACTIVATION_HEIGHT_{N+1}), on which consensus rule sets are defined.

-

When a consensus rule depends on activation of a particular upgrade, its implementation (and that of any network behavior or surrounding code that depends on it) MUST be gated by a block height check. For example:

-
if (CurrentEpoch(chainActive.Height(), Params().GetConsensus()) == Consensus::UPGRADE_OVERWINTER) {
-    // Overwinter-specific logic
-} else {
-    // Non-Overwinter logic
-}
-
-// ...
-
-if (NetworkUpgradeActive(pindex->nHeight, Params().GetConsensus(), Consensus::UPGRADE_OVERWINTER)) {
-    // Overwinter consensus rules applied to block
-} else {
-    // Pre-Overwinter consensus rules applied to block
-}
-

Block validation

-

Incoming blocks known to have a particular height (due to their parent chain being entirely known) MUST be validated under the consensus rules corresponding to the expected consensus branch ID for that height.

-

Incoming blocks with unknown heights (because at least one block header in their parent chain is unknown) MAY be cached, so that they can be reconsidered in the future after all their parents have been received.

-
-

Chain reorganization

-

It is possible for a reorganization to occur that rolls back from after the activation height, to before that height. This can be handled in the same way as any regular chain orphaning or reorganization, as long as the new chain is valid.

-
-

Post-activation upgrading

-

If a user does not upgrade their node to a compatible software version before ACTIVATION_HEIGHT is reached, and the node continues running (which could normally only occur if the End-of-Service halt were bypassed), then the node will follow any pre-upgrade consensus branch that persists. In this case it may download blocks that are incompatible with the post-upgrade consensus branch. If the user subsequently upgrades their node to a compatible software version, the node will consider these blocks to be invalid, and if there are a significant number of invalid blocks it SHOULD shut down and alert the user of the issue.

-
-
-

Memory pool

-

While the current chain tip height is below ACTIVATION_HEIGHT, nodes SHOULD NOT accept transactions that will only be valid on the post-upgrade consensus branch.

-

When the current chain tip height reaches ACTIVATION_HEIGHT, the node's local transaction memory pool SHOULD be cleared of transactions that will never be valid on the post-upgrade consensus branch.

-
-

Two-way replay protection

-

Before the Overwinter network upgrade, two-way replay protection is ensured by enforcing post-upgrade that the most significant bit of the transaction version is set to 1. 6 From the perspective of old nodes, the transactions will have a negative version number, which is invalid under the old consensus rules. Enforcing this rule trivially makes old transactions invalid on the Overwinter consensus branch.

-

After the Overwinter network upgrade, two-way replay protection is ensured by transaction signatures committing to a specific CONSENSUS_BRANCH_ID. 4

-
-

Wipe-out protection

-

Nodes running upgrade-aware software versions will enforce the upgraded consensus rules from ACTIVATION_HEIGHT. The chain from that height will not reorganize to a pre-upgrade consensus branch if any block in that consensus branch would violate the new consensus rules.

-

Care must be taken, however, to account for possible edge cases where the old and new consensus rules do not differ. For example, if the non-upgraded chain only contained empty blocks from ACTIVATION_HEIGHT, and the coinbase transactions were valid under both the old and new consensus rules, a wipe-out could occur. The Overwinter network upgrade is not susceptible to this because all previous transaction versions will become invalid, meaning that the coinbase transactions must use the newer transaction version. More generally, this issue could be addressed in a future network upgrade by modifying the block header to include a commitment to the CONSENSUS_BRANCH_ID.

-
-
-

Deployment

-

This proposal will be deployed with the Overwinter network upgrade. 5

-
-

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.

-
-

Reference Implementation

-

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

-
-

References

- - - - - - - -
1Information 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"
- - - - - - - -
2Consensual Currency. Electric Coin Company blog
- - - - - - - -
3 - -
- - - - - - - -
4ZIP 143: Transaction Signature Validation for Overwinter
- - - - - - - -
5ZIP 201: Network Peer Management for Overwinter
- - - - - - - -
6ZIP 202: Version 3 Transaction Format for Overwinter
-
-
- - \ No newline at end of file diff --git a/rendered/zip-0201.html b/rendered/zip-0201.html deleted file mode 100644 index d7a384f7a..000000000 --- a/rendered/zip-0201.html +++ /dev/null @@ -1,271 +0,0 @@ - - - - ZIP 201: Network Peer Management for Overwinter - - - -
-
ZIP: 201
-Title: Network Peer Management for Overwinter
-Owners: Daira-Emma Hopwood <daira-emma@electriccoin.co>
-Original-Authors: Simon Liu
-Status: Final
-Category: Network
-Created: 2018-01-15
-License: MIT
-

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 terms "consensus branch" and "network upgrade" in this document are to be interpreted as described in ZIP 200. 3

-

The terms below are to be interpreted as follows:

-
-
Overwinter
-
Code-name for the first Zcash network upgrade, also known as Network Upgrade Zero.
-
-
-

Abstract

-

This proposal defines an upgrade to the network handshake and peer management required for network upgrades following the Network Upgrade Mechanism 3.

-

Related to:

-
    -
  • Transaction Signature Validation for Overwinter 2.
  • -
  • Version 3 Transaction Format for Overwinter 4.
  • -
  • Transaction Expiry 5.
  • -
-
-

Motivation

-

With scheduled network upgrades, at the activation height, nodes on each consensus branch should disconnect from nodes on other consensus branches and only accept new incoming connections from nodes on the same consensus branch.

-
-

Specification

-

When a new inbound connection is received or an outbound connection created, a CNode object is instantiated with the version field set to INIT_PROTO_VERSION which has a value of 209. This value is not transmitted across the network, but for legacy reasons and technical debt beyond the scope of this ZIP, this value will not be changed.

-

Once the two nodes have connected and started the handshake to negotiate the protocol version, the version field of CNode will be updated. The handshake 8 involves "version" and "verack" messages being exchanged.:

-
L -> R: Send version message with the local peer's version
-R -> L: Send version message back
-R -> L: Send verack message
-R:      Sets version to the minimum of the 2 versions
-L -> R: Send verack message after receiving version message from R
-L:      Sets version to the minimum of the 2 versions
-

To send a version message, the node will invoke PushVersion():

-
void CNode::PushVersion() {
-    ...
-    PushMessage("version", PROTOCOL_VERSION, nLocalServices, nTime, addrYou, addrMe, ...);
-    ...
-}
-

where PROTOCOL_VERSION is the highest protocol version supported by the node.

-

Rejecting Pre-Overwinter Connections

-

Currently, nodes will reject connections from peers with an advertised protocol version lower than the other node's minimum supported protocol version.

-

This value is defined as:

-
//! disconnect from peers older than this proto version
-static const int MIN_PEER_PROTO_VERSION = 170002;
-

With rejection implemented as:

-
if (pfrom->nVersion < MIN_PEER_PROTO_VERSION)
-{
-    // disconnect from old peers running protocol version we don't support.
-

Activation of Overwinter will take place first on testnet, and if successful, followed by mainnet.

-

To prepare for testnet activation, Overwinter nodes will contain the following constants:

-
static const int PROTOCOL_VERSION = 170003;
-static const int MIN_PEER_PROTO_VERSION = 170002;
-

Nodes running protocol version 170003 have a testnet activation height set, but do not have a mainnet activation height set.

-

On testnet, a pre-Overwinter node is defined to be a node for which the highest supported protocol version is <= 170002.

-

These constants allow pre-Overwinter nodes that support protocol version 170002, and Overwinter nodes (which support both protocol versions 170002 and 170003 before Overwinter activation) to remain connected until the activation.

-

To prepare for mainnet activation, Overwinter nodes will contain the following constants:

-
static const int PROTOCOL_VERSION = 170005;
-static const int MIN_PEER_PROTO_VERSION = 170002;
-

On mainnet, a pre-Overwinter node is defined to be a node for which the highest supported protocol version is <= 170004. (Nodes running protocol version 170003 or 170004 do not have a mainnet activation height set. The intermediate protocol version 170004 is used to indicate support for the NODE_BLOOM service bit defined in 6.)

-

These constants allow pre-Overwinter nodes that support protocol versions 170002 to 170004 inclusive, and Overwinter nodes (which support protocol versions 170002 to 170005 inclusive before Overwinter activation) to remain connected until the activation.

-

As these constants cannot be changed at run-time, once Overwinter activates on testnet or mainnet, Overwinter nodes should take steps to:

-
    -
  • reject new connections from pre-Overwinter nodes;
  • -
  • disconnect any existing connections to pre-Overwinter nodes.
  • -
-
-

Network Coalescence

-

Prior to the activation of Overwinter, nodes running a pre-Overwinter protocol version (e.g. 170002) and the Overwinter protocol version (170003 for testnet; 170005 for mainnet) remain connected with the same consensus rules, but it is desirable for nodes supporting Overwinter to connect preferentially to other nodes supporting Overwinter.

-

This is intended to help the network partition smoothly, since nodes should already be connected to (a majority of) peers running the same protocol version. Otherwise an Overwinter node may find their connections to Sprout nodes dropped suddenly at the activation height, potentially leaving them isolated and susceptible to eclipse attacks. 9

-

To assist network coalescence before the activation height, we update the eviction process to place a higher priority on evicting Sprout nodes.

-

Currently, an eviction process takes place when new inbound connections arrive, but the node has already connected to the maximum number of inbound peers:

-
if (nInbound >= nMaxInbound)
-{
-    if (!AttemptToEvictConnection(whitelisted)) {
-        // No connection to evict, disconnect the new connection
-        LogPrint("net", "failed to find an eviction candidate - connection dropped (full)\n");
-        CloseSocket(hSocket);
-        return;
-    }
-}
-

We update this process by adding behaviour so that the set of eviction candidates will prefer pre-Overwinter nodes, when the chain tip is in a period N blocks before the activation block height, where N is defined as:

-
/** The period before a network upgrade activates, where connections to upgrading peers are preferred (in blocks). */
-static const int NETWORK_UPGRADE_PEER_PREFERENCE_BLOCK_PERIOD = 24 * 24 * 3;
-

The eviction candidates can be modified as so:

-
static bool AttemptToEvictConnection(bool fPreferNewConnection) {
-...
-// Protect connections with certain characteristics
-...
-// Check version of eviction candidates...
-// If we are connected to any pre-Overwinter nodes, keep them in the eviction set and remove any Overwinter nodes
-// If we are only connected to Overwinter nodes, continue with existing behaviour.
-if (nActivationHeight > 0 &&
-    height < nActivationHeight &&
-    height >= nActivationHeight - NETWORK_UPGRADE_PEER_PREFERENCE_BLOCK_PERIOD)
-{
-    // Find any nodes which don't support Overwinter protocol version
-    BOOST_FOREACH(const CNodeRef &node, vEvictionCandidates) {
-        if (node->nVersion < params.vUpgrades[Consensus::UPGRADE_OVERWINTER].nProtocolVersion) {
-            vTmpEvictionCandidates.push_back(node);
-        }
-    }
-
-    // Prioritize these nodes by replacing eviction set with them
-    if (vTmpEvictionCandidates.size() > 0) {
-        vEvictionCandidates = vTmpEvictionCandidates;
-    }
-}
-

The existing method of disconnecting a candidate remains:

-
-

vEvictionCandidates[0]->fDisconnect = true;

-
-

The existing eviction process will classify and divide eviction candidates into buckets called netgroups. If a netgroup only has one peer, it will not be evicted. This means at least one pre-Overwinter node will remain connected upto the activation block height, barring any network issues or a high ban score.

-
-

Disconnecting Existing Connections

-

At the activation block height, an Overwinter node may still remain connected to pre-Overwinter nodes. Currently, when connecting, a node can only perform the networking handshake once, where it sends the version message before any other messages are processed. To disconnect existing pre-Overwinter connections, ProcessMessage is modified so that once Overwinter activates, if necessary, the protocol version of an existing peer is validated when inbound messages arrive.

-

Example code:

-
bool static ProcessMessage(CNode* pfrom, string strCommand, CDataStream& vRecv, int64_t nTimeReceived)
-    ...
-    else if (pfrom->nVersion == 0)
-    {
-        // Must have a version message before anything else
-        Misbehaving(pfrom->GetId(), 1);
-        return false;
-    }
-    else if (strCommand == "verack")
-    {
-        ...
-    }
-
-    // Disconnect existing peer connection when:
-    // 1. The version message has been received
-    // 2. Overwinter is active
-    // 3. Peer version is pre-Overwinter
-    else if (NetworkUpgradeActive(GetHeight(), chainparams.GetConsensus(), Consensus::UPGRADE_OVERWINTER)
-            && (pfrom->nVersion < chainparams.GetConsensus().vUpgrades[Consensus::UPGRADE_OVERWINTER].nProtocolVersion))
-    {
-        LogPrintf("peer=%d using obsolete version %i; disconnecting\n", pfrom->id, pfrom->nVersion);
-        pfrom->PushMessage("reject", strCommand, REJECT_OBSOLETE,
-                            strprintf("Version must be %d or greater",
-                            chainparams.GetConsensus().vUpgrades[Consensus::UPGRADE_OVERWINTER].nProtocolVersion));
-        pfrom->fDisconnect = true;
-        return false;
-    }
-
-
-

Deployment of Overwinter

-

The Overwinter network upgrade defines the following network upgrade constants 3:

-
-
CONSENSUS_BRANCH_ID
-
0x5ba81b19
-
ACTIVATION_HEIGHT
-
-

Testnet: 207500

-

Mainnet: 347500

-
-
-

The following ZIPs are deployed by Overwinter:

-
    -
  • ZIP 200 3
  • -
  • ZIP 201 (this ZIP)
  • -
  • ZIP 202 4
  • -
  • ZIP 203 5
  • -
  • ZIP 143 2
  • -
-
-

Backward compatibility

-

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

-

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

-
-

Reference Implementation

-

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

-
-

References

- - - - - - - -
1Information 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"
- - - - - - - -
2ZIP 143: Transaction Signature Validation for Overwinter
- - - - - - - -
3ZIP 200: Network Upgrade Mechanism
- - - - - - - -
4ZIP 202: Version 3 Transaction Format for Overwinter
- - - - - - - -
5ZIP 203: Transaction Expiry
- - - - - - - -
6BIP 111: NODE_BLOOM service bit
- - - - - - - -
7https://en.bitcoin.it/wiki/Protocol_documentation#version
- - - - - - - -
8https://en.bitcoin.it/wiki/Version_Handshake
- - - - - - - -
9Eclipse Attacks on Bitcoin’s Peer-to-Peer Network
- - - - - - - -
10Partition nodes with old protocol version from network in advance of hard fork
-
-
- - \ No newline at end of file diff --git a/rendered/zip-0202.html b/rendered/zip-0202.html deleted file mode 100644 index 43a4a2cf3..000000000 --- a/rendered/zip-0202.html +++ /dev/null @@ -1,377 +0,0 @@ - - - - ZIP 202: Version 3 Transaction Format for Overwinter - - - -
-
ZIP: 202
-Title: Version 3 Transaction Format for Overwinter
-Owners: Daira-Emma Hopwood <daira-emma@electriccoin.co>
-Original-Authors: Simon Liu
-Status: Final
-Category: Consensus
-Created: 2018-01-10
-License: MIT
-

Terminology

-

The key words "MUST", "MUST NOT", 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 terms "consensus branch", "network upgrade", and "consensus rule change" in this document are to be interpreted as described in ZIP 200. 3

-

The term "Overwinter" in this document is to be interpreted as described in ZIP 201. 4

-
-

Abstract

-

This proposal defines a new transaction format required for Network Upgrade Mechanism 3 and Transaction Expiry 5.

-
-

Motivation

-

Zcash launched with support for upstream Bitcoin version 1 transactions and defined a new version 2 transaction format which added fields required for shielded transactions.

- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
VersionFieldDescriptionType
>= 1versionpositive valueint32
>= 1tx_in_countvariable-length integercompactSize
>= 1tx_inlist of inputsvector
>= 1tx_out_countvariable-length integercompactSize
>= 1tx_outlist of outputsvector
>= 1lock_timeblock height or timestampuint32
>= 2nJoinSplitvariable-length integercompactSize
>= 2vJoinSplitlist of joinsplitsvector
>= 2joinSplitPubKeyjoinsplit_sig public key32 bytes
>= 2joinSplitSigsignature64 bytes
-

A new transaction format is required to:

-
    -
  • support safe network upgrades as specified in Network Upgrade Mechanism 3;
  • -
  • provide replay protection between pre-Overwinter and Overwinter consensus branches during upgrades;
  • -
  • provide replay protection between different consensus branches post-Overwinter;
  • -
  • enable a consensus branch to support multiple transaction version formats;
  • -
  • ensure transaction formats are parsed uniquely across parallel consensus branches;
  • -
  • support transaction expiry 5.
  • -
-
-

Specification

-

Transaction format version 3

-

A new version 3 transaction format will be introduced for Overwinter.

-

The version 3 format differs from the version 2 format in the following ways:

-
    -
  • header (first four bytes, little-endian encoded) -
      -
    • fOverwintered flag : bit 31, must be set
    • -
    • nVersion : bits 30-0, positive integer
    • -
    -
  • -
  • nVersionGroupId
  • -
  • nExpiryHeight
  • -
- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
VersionFieldDescriptionType
>= 3header -

contains:

-
    -
  • fOverwintered flag (bit 31, always set)
  • -
  • nVersion (bits 30-0)
  • -
-
uint32
>= 3nVersionGroupIdversion group ID (not zero)uint32
>= 1tx_in_countvariable-length integercompactSize
>= 1tx_inlist of inputsvector
>= 1tx_out_countvariable-length integercompactSize
>= 1tx_outlist of outputsvector
>= 1lock_timeblock height or timestampuint32
>= 3expiryHeightblock heightuint32
>= 2nJoinSplitvariable-length integercompactSize
>= 2vJoinSplitlist of joinsplitsvector
>= 2joinSplitPubKeyjoinsplit_sig public key32 bytes
>= 2joinSplitSigsignature64 bytes
-
-

Header Field

-

The first four bytes of pre-Overwinter and Overwinter transactions are little-endian encoded.

-

Version 1 transaction (txid 5c6ba844e1ca1c8083cd53e29971bd82f1f9eea1f86c1763a22dd4ca183ae061)

-
    -
  • begins with little-endian byte sequence [0x01, 0x00, 0x00, 0x00];
  • -
  • deserialized as 32-bit signed integer with decimal value of 1.
  • -
-

Version 2 transaction (txid 4435bf8064e74f01262cb1725fd9b53e600fa285950163fd961bed3a64260d8b)

-
    -
  • begins with little-endian byte sequence [0x02, 0x00, 0x00, 0x00];
  • -
  • deserialized as 32-bit signed integer with decimal value of 2.
  • -
-

Transaction parsers for versions of Zcash prior to Overwinter, and for most other Bitcoin forks, require the transaction version number to be positive.

-

With the version 3 transaction format, the first four bytes of a serialized transaction, the 32-bit header, are made up of two fields as shown in the table above:

-
    -
  • 1-bit fOverwintered flag, must be set;
  • -
  • 31-bit unsigned int for the version.
  • -
-

Pre-Overwinter parsers will deserialize these four bytes as a 32-bit signed integer. With two's complement integers, the most significant bit indicates whether an integer is positive or negative. With the Overwinter flag set, the transaction version will be negative, resulting in pre-Overwinter parsers rejecting the transaction as invalid. This provides transaction replay protection between pre-Overwinter and Overwinter software.

-

Consider the following example of a serialized version 3 transaction.

-

Pre-Overwinter parser:

-
    -
  • data begins with little-endian byte sequence: [0x03, 0x00, 0x00, 0x80];
  • -
  • deserialized as 32-bit signed integer. -
      -
    • with hexadecimal value of 0x80000003 (most significant bit is set);
    • -
    • decimal value of -2147483645.
    • -
    -
  • -
-

Legacy parsers will expect the version to be a positive value, such as 1 or 2, and will thus reject the Overwinter transaction as invalid.

-

Overwinter parser:

-
    -
  • data begins with little-endian byte sequence: [0x03, 0x00, 0x00, 0x80];
  • -
  • deserialized as 32-bit unsigned integer -
      -
    • with binary value of 0b10000000000000000000000000000011;
    • -
    -
  • -
  • the 32-bits are decomposed into two fields: -
      -
    • fOverwintered flag (bit 31) as a boolean, expected to be set;
    • -
    • version (bits 30 - bit 0) as an unsigned integer, expected to have a decimal value of 3.
    • -
    -
  • -
-

Overwinter parsers will accept the transaction as valid as the most significant bit of the header has been set. By masking off (unsetting) the most significant bit, the parser can retrieve the transaction version number:

-
0x80000003 & 0x7FFFFFFF = 0x00000003 = 3
-
-

Version Group ID

-

The version group ID is a non-zero, random and unique identifier, of type uint32, assigned to a transaction format version, or a group of soft-forking transaction format versions. The version group ID helps nodes disambiguate between consensus branches using the same version number.

-

That is, it prevents a client on one branch of the network from attempting to parse transactions intended for another consensus branch, in the situation where the transactions share the same format version number but are actually specified differently. For example, Zcash and a clone of Zcash might both define their own custom v3 transaction formats, but each will have its own unique version group ID, so that they can reject v3 transactions with unknown version group IDs.

-

The combination of transaction version and version group ID, nVersion || nVersionGroupId, uniquely defines the transaction format, thus enabling parsers to reject transactions from outside the client's chain which cannot be parsed.

-

By convention, it is expected that when introducing a new transaction version requiring a network upgrade, a new unique version group ID will be assigned to that transaction version.

-

However, if a new transaction version can be correctly parsed according to the format of a preceding version (that is, it only restricts the format, or defines fields that were previously reserved and which old parsers can safely ignore), then the same version group ID MAY be re-used.

-
-

Expiry Height

-

The expiry height field, as defined in the Transaction Expiry ZIP 5, stores the block height after which a transaction can no longer be mined.

-
-

Transaction Validation

-

A valid Overwinter transaction intended for Zcash MUST have:

-
    -
  • version number 3; and
  • -
  • version group ID 0x03C48270; and
  • -
  • fOverwintered flag set.
  • -
-

Overwinter validators MUST reject transactions for violating consensus rules if:

-
    -
  • the fOverwintered flag is not set; or
  • -
  • the version group ID is unknown; or
  • -
  • the version number is unknown.
  • -
-

Validation of version 3 transactions MUST use the signature validation process detailed in the Transaction Signature Validation for Overwinter ZIP 2.

-
-
-

Implementation

-

The comments and code samples in this section apply to the reference C++ implementation of Zcash. Other implementations may vary.

-

Transaction Version

-

Transaction version remains a positive value. The main Zcash chain will follow convention and continue to order transaction versions in an ascending order.

-

Tests can continue to check for the existence of forwards-compatible transaction fields by checking the transaction version using comparison operators:

-
if (tx.nVersion >= 2) {
-    for (int js = 0; js < joinsplits; js++) {
-        ...
-    }
-}
-

When (de)serializing v3 transactions, the version group ID must also be checked in case the transaction is intended for a consensus branch which has a different format for its version 3 transaction:

-
if (tx.nVersion == 3 && tx.nVersionGroupId == OVERWINTER_VERSION_GROUP_ID) {
-    auto expiryHeight = tx.nExpiryHeight;
-}
-

Tests can continue to set the version to zero as an error condition:

-
mtx.nVersion = 0
-
-

Overwinter Validation

-

To test if the format of an Overwinter transaction is v3 or not:

-
if (tx.fOverwintered && tx.nVersion == 3) {
-    // Valid v3 format transaction
-}
-

This only tests that the format of the transaction matches the v3 specification described above.

-

To test if the format of an Overwinter transaction is both v3 and the transaction itself is intended for the client's chain:

-
if (tx.fOverwintered &&
-    tx.nVersionGroupId == OVERWINTER_VERSION_GROUP_ID) &&
-    tx.nVersion == 3) {
-    // Valid v3 format transaction intended for this client's chain
-}
-

It is expected that this test involving nVersionGroupId is only required when a transaction is being constructed or deserialized e.g. when an external transaction enters the system.

-

However, it's possible that a clone of Zcash is using the same version group ID and passes the conditional.

-

Ultimately, a client can determine if a transaction is truly intended for the client's chain or not by following the signature validation process detailed in the Transaction Signature Validation for Overwinter ZIP 2.

-
-
-

Deployment

-

This proposal will be deployed with the Overwinter network upgrade. The activation block height proposal is in 4.

-
-

Backwards compatibility

-

This proposal intentionally creates what is known as a "bilateral consensus rule change" 3 between pre-Overwinter software and Overwinter-compatible software. Use of this new transaction format requires that all network participants upgrade their software to a compatible version within the upgrade window. Pre-Overwinter software will treat Overwinter transactions as invalid.

-

Once Overwinter has activated, Overwinter-compatible software will reject version 1 and version 2 transactions, and will only accept transactions based upon supported transaction version numbers and recognized version group IDs.

-
-

Reference Implementation

-

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

-
-

References

- - - - - - - -
1Information 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"
- - - - - - - -
2ZIP 143: Transaction Signature Validation for Overwinter
- - - - - - - -
3ZIP 200: Network Upgrade Mechanism
- - - - - - - -
4ZIP 201: Network Handshaking for Overwinter
- - - - - - - -
5ZIP 203: Transaction Expiry
-
-
- - \ No newline at end of file diff --git a/rendered/zip-0203.html b/rendered/zip-0203.html deleted file mode 100644 index 074d62c7d..000000000 --- a/rendered/zip-0203.html +++ /dev/null @@ -1,114 +0,0 @@ - - - - ZIP 203: Transaction Expiry - - - - -
-
ZIP: 203
-Title: Transaction Expiry
-Owners: Daira-Emma Hopwood <daira-emma@electriccoin.co>
-Original-Authors: Jay Graber
-Status: Final
-Category: Consensus
-Created: 2018-01-09
-License: MIT
-

Abstract

-

This is a Standards ZIP describing a new consensus rule to set an expiration time after which a transaction cannot be mined. If it is not mined within that time, the transaction will be removed from nodes' mempools.

-
-

Motivation

-

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\) - , 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\) - , and blocks that include expired transactions will not be considered valid.

-
-

Specification

-

Transactions will have a new field, nExpiryHeight, which will set the block height after which transactions will be removed from the mempool if they have not been mined.

-

The data type for nExpiryHeight will be uint32_t. nExpiryHeight will never be a UNIX timestamp, unlike nLockTime values, and thus the maximum expiry height will be 499999999 (but see the exception for coinbase transactions described in Changes for NU5).

-

Note: a previous version of this ZIP incorrectly specified an interaction between nExpiryHeight and nLockTime that was never implemented.

-

For the example below, the last block that the transaction below could possibly be included in is 3539. After that, it will be removed from the mempool.

-
"txid": "17561b98cc77cd5a984bb959203e073b5f33cf14cbce90eb32b95ae2c796723f",
-"version": 3,
-"locktime": 2089,
-"expiryheight": 3539,
-

Default: (Before Blossom) 20 blocks from the current height, or about 50 minutes at 2.5-minute target block spacing. A configuration option can be used to set the user's default.

-

Minimum: No minimum

-

Maximum: 499999999, which is about 1185 years from now at 75 seconds/block.

-

No limit: To set no limit on transactions (so that they do not expire), nExpiryHeight should be set to 0.

-

Coinbase: nExpiryHeight on coinbase transactions is ignored, and is set to 0 by convention.

-

Every time a transaction expires and should be removed from the mempool, so should all of its dependent transactions.

-

Changes for Blossom

-

On Blossom activation 2, the default changes to 40 blocks from the current height, which still represents about 50 minutes at the revised 75-second target block spacing.

-
-

Changes for NU5

-

As mentioned above, nExpiryHeight is ignored for coinbase transactions. However, from NU5 activation 3, the nExpiryHeight field of a coinbase transaction MUST be set equal to the block height. Also, for coinbase transactions only, the bound of 499999999 on nExpiryHeight is removed. The motivation is to ensure that transaction IDs remain unique, as explained in more detail in a note in Section 7.1 of the protocol specification 4.

-
-

Wallet behavior and UI

-

With the addition of this feature, zero-confirmation transactions with an expiration block height set will have even less guarantee of inclusion. This means that UIs and services must never rely on zero-confirmation transactions in Zcash.

-

Wallet should notify the user of expired transactions that must be re-sent.

-
-

RPC

-

For Overwinter, transaction expiry will be set to a default that can be overridden by a flag txexpirydelta set in the config file.

-

-txexpirydelta= set the number of blocks after which a transaction that has not been mined will become invalid

-

To view: listtransactions has a new filter attribute, showing expired transactions only:

-
listtransactions "*" 10 0 "expired"
-

WalletTxToJSON shows a boolean expired true/false.

-
-

Config

-

The default will be user-configurable with the option txexpirydelta.

-

--txexpirydelta=100

-
-

Deployment

-

This feature will be deployed with Overwinter. The activation blockheight proposal is in 1.

-
-
-

Reference Implementation

-

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

-
-

References

- - - - - - - -
1ZIP 201: Network Peer Management for Overwinter
- - - - - - - -
2ZIP 206: Deployment of the Blossom Network Upgrade
- - - - - - - -
3ZIP 252: Deployment of the NU5 Network Upgrade
- - - - - - - -
4Zcash Protocol Specification, Version 2021.2.16. Section 7.1: Transaction Encoding and Consensus
-
-
- - \ No newline at end of file diff --git a/rendered/zip-0204.html b/rendered/zip-0204.html deleted file mode 100644 index 150f8bfe4..000000000 --- a/rendered/zip-0204.html +++ /dev/null @@ -1,17 +0,0 @@ - - - - ZIP 204: Zcash P2P Network Protocol - - - -
-
ZIP: 204
-Title: Zcash P2P Network Protocol
-Owners: Daira-Emma Hopwood <daira-emma@electriccoin.co>
-Status: Reserved
-Category: Network
-Discussions-To: <https://github.com/zcash/zips/issues/352>
-
- - \ No newline at end of file diff --git a/rendered/zip-0205.html b/rendered/zip-0205.html deleted file mode 100644 index 73bc1a994..000000000 --- a/rendered/zip-0205.html +++ /dev/null @@ -1,152 +0,0 @@ - - - - ZIP 205: Deployment of the Sapling Network Upgrade - - - -
-
ZIP: 205
-Title: Deployment of the Sapling Network Upgrade
-Owners: Daira-Emma Hopwood <daira-emma@electriccoin.co>
-Credits: Simon Liu
-Status: Final
-Category: Consensus / Network
-Created: 2018-10-08
-License: MIT
-

Terminology

-

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

-

The terms "consensus branch" and "network upgrade" in this document are 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 3.

-

The terms below are to be interpreted as follows:

-
-
Sapling
-
Code-name for the second Zcash network upgrade, also known as Network Upgrade 1.
-
-
-

Abstract

-

This proposal defines the deployment of the Sapling network upgrade. In addition, it describes a hard fork that occurred on Testnet to allow "minimum-difficulty" blocks.

-
-

Specification

-

Sapling deployment

-

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

-
    -
  • The Zcash Protocol Specification 2.
  • -
  • Transaction Signature Validation for Sapling 9.
  • -
  • Network Upgrade Mechanism 7.
  • -
-

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

-

The following network upgrade constants 7 are defined for the Sapling upgrade:

-
-
CONSENSUS_BRANCH_ID
-
0x76b809bb
-
ACTIVATION_HEIGHT (Sapling)
-
-

Testnet: 280000

-

Mainnet: 419200

-
-
-

On Testnet, Sapling had activated prior to this height, but that consensus branch was rolled back. A subsequent hard fork occurred on Testnet, changing the difficulty algorithm to accept "minimum-difficulty" blocks under certain conditions starting at block height 299188.

-

On both Mainnet and Testnet, Sapling-compatible nodes MUST advertise protocol version 170007 or later. The minimum peer protocol version that Sapling-compatible nodes will connect to, remains 170002.

-

Pre-Sapling nodes are defined as nodes advertising a protocol version less than 170007.

-

Approximately three days (defined in terms of block height) before the Sapling activation height, Sapling-compatible nodes will change the behaviour of their peer connection logic in order to prefer pre-Sapling peers for eviction from the set of peer connections.

-
/** The period before a network upgrade activates, where connections to upgrading peers are preferred (in blocks). */
-static const int NETWORK_UPGRADE_PEER_PREFERENCE_BLOCK_PERIOD = 24 * 24 * 3;
-

The implementation is similar to that for Overwinter which was described in 8.

-

Once Sapling activates on Testnet or Mainnet, Sapling nodes SHOULD take steps to:

-
    -
  • reject new connections from pre-Sapling nodes;
  • -
  • disconnect any existing connections to pre-Sapling nodes.
  • -
-
-

Change to difficulty adjustment on Testnet

-

Section 7.6.3 of the Zcash Protocol Specification 5 describes the algorithm used to adjust the difficulty of a block (defined in terms of a "target threshold") based on the nTime and nBits fields of preceding blocks.

-

This algorithm changed on Testnet, starting from block 299188, to allow "minimum-difficulty" blocks. If the block time of a block from this height onward is greater than 15 minutes 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 4, and ToCompact is as defined in section 7.7.4 of that specification 6.

-

Note: a previous revision of this ZIP 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.

-
-
-

Backward compatibility

-

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

-

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

-
-

Support in zcashd

-

Support for Sapling consensus rules was implemented in zcashd version 2.0.0. The majority of support for RPC calls and persistence of Sapling z-addresses was implemented in version 2.0.1. Both of these versions advertise protocol version 170007.

-
-

References

- - - - - - - -
1Information 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"
- - - - - - - -
2Zcash Protocol Specification, Version 2021.2.16 or later
- - - - - - - -
3Zcash Protocol Specification, Version 2021.2.16. Section 3.12: Mainnet and Testnet
- - - - - - - -
4Zcash Protocol Specification, Version 2021.2.16. Section 5.3: Constants
- - - - - - - -
5Zcash Protocol Specification, Version 2021.2.16. Section 7.7.3: Difficulty adjustment
- - - - - - - -
6Zcash Protocol Specification, Version 2021.2.16. Section 7.7.4: nBits conversion
- - - - - - - -
7ZIP 200: Network Upgrade Mechanism
- - - - - - - -
8ZIP 201: Network Peer Management for Overwinter
- - - - - - - -
9ZIP 243: Transaction Signature Validation for Sapling
-
-
- - \ No newline at end of file diff --git a/rendered/zip-0206.html b/rendered/zip-0206.html deleted file mode 100644 index bf74ecadb..000000000 --- a/rendered/zip-0206.html +++ /dev/null @@ -1,117 +0,0 @@ - - - - ZIP 206: Deployment of the Blossom Network Upgrade - - - -
-
ZIP: 206
-Title: Deployment of the Blossom Network Upgrade
-Owners: Daira-Emma Hopwood <daira-emma@electriccoin.co>
-Credits: Simon Liu
-Status: Final
-Category: Consensus / Network
-Created: 2019-07-29
-License: MIT
-

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. 3

-

The terms below are to be interpreted as follows:

-
-
Blossom
-
Code-name for the third Zcash network upgrade, also known as Network Upgrade 2.
-
Testnet
-
The Zcash test network, as defined in 2.
-
Mainnet
-
The Zcash production network, as defined in 2.
-
-
-

Abstract

-

This proposal defines the deployment of the Blossom network upgrade.

-
-

Specification

-

Blossom deployment

-

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

-
    -
  • The Zcash Protocol Specification 2.
  • -
  • Shorter Block Target Spacing 5.
  • -
  • Network Upgrade Mechanism 3.
  • -
-

The network handshake and peer management mechanisms defined in 4 also apply to this upgrade.

-

The following network upgrade constants 3 are defined for the Blossom upgrade:

-
-
CONSENSUS_BRANCH_ID
-
0x2BB40E60
-
ACTIVATION_HEIGHT (Blossom)
-
-

Testnet: 584000

-

Mainnet: 653600

-
-
-

Nodes compatible with Blossom activation on testnet MUST advertise protocol version 170008 or later. Nodes compatible with Blossom activation on mainnet MUST advertise protocol version 170009 or later. The minimum peer protocol version that Blossom-compatible nodes will connect to is 170002.

-

Pre-Blossom testnet nodes are defined as nodes on testnet advertising a protocol version less than 170008. Pre-Blossom mainnet nodes are defined as nodes on mainnet advertising a protocol version less than 170009.

-

For each network (testnet and mainnet), approximately three days (defined in terms of block height) before the corresponding Blossom activation height, nodes compatible with Blossom activation on that network will change the behaviour of their peer connection logic in order to prefer pre-Blossom peers on that network for eviction from the set of peer connections:

-
/** The period before a network upgrade activates, where connections to upgrading peers are preferred (in blocks). */
-static const int NETWORK_UPGRADE_PEER_PREFERENCE_BLOCK_PERIOD = 24 * 24 * 3;
-

The implementation is similar to that for Overwinter which was described in 4.

-

Once Blossom activates on testnet or mainnet, Blossom nodes SHOULD take steps to:

-
    -
  • reject new connections from pre-Blossom nodes on that network;
  • -
  • disconnect any existing connections to pre-Blossom nodes on that network.
  • -
-
-
-

Backward compatibility

-

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

-

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

-

Unlike Overwinter and Sapling, Blossom does not define a new transaction version. Blossom transactions are therefore in the same v4 format as Sapling transactions, and use the same version group ID, i.e. 0x892F2085 as defined in 2 section 7.1. This does not imply that transactions are valid across the Blossom activation, since signatures MUST use the appropriate consensus branch ID.

-
-

Support in zcashd

-

Support for Blossom on testnet is implemented in zcashd version 2.0.7, which advertises protocol version 170008. Support for Blossom on mainnet is implemented in zcashd version 2.1.0, which advertises protocol version 170009.

-
-

References

- - - - - - - -
1Information 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"
- - - - - - - -
2Zcash Protocol Specification, Version 2021.2.16 or later
- - - - - - - -
3ZIP 200: Network Upgrade Mechanism
- - - - - - - -
4ZIP 201: Network Peer Management for Overwinter
- - - - - - - -
5ZIP 208: Shorter Block Target Spacing
-
-
- - \ No newline at end of file diff --git a/rendered/zip-0207.html b/rendered/zip-0207.html deleted file mode 100644 index 220c16514..000000000 --- a/rendered/zip-0207.html +++ /dev/null @@ -1,469 +0,0 @@ - - - - ZIP 207: Funding Streams - - - - -
-
ZIP: 207
-Title: Funding Streams
-Owners: Jack Grigg <str4d@electriccoin.co>
-        Daira-Emma Hopwood <daira-emma@electriccoin.co>
-Status: Final
-Category: Consensus
-Created: 2019-01-04
-License: MIT
-

Terminology

-

The key words "MUST", "SHOULD", "SHOULD NOT", 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 terms "block subsidy" and "halving" in this document are to be interpreted as described in sections 3.9 and 7.7 of the Zcash Protocol Specification. 3 9

-

The terms "consensus branch" and "network upgrade" in this document are to be interpreted as described in ZIP 200. 13

-

The terms below are to be interpreted as follows:

-
-
Canopy
-
Code-name for the fifth Zcash network upgrade, also known as Network Upgrade 4.
-
Testnet
-
The Zcash test network, as defined in the Zcash Protocol Specification. 4
-
Mainnet
-
The Zcash production network, as defined in the Zcash Protocol Specification. 4
-
-
-

Abstract

-

This proposal specifies a mechanism to support funding streams, distributed from a portion of the block subsidy for a specified range of block heights.

-

This is intended as a means of implementing the Zcash Development Fund, using the funding stream definitions specified in ZIP 214 17. It should be read in conjunction with ZIP 1014 20, which describes the high-level requirements for that fund.

-
-

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.

-
-

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.

-

As for the original Founders' Reward, a mechanism is provided to allow addresses for a given funding stream to be changed on a roughly-monthly basis, so that keys that are not yet needed may be kept off-line as a security measure.

-
-

Specification

-

Definitions

-

We use the following constants and functions defined in 5, 8, 9, and 10:

-
    -
  • - \(\mathsf{BlossomActivationHeight}\) -
  • -
  • - \(\mathsf{PostBlossomHalvingInterval}\) -
  • -
  • - \(\mathsf{Halving}(\mathsf{height})\) -
  • -
  • - \(\mathsf{BlockSubsidy}(\mathsf{height})\) -
  • -
  • - \(\mathsf{RedeemScriptHash}(\mathsf{height})\) - .
  • -
-

We also define the following function:

-
    -
  • - \(\mathsf{HeightForHalving}(\mathsf{halving})\) - : Smallest - \(\mathsf{height}\) - such that - \(\mathsf{Halving}(\mathsf{height}) = \mathsf{halving}\) -
  • -
-
-

Funding streams

-

A funding stream is defined by a block subsidy fraction (represented as a numerator and a denominator), a start height (inclusive), an end height (exclusive), and a sequence of recipients as defined below.

-

By defining the issuance as a proportion of the total block subsidy, rather than absolute zatoshis, this ZIP dovetails with any changes to both block target spacing and issuance-per-block rates. Such a change occurred at the Blossom network upgrade, for example. 14

-

The value of a funding stream at a given block height is defined as:

-
\(\mathsf{FundingStream[FUND].Value}(\mathsf{height}) = - \mathsf{floor}\left( - \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.

-

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*} - \mathsf{AddressChangeInterval} &=& \mathsf{PostBlossomHalvingInterval} / 48 \\ - \mathsf{AddressPeriod}(\mathsf{height}) &=& - \mathsf{floor}\left( - {\small\frac{\mathsf{height} + \mathsf{PostBlossomHalvingInterval} - \mathsf{HeightForHalving}(1)}{\mathsf{AddressChangeInterval}}} - \right) \\ - \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*}\)
-

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:

-
- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
Example heightStream AStream BStream C
AddressChangeInterval - 2A0
AddressChangeInterval - 1A0
AddressChangeIntervalA1B0C0
AddressChangeInterval + 1A1B0C0
...
2*AddressChangeInterval - 2A1B0C0
2*AddressChangeInterval - 1A1B0C0
2*AddressChangeIntervalA2C1
2*AddressChangeInterval + 1A2C1
...
PostBlossomHalvingInterval - 2A2C1
PostBlossomHalvingInterval - 1A2C1
PostBlossomHalvingIntervalC2
PostBlossomHalvingInterval + 1C2
-
-

On Mainnet, Canopy is planned to activate exactly at the point when the Founders' Reward expires, at block height 1046400. On Testnet, there will be a shortened Founders' Reward address period prior to Canopy activation.

-
-

Deferred Development Fund Chain Value Pool Balance

-

Full node implementations MUST track an additional - \(\mathsf{ChainValuePoolBalance^{Deferred}}\) - chain value pool balance, in addition to the Sprout, Sapling, and Orchard chain value pool balances.

-

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}\_\mathsf{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}\) - 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})\) - .

-

Note: - \(\mathsf{totalDeferredOutput}(\mathsf{h})\) - is necessarily zero for heights - \(\mathsf{h}\) - 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

-

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.)
  • -
  • 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 - \(\mathsf{DEFERRED}\_\mathsf{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.
  • -
  • - \(\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 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 - \(\mathbf{0x02}\!\) - , as specified in 15.
  • -
-

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

-

The effect of the definition of - \(\mathsf{ChainValuePoolBalance^{Deferred}}\) - above is that payments to the - \(\mathsf{DEFERRED}\_\mathsf{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

-
-
-

Deployment

-

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.

-
-

Reference Implementation

- -
-

References

- - - - - - - -
1Information 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>
- - - - - - - -
2Zcash Protocol Specification, Version 2024.5.1 or later <protocol/protocol.pdf>
- - - - - - - -
3Zcash Protocol Specification, Version 2024.5.1 [NU6]. Section 3.10: Block Subsidy and Founders' Reward <protocol/protocol.pdf#subsidyconcepts>
- - - - - - - -
4Zcash Protocol Specification, Version 2024.5.1 [NU6]. Section 3.12: Mainnet and Testnet <protocol/protocol.pdf#networks>
- - - - - - - -
5Zcash Protocol Specification, Version 2024.5.1 [NU6]. Section 5.3: Constants <protocol/protocol.pdf#constants>
- - - - - - - -
6Zcash Protocol Specification, Version 2024.5.1 [NU6]. Section 5.6.1.1: Transparent Addresses <protocol/protocol.pdf#transparentaddrencoding>
- - - - - - - -
7Zcash Protocol Specification, Version 2024.5.1 [NU6]. Section 5.6.3.1: Sapling Payment Addresses <protocol/protocol.pdf#saplingpaymentaddrencoding>
- - - - - - - -
8Zcash Protocol Specification, Version 2024.5.1 [NU6]. Section 7.7.3: Difficulty adjustment <protocol/protocol.pdf#diffadjustment>
- - - - - - - -
9Zcash Protocol Specification, Version 2024.5.1 [NU6]. Section 7.8: Calculation of Block Subsidy, Funding Streams, and Founders' Reward <protocol/protocol.pdf#subsidies>
- - - - - - - -
10Zcash Protocol Specification, Version 2024.5.1 [NU6]. Section 7.9: Payment of Founders' Reward <protocol/protocol.pdf#foundersreward>
- - - - - - - -
11Zcash Protocol Specification, Version 2024.5.1 [NU6]. Section 7.10: Payment of Funding Streams <protocol/protocol.pdf#fundingstreams>
- - - - - - - -
12ZIP 0: ZIP Process <zip-0000.rst>
- - - - - - - -
13ZIP 200: Network Upgrade Mechanism <zip-0200.rst>
- - - - - - - -
14ZIP 208: Shorter Block Target Spacing <zip-0208.rst>
- - - - - - - -
15ZIP 212: Allow Recipient to Derive Sapling Ephemeral Secret from Note Plaintext <zip-0212.rst>
- - - - - - - -
16ZIP 213: Shielded Coinbase <zip-0213.rst>
- - - - - - - -
17ZIP 214: Consensus rules for a Zcash Development Fund <zip-0214.rst>
- - - - - - - -
18ZIP 251: Deployment of the Canopy Network Upgrade <zip-0251.rst>
- - - - - - - -
19ZIP 253: Deployment of the NU6 Network Upgrade <zip-0253.rst>
- - - - - - - -
20ZIP 1014: Establishing a Dev Fund for ECC, ZF, and Major Grants <zip-1014.rst>
- - - - - - - -
21ZIP 1015: Block Reward Allocation for Non-Direct Development Funding <zip-1015.rst>
- - - - - - - -
22ZIP 2001: Lockbox Funding Streams <zip-2001.rst>
-
-
- - \ No newline at end of file diff --git a/rendered/zip-0208.html b/rendered/zip-0208.html deleted file mode 100644 index 4d4a014bc..000000000 --- a/rendered/zip-0208.html +++ /dev/null @@ -1,313 +0,0 @@ - - - - ZIP 208: Shorter Block Target Spacing - - - -
-
ZIP: 208
-Title: Shorter Block Target Spacing
-Owners: Daira-Emma Hopwood <daira-emma@electriccoin.co>
-Original-Authors: Daira-Emma Hopwood
-                  Simon Liu
-Status: Final
-Category: Consensus
-Created: 2019-01-10
-License: MIT
-Pull-Request: <https://github.com/zcash/zips/pull/237>
-

Terminology

-

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

-

The terms "block chain", "consensus rule change", "consensus branch", and "network upgrade" are to be interpreted as defined in 9.

-

The term "block target spacing" means the time interval between blocks targeted by the difficulty adjustment algorithm in a given consensus branch. It is normally measured in seconds. (This is also sometimes called the "target block time", but "block target spacing" is the term used in the Zcash Protocol Specification 6.)

-

The terms "Testnet" and "Mainnet" are to be interpreted as described in section 3.12 of the Zcash Protocol Specification 4.

-
-

Abstract

-

This proposal specifies a change in the block target spacing, to take effect in the Blossom network upgrade 11.

-

The emission schedule of mined ZEC will be approximately the same in terms of time, but this requires the emission per block to be adjusted to take account of the changed block target spacing.

-
-

Motivation

-

The motivations for decreasing the block target spacing are:

-
    -
  • Reduced latency for considering transactions to be sufficiently confirmed;
  • -
  • Greater throughput of transactions in unit time.
  • -
-

The latter goal could alternatively be achieved by increasing the block size limit, but that would not also achieve the former goal.

-

Note that, for a given security requirement (in terms of the expected cost distribution of a rollback attack), the number of confirmations needed increases more slowly than the decrease in block time, and so, up to a point, decreasing the block target spacing can provide a better trade-off between latency and security. This argument assumes that the validation and propagation time for a block remain small compared to the block target spacing. See 13 for further analysis in various attack models.

-
-

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.

-

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:

-
    -
  • 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.
    • -
    -
  • -
-

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:

-
    -
  • 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
    • -
    -
  • -
-

Note: BlossomActivationHeight, PostBlossomHalvingInterval, and 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.
  • -
-

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).

-

Also define:

-
    -
  • FoundersRewardLastBlockHeight := max({ height ⦂ N | Halving(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).
  • -
-

and in the second note, replace SlowStartShift + PreBlossomHalvingInterval - 1 with 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.

-

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.

-

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.

-
-
-

Non-consensus node behaviour

-

End-of-Service halt

-

zcashd implements an "End-of-Service halt" behaviour that halts the node at a block height that corresponds approximately to a given time after release. This interval SHOULD be adjusted in releases where the End-of-Service halt time will follow Blossom activation.

-
-

Default expiry delta

-

When not overridden by the -txexpirydelta option, zcashd RPC calls that create transactions use a default value for the number of blocks after which a transaction will expire. The default in recent versions of zcashd is 20 blocks, which at the pre-Blossom block target spacing corresponds to roughly 50 minutes.

-

This default SHOULD change to BlossomPoWTargetSpacingRatio · 20 blocks after Blossom activation, to maintain the approximate expiry time of 50 minutes.

-

If the -txexpirydelta option is set, then the set value SHOULD be used both before and after Blossom activation.

-
-

Sprout to Sapling migration

-

ZIP 308 12 defines a procedure for migrating funds from Sprout to Sapling z-addresses. In that procedure, migration transactions are sent every 500 blocks, which corresponded to roughly 20.83 hours before Blossom.

-

The 500-block constant has not been changed. Therefore, migration transactions are now sent roughly every 10.42 hours after Blossom activation. This has been noted in the ZIP, and a table showing the expected time to complete migration has been updated accordingly.

-
-

Fingerprinting mitigation

-

A "fingerprinting attack" is a network analysis technique in which nodes are identified across network sessions, for example using information about which blocks they request or send.

-

zcashd inherits from Bitcoin Core the following behaviour, described in a comment in main.cpp, intended as a fingerprinting mitigation:

-
// To prevent fingerprinting attacks, only send blocks outside of the active
-// chain if they are valid, and no more than a month older (both in time, and in
-// best equivalent proof of work) than the best header chain we know about.
-

We make no assertion about the significance of fingerprinting for Zcash, and (despite the word "prevent" in the above comment) no claim about the effectiveness of this mitigation.

-

In any case, to estimate the "best equivalent proof of work" of a given block chain (measured in units of time), we take the total work of the chain as defined in section 7.7.5 of the Zcash Protocol Specification 8, divide by the work of the block at the active tip, and multiply by the target block spacing of that block.

-

It is not a requirement of the Zcash protocol that this fingerprinting mitigation is used; however, if it is used, then it SHOULD use the target block spacing at the same block height that is used for the current work estimate.

-
-

Monitoring for quicker- or slower-than-expected blocks

-

zcashd previously did this monitoring every 150 seconds; it is now done every 60 seconds.

-
-

Block timeout

-

The timeout for a requested block is calculated as the target block time, multiplied by 2 + (the number of queued validated headers)/2.

-
-

Latency optimization when requesting blocks

-

When zcashd sees an announced block that chains from headers that it does not already have, it will first ask for the headers, and then the block itself. A latency optimization is performed only if the chain is "nearly synced":

-
// First request the headers preceding the announced block. In the normal fully-synced
-// case where a new block is announced that succeeds the current tip (no reorganization),
-// there are no such headers.
-// Secondly, and only when we are close to being synced, we request the announced block directly,
-// to avoid an extra round-trip. Note that we must *first* ask for the headers, so by the
-// time the block arrives, the header chain leading up to it is already validated. Not
-// doing this will result in the received block being rejected as an orphan in case it is
-// not a direct successor.
-

The heuristic for "nearly synced" is that the timestamp of the block at the active tip is no more than 20 block times before the current "adjusted time". In zcashd this calculation uses the block target spacing as of the best known header. Around Blossom activation when the block target spacing changes, this could cause the heuristic to be based on the pre-Blossom block target spacing until the node has synced headers past the activation block, but this is not anticipated to cause any problem.

-
-

Response to getblocks message when pruning

-

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.

-
-

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.

-
- -
-
-

Deployment

-

This proposal will be deployed with the Blossom network upgrade. 11

-
-

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.

-
-

Reference Implementation

-

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

-
-

References

- - - - - - - -
1Information 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"
- - - - - - - -
2Zcash Protocol Specification, Version 2018.0-beta-37 (exactly)
- - - - - - - -
3Zcash Protocol Specification, Version 2021.2.16 or later
- - - - - - - -
4Zcash Protocol Specification, Version 2021.2.16. Section 3.12: Mainnet and Testnet
- - - - - - - -
5Zcash Protocol Specification, Version 2021.2.16. Section 5.3: Constants
- - - - - - - -
6Zcash Protocol Specification, Version 2021.2.16. Section 7.7.3: Difficulty adjustment
- - - - - - - -
7Zcash Protocol Specification, Version 2021.2.16. Section 7.7.4: nBits conversion
- - - - - - - -
8Zcash Protocol Specification, Version 2021.2.16. Section 7.7.5: Definition of Work
- - - - - - - -
9ZIP 200: Network Upgrade Mechanism
- - - - - - - -
10ZIP 205: Deployment of the Sapling Network Upgrade
- - - - - - - -
11ZIP 206: Deployment of the Blossom Network Upgrade
- - - - - - - -
12ZIP 308: Sprout to Sapling Migration
- - - - - - - -
13On Slow and Fast Block Times
-
-
- - \ No newline at end of file diff --git a/rendered/zip-0209.html b/rendered/zip-0209.html deleted file mode 100644 index 83e0a7eed..000000000 --- a/rendered/zip-0209.html +++ /dev/null @@ -1,77 +0,0 @@ - - - - ZIP 209: Prohibit Negative Shielded Chain Value Pool Balances - - - -
-
ZIP: 209
-Title: Prohibit Negative Shielded Chain Value Pool Balances
-Owners: Sean Bowe <sean@electriccoin.co>
-        Daira-Emma Hopwood <daira-emma@electriccoin.co>
-Status: Final
-Category: Consensus
-Created: 2019-02-25
-License: MIT
-

Terminology

-

The key words "MUST", "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 "block chain" and "network upgrade" are to be interpreted as defined in 3.

-

The "Sprout chain value pool balance" for a given block chain is the sum of all vpub_old fields for transactions in the block chain, minus the sum of all vpub_new fields for transactions in the block chain.

-

The "Sapling chain value pool balance" for a given block chain is the negation of the sum of all valueBalanceSapling fields for transactions in the block chain.

-

The "Orchard chain value pool balance" for a given block chain is the negation of the sum of all valueBalanceOrchard fields for transactions in the block chain. (Before NU5 has activated, the Orchard chain value pool balance is zero.)

-

The terms "Testnet" and "Mainnet" are to be interpreted as described in section 3.12 of the Zcash Protocol Specification 2.

-
-

Abstract

-

This proposal defines how the consensus rules are altered such that blocks that produce negative shielded chain value pool balances are prohibited.

-
-

Motivation

-

It is possible for nodes to monitor the total value of notes that are shielded to, or unshielded from, each of the Sprout, Sapling, and Orchard value pools. If the total value that is unshielded exceeds the total value that was shielded for a given pool, a balance violation has occurred in the corresponding shielded transaction protocol.

-

It would be preferable for the network to reject blocks that result in the aforementioned balance violation. However, nodes do not currently react to such an event. Remediation may therefore require chain rollbacks and other disruption.

-
-

Specification

-

If any of the "Sprout chain value pool balance", "Sapling chain value pool balance", or "Orchard chain value pool balance" would become negative in the block chain created as a result of accepting a block, then all nodes MUST reject the block as invalid.

-

Nodes MAY relay transactions even if one or more of them cannot be mined due to the aforementioned restriction.

-
-

Deployment

-

This consensus rule is not deployed as part of a network upgrade as defined in ZIP-200 3 and there is no mechanism by which the network will synchronize to enforce this rule. Rather, all nodes SHOULD begin enforcing this consensus rule upon acceptance of this proposal.

-

There is a risk that before all nodes on the network begin enforcing this consensus rule that block(s) will be produced that violate it, potentially leading to network fragmentation. This is considered sufficiently unlikely that the benefits of enforcing this consensus rule sooner are overwhelming.

-

This specification was deployed in zcashd v2.0.4 for Testnet, and in zcashd v2.0.5 for Mainnet. The application to the Orchard chain value pool balance will be deployed from NU5 activation 4.

-
-

References

- - - - - - - -
1Information 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"
- - - - - - - -
2Zcash Protocol Specification, Version 2021.2.16 or later. Section 3.12: Mainnet and Testnet
- - - - - - - -
3ZIP 200: Network Upgrade Mechanism
- - - - - - - -
4ZIP 252: Deployment of the NU5 Network Upgrade
-
-
- - \ No newline at end of file diff --git a/rendered/zip-0210.html b/rendered/zip-0210.html deleted file mode 100644 index 259d861ba..000000000 --- a/rendered/zip-0210.html +++ /dev/null @@ -1,96 +0,0 @@ - - - - ZIP 210: Sapling Anchor Deduplication within Transactions - - - -
-
ZIP: 210
-Title: Sapling Anchor Deduplication within Transactions
-Owners: Jack Grigg <str4d@electriccoin.co>
-Status: Withdrawn
-Category: Consensus
-Created: 2019-03-27
-License: MIT
-

Status

-

This ZIP has been withdrawn because a similar change has been incorporated into the ZIP 225 proposal for a version 5 transaction format. 5

-
-

Terminology

-

The key words "MUST" 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 3.

-

The term "Sapling" in this document is to be interpreted as described in ZIP 205 4.

-
-

Abstract

-

This proposal defines a modification to the transaction format whereby a single Sapling anchor is used for all Sapling spends. This change removes a potential implementation fingerprint, and reduces the size of Sapling transactions within the block chain.

-
-

Motivation

-

The Sapling network upgrade 4 introduced new shielded inputs (spends) and outputs. Each spend proves the existence of the note being spent by including the anchor of a Merkle tree that contains the note's commitment, and proving in zero knowledge the existence of a path from the commitment to the anchor (a witness). Valid anchors correspond to the state of the Sapling commitment tree after each block in the chain.

-

The choice of anchor leaks information about the note being spent, namely that the note was created no later than the anchor's block height. This is an unavoidable outcome of the Zcash design, and the least information it is possible to leak about a note being spent. However, the Sapling v4 transaction format 2 includes a separate anchor for each Sapling spend, and thus it is possible to leak additional information by using different anchors for different notes. The anchor selection choices could also be used as a fingerprint to identify transactions created by particular wallet implementations, reducing the privacy set.

-

Modifying the transaction format to have a single Sapling anchor field, instead of one field per Sapling spend, removes the ability (within the new transaction format version) to create transactions with this fingerprint. It also reduces the size of the transaction, costing 32 bytes per transaction instead of 32 bytes per spend.

-
-

Specification

-

A new transaction format is defined, identical to the Sapling v4 transaction format except for two changes:

-
    -
  • The anchor field in SpendDescription is removed.
  • -
  • A new field saplingAnchor is placed between vShieldedOutput and vJoinSplit, if and only if vShieldedSpend is not empty.
  • -
-

Consensus rules that previously applied to individual anchor entries MUST be applied to saplingAnchor.

-

TODO: If this is the only ZIP updating the transaction format in a NU, specify the full transaction format here. Otherwise, reference the new transaction format when specified.

-

Implementations that support older transaction formats MAY copy saplingAnchor into each spend's in-memory representation during parsing to reduce code duplication, and MUST ensure that these per-spend in-memory anchors are all identical prior to serialization.

-
-

Rationale

-

Placing the saplingAnchor field after vShieldedOutput means that it can be conditionally included (saving space when there are no Sapling spends), while ensuring that the transaction can still be parsed unambiguously.

-

Requiring all Sapling spends to use the same anchor removes a possible performance optimisation in certain classes of (particularly light) wallets, where witnesses for older notes are only updated periodically instead of every block. This optimisation is exactly the kind of behaviour that can be used as a fingerprint in the v4 transaction format, and that we are choosing to prevent with this proposal.

-
-

Security and Privacy Considerations

-

This proposal eliminates a possible avenue for distinguishing transactions based on the client implementation that created them.

-
-

Reference Implementation

-

TBD

-
-

References

- - - - - - - -
1Information 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"
- - - - - - - -
2Zcash Protocol Specification, Version 2021.2.16. Section 7.1: Transaction Encoding and Consensus
- - - - - - - -
3ZIP 200: Network Upgrade Mechanism
- - - - - - - -
4ZIP 205: Deployment of the Sapling Network Upgrade
- - - - - - - -
5ZIP 225: Version 5 Transaction Format
-
-
- - \ No newline at end of file diff --git a/rendered/zip-0211.html b/rendered/zip-0211.html deleted file mode 100644 index ea75db48d..000000000 --- a/rendered/zip-0211.html +++ /dev/null @@ -1,140 +0,0 @@ - - - - ZIP 211: Disabling Addition of New Value to the Sprout Chain Value Pool - - - -
-
ZIP: 211
-Title: Disabling Addition of New Value to the Sprout Chain Value Pool
-Owners: Daira-Emma Hopwood <daira-emma@electriccoin.co>
-Credits: Sean Bowe
-Status: Final
-Category: Consensus
-Created: 2019-03-29
-License: MIT
-

Terminology

-

The key words "MUST", "SHOULD", and "OPTIONAL" 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 3.

-

The term "Sprout shielded protocol" in this document refers to the shielded payment protocol defined at the launch of the Zcash network.

-

The term "Sapling shielded protocol" in this document refers to the shielded payment protocol introduced in the Sapling network upgrade 4 2.

-

The term "Sprout chain value pool balance" in this document is to be interpreted as described in ZIP 209 5.

-
-

Abstract

-

This proposal disables the ability to add new value to the Sprout chain value pool balance. This takes a step toward being able to remove the Sprout shielded protocol, thus reducing the overall complexity and attack surface of Zcash.

-
-

Motivation

-

The first iteration of the Zcash network, called Sprout, provided a shielded payment protocol that was relatively closely based on the original Zerocash proposal. 8

-

The Sapling network upgrade 4 introduced significant efficiency and functionality improvements for shielded transactions. It is expected that over time, the use of Sapling will replace the use of Sprout in shielded transactions.

-

The Sapling and Sprout shielded protocols employ different cryptographic designs. Since an adversary could potentially exploit any vulnerability in either design, supporting both presents additional risk over supporting only the newer Sapling shielded protocol.

-

For example, a vulnerability was discovered in the zero-knowledge proving system originally used by Zcash that could have allowed counterfeiting 9. While this particular vulnerability was addressed (also for Sprout shielded transactions) by the Sapling upgrade, and we are not aware of others at the time of writing, the possibility of other cryptographic weaknesses cannot be entirely ruled out.

-

In addition, the Zcash specification and implementation incurs complexity and "technical debt" from the requirement to support and test both shielded payment protocols.

-

Removing the ability to add to the Sprout chain value pool balance, is a first step toward reducing this complexity and potential risk. This does not prevent extracting value held in Sprout addresses and sending it to transparent addresses, or to Sapling addresses via the migration tool 7.

-
-

Specification

-

Consensus rule: From the relevant activation height, the vpub_old field of each JoinSplit description MUST be zero.

-

When this proposal is activated, nodes and wallets MUST disable any facilities to create transactions that have both one or more outputs to Sprout addresses, and one or more inputs from non-Sprout addresses. This SHOULD be made clear in user interfaces and API documentation.

-

Notes:

-
    -
  • The requirement on wallets is intentionally slightly stronger than that enforced by the consensus rule. It is possible to construct a mixed transaction with inputs from both Sprout and non-Sprout addresses, in which all vpub_old fields are zero, but there are nevertheless sufficient funds from Sprout inputs to balance the Sprout outputs. This is prohibited for usability reasons, but not by consensus.
  • -
  • The facility to send to Sprout addresses, even before activation of this proposal, is OPTIONAL for a particular node or wallet implementation.
  • -
-
-

Rationale

-

This design does not require any change to the JoinSplit circuit, thus minimizing the risk of security regressions, and avoiding the need for a new ceremony to generate circuit parameters.

-

The code changes needed are very small and simple, and their security is easy to analyse.

-

During the development of this proposal, alternative designs were considered that would have removed some fields of a JoinSplit description. These alternatives were abandoned for several reasons:

-
    -
  • Privacy concerns raised as a consequence of preventing the use of internal change between JoinSplits, and/or change sent back to the input Sprout addresses. This would have required the total value of the input Sprout notes (or, for some considered designs, the total value of the two Sprout inputs to each JoinSplit) to be leaked. As it is, there is an unavoidable leak of the total value extracted from the Sprout value pool, but not of the sum of values of particular subsets of notes.
  • -
  • Modifications would have been needed to the design of the Sprout to Sapling migration procedure described in 7.
  • -
  • A new transaction version would have been required.
  • -
-
-

Security and Privacy Considerations

-

The security motivations for making this change are described in the Motivation section. Privacy concerns that led to the current design are discussed in the Rationale section.

-

Since all clients change their behaviour at the same time from this proposal's activation height, there is no additional client distinguisher.

-
-

Deployment

-

This proposal will be deployed with the Canopy network upgrade. 6

-
-

Reference Implementation

-

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

-
-

References

- - - - - - - -
1Information 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"
- - - - - - - -
2Zcash Protocol Specification, Version 2021.2.16 or later
- - - - - - - -
3ZIP 200: Network Upgrade Mechanism
- - - - - - - -
4ZIP 205: Deployment of the Sapling Network Upgrade
- - - - - - - -
5ZIP 209: Prohibit Negative Shielded Value Pool
- - - - - - - -
6ZIP 251: Deployment of the Canopy Network Upgrade
- - - - - - - -
7ZIP 308: Sprout to Sapling Migration
- - - - - - - -
8Zerocash: Decentralized Anonymous Payments from Bitcoin (extended version)
- - - - - - - -
9Zcash Counterfeiting Vulnerability Successfully Remediated
-
-
- - \ No newline at end of file diff --git a/rendered/zip-0212.html b/rendered/zip-0212.html deleted file mode 100644 index 2c755bc84..000000000 --- a/rendered/zip-0212.html +++ /dev/null @@ -1,485 +0,0 @@ - - - - ZIP 212: Allow Recipient to Derive Ephemeral Secret from Note Plaintext - - - - -
-
ZIP: 212
-Title: Allow Recipient to Derive Ephemeral Secret from Note Plaintext
-Owners: Sean Bowe <sean@electriccoin.co>
-Status: Final
-Category: Consensus
-Created: 2019-03-31
-License: MIT
-

Terminology

-

The key words "MUST", "MUST NOT", "SHOULD NOT", 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 following functions are defined in the Zcash Protocol Specification 2 according to the type (Sapling or Orchard) of note plaintext being processed:

-
    -
  • let - \(\mathsf{ToScalar}\) - be - \(\mathsf{ToScalar^{Sapling}}\) - defined in section 4.2.2 5 or - \(\mathsf{ToScalar^{Orchard}}\) - defined in section 4.2.3 6;
  • -
  • let - \(\mathsf{DiversifyHash}\) - be - \(\mathsf{DiversifyHash^{Sapling}}\) - or - \(\mathsf{DiversifyHash^{Orchard}}\) - defined in section 5.4.1.6 12;
  • -
  • let - \(\mathsf{KA}\) - be - \(\mathsf{KA^{Sapling}}\) - defined in section 5.4.5.3 13 or - \(\mathsf{KA^{Orchard}}\) - defined in section 5.4.5.5 14;
  • -
  • let - \(\mathsf{NoteCommit}\) - be - \(\mathsf{NoteCommit^{Sapling}}\) - or - \(\mathsf{NoteCommit^{Orchard}}\) - defined in section 4.1.8 4.
  • -
-
-

Abstract

-

This ZIP proposes a new note plaintext format for Sapling Outputs (later extended to include Orchard Actions) in transactions. The new format allows recipients to verify that the sender of an Output or Action knows the private key corresponding to the ephemeral Diffie–Hellman key, in order to avoid an assumption on zk-SNARK soundness for preventing diversified address linkability.

-
-

Motivation

-

The Sapling and Orchard payment protocols have a feature called "diversified addresses" which allows a single incoming viewing key to receive payments on an enormous number of distinct and unlinkable payment addresses. This feature 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 - \((\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 - \(\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 - \(\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 - \(\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 - \((\mathsf{pk_d}, \mathsf{d})\) - was used to compute the shared secret, but the sender is asked to include the - \(\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 attacker strategy was discovered by Brian Warner earlier in the design of the 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 - \(\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.

-

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 - \(\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) - \(\mathsf{epk} = [\mathsf{esk}]\, \mathsf{g_d}\) - is not checked in the Action statement.

-

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 - \(\mathsf{esk}\) - and - \(\mathsf{rcm}\!\) - .

-
-

Specification

- -

Pseudo random functions (PRFs) are defined in section 4.1.2 of the Zcash Protocol Specification 3. We will be adapting - \(\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

-

Note plaintext encodings are specified in section 5.5 of the Zcash Protocol Specification 15. Before activation of this ZIP, the encoding of a Sapling note plaintext required that the first byte take the form - \(\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 - \(\mathtt{0x02}\) - (representing the new note plaintext version).
  • -
  • 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 - \(\mathsf{NoteCommit.Trapdoor}\) - (as it did for Sapling) but instead is a - \(32\!\) - -byte sequence.
  • -
-

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.

-
-

Changes to the process of sending Sapling or Orchard notes

-

The process of sending notes is described in section 4.7.2 of the Zcash Protocol Specification for Sapling 7 and section 4.7.3 for Orchard 8. In addition, the process of encrypting a note is described in section 4.19.1 of the Zcash Protocol Specification 9. Prior to activation of this ZIP, the 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 - \(32\!\) - -byte sequence - \(\mathsf{rseed}\!\) - . The note plaintext takes - \(\mathsf{rseed}\) - in place of - \(\mathsf{rcm^{new}}\!\) - .

-

For Sapling:

-
    -
  • - \(\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:

-
    -
  • - \(\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 - \(\underline{\text{ρ}} = \mathsf{I2LEOSP}_{256}(\mathsf{nf^{old}}\) - from the same Action description - \(\!)\!\) - .

- -
-

Changes to the process of receiving Sapling or Orchard notes

-

The process of receiving notes in Sapling is described in sections 4.19.2 and 4.19.3 of the Zcash Protocol Specification. 10 11

-

There is a "grace period" of 32256 blocks starting from the block at which this 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 GracePeriodEndHeight be ActivationHeight + 32256.

-

The height of a transaction in a mined block is defined as the height of that block. An implementation MAY also decrypt mempool transactions, in which case the height used is the height of the next block at the time of the check. An implementation SHOULD NOT attempt to decrypt mempool transactions without having obtained a best-effort view of the current block chain height.

-

When the recipient of a note (either using an incoming viewing key or a full 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 - \(\mathtt{0x01}\) - is accepted as the plaintext lead byte.
  • -
  • If the height is at least ActivationHeight and less than GracePeriodEndHeight, then either - \(\mathtt{0x01}\) - or - \(\mathtt{0x02}\) - is accepted as the plaintext lead byte.
  • -
  • 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. 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 - \(\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 - \(\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

-

After the activation of this ZIP, any Sapling output of a coinbase transaction that is decrypted to a note plaintext as specified in 17, MUST have note plaintext lead byte equal to - \(\mathtt{0x02}\!\) - .

-

This applies even during the “grace period”, and also applies to funding stream outputs 16 sent to shielded payment addresses, if there are any.

-

Since NU5 activates after the end of the grace period 19, Orchard outputs will always require a note plaintext lead byte equal to - \(\mathtt{0x02}\!\) - .

-
-
-

Rationale

-

The attack that this prevents is an interactive attack that requires an adversary to be able to break critical soundness properties of the zk-SNARKs underlying Sapling. It is potentially valid to assume that this cannot occur, due to other damaging effects on the system such as undetectable counterfeiting. However, we have attempted to avoid any instance in the protocol where privacy (even against interactive attacks) depended on strong cryptographic assumptions. 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 - \(\mathsf{esk}\) - within the existing note plaintext without modifying the transaction format, but this would have harmed users who 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 - \(\mathsf{esk}\) - rather than - \(\mathsf{esk}\) - itself, but this appears to be an unnecessary complication and is likely slower than just supplying - \(\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 grace period (of about 4 weeks), it will be possible to identify wallets that 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 - \(\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 - \(\mathtt{0x01}\) - that were sent conformantly and not mined before the upgrade.

-

Historical note: in practice some note plaintexts with lead byte - \(\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 20.

-
-

Security and Privacy Considerations

-

The changes made in this proposal prevent an interactive attack that could link together diversified addresses by only breaking the knowledge soundness 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 - \(\mathsf{esk}\) - is supplied directly to the recipient (rather than derived through - \(\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 written by reprogramming the oracle to return bogus keys when necessary.

-
-

Deployment

-

This proposal will be deployed with the Canopy network upgrade. 18

-
-

Reference Implementation

-

In zcashd:

- -

In librustzcash:

- -
-

Acknowledgements

-

The discovery that diversified address unlinkability depended on the zk-SNARK knowledge assumption was made by Sean Bowe and Zooko Wilcox.

-
-

References

- - - - - - - -
1Information 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"
- - - - - - - -
2Zcash Protocol Specification, Version 2023.4.0 or later
- - - - - - - -
3Zcash Protocol Specification, Version 2023.4.0. Section 4.1.2: Pseudo Random Functions
- - - - - - - -
4Zcash Protocol Specification, Version 2023.4.0. Section 4.1.8: Commitment
- - - - - - - -
5Zcash Protocol Specification, Version 2023.4.0. Section 4.2.2: Sapling Key Components
- - - - - - - -
6Zcash Protocol Specification, Version 2023.4.0. Section 4.2.3: Orchard Key Components
- - - - - - - -
7Zcash Protocol Specification, Version 2023.4.0. Section 4.7.2: Sending Notes (Sapling)
- - - - - - - -
8Zcash Protocol Specification, Version 2023.4.0. Section 4.7.3: Sending Notes (Orchard)
- - - - - - - -
9Zcash Protocol Specification, Version 2023.4.0. Section 4.19.1: Encryption (Sapling and Orchard)
- - - - - - - -
10Zcash Protocol Specification, Version 2023.4.0. Section 4.19.2: Decryption using an Incoming Viewing Key (Sapling and Orchard)
- - - - - - - -
11Zcash Protocol Specification, Version 2023.4.0. Section 4.19.3: Decryption using a Full Viewing Key (Sapling and Orchard)
- - - - - - - -
12Zcash Protocol Specification, Version 2023.4.0. Section 5.4.1.6: DiversifyHash^Sapling and DiversifyHash^Orchard Hash Functions
- - - - - - - -
13Zcash Protocol Specification, Version 2023.4.0. Section 5.4.5.3 Sapling Key Agreement
- - - - - - - -
14Zcash Protocol Specification, Version 2023.4.0. Section 5.4.5.5 Orchard Key Agreement
- - - - - - - -
15Zcash Protocol Specification, Version 2023.4.0. Section 5.5: Encodings of Note Plaintexts and Memo Fields
- - - - - - - -
16ZIP 207: Split Founders' Reward
- - - - - - - -
17ZIP 213: Shielded Coinbase
- - - - - - - -
18ZIP 251: Deployment of the Canopy Network Upgrade
- - - - - - - -
19ZIP 252: Deployment of the NU5 Network Upgrade
- - - - - - - -
20Commit c31a04a in aditypk00/librustzcash: Move ZIP-212 grace period to end of April
-
-
- - \ No newline at end of file diff --git a/rendered/zip-0213.html b/rendered/zip-0213.html deleted file mode 100644 index f40ada08c..000000000 --- a/rendered/zip-0213.html +++ /dev/null @@ -1,131 +0,0 @@ - - - - ZIP 213: Shielded Coinbase - - - -
-
ZIP: 213
-Title: Shielded Coinbase
-Owners: Jack Grigg <jack@z.cash>
-Status: Final
-Category: Consensus
-Created: 2019-03-30
-License: MIT
-

Terminology

-

The key words "MUST" 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 term "Sapling" in this document is to be interpreted as described in ZIP 205 3.

-

The terms "Founders' Reward" and "funding stream" in this document are to be interpreted as described in ZIP 207 4.

-
-

Abstract

-

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).

-

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.

-
-

Specification

-

Prior to activation of the Heartwood network upgrade, this existing consensus rule on coinbase transactions is enforced:

-
-

A coinbase transaction MUST NOT have any JoinSplit descriptions, Spend descriptions, or Output descriptions.

-
-

Once the Heartwood network upgrade activates:

-
    -
  • Coinbase transactions MAY contain Sapling outputs. More precisely, the above existing consensus rule is modified to: -

    A coinbase transaction MUST NOT have any JoinSplit descriptions or Spend descriptions.

    -

    [Pre-Heartwood] A coinbase transaction also MUST NOT have any Output descriptions.

    -
  • -
  • The consensus rules applied to valueBalance, vShieldedOutput, and bindingSig in non-coinbase transactions MUST also be applied to coinbase transactions.
  • -
  • Only transparent outputs in coinbase transactions are subject to the existing restrictions on spending coinbase funds. More precisely: -
      -
    • The existing consensus rule requiring transactions that spend coinbase outputs to have an empty vout, is amended to only apply to transactions that spend transparent coinbase outputs.
    • -
    • The existing consensus rule requiring coinbase outputs to have 100 confirmations before they may be spent (coinbase maturity), is amended to only apply to transparent coinbase outputs. Specifically, it becomes: -

      A transaction MUST NOT spend a transparent output of a coinbase transaction from a block less than 100 blocks prior to the spend. Note that outputs of coinbase transactions include Founders’ Reward outputs [and potentially funding stream outputs].

      -
    • -
    -
  • -
  • Full note decryption of shielded coinbase outputs MUST succeed using the all-zero outgoing viewing key. More precisely, all shielded coinbase outputs MUST have valid note commitments when recovered using a sequence of 32 zero bytes as the outgoing viewing key.
  • -
-

Once the NU5 network upgrade activates:

-
    -
  • Coinbase transactions MAY contain Sapling and/or Orchard outputs.
  • -
-

This does not require any change to the consensus rule given above; it is a consequence of other rules as of NU5 activation.

-

Interaction with the Founders' Reward

-

This ZIP does not alter the existing Founders' Reward addresses.

-
-
-

Rationale

-

The ZIP does not require that all coinbase must be shielded immediately from activation of the network upgrade, so that miners and mining pools may gradually migrate from their existing transparent addresses to Sapling addresses. This also simplifies the consensus rules, because the Founders' Reward targets transparent addresses, and thus it remains necessary for the time being to support them. A future ZIP could require all coinbase to be shielded immediately.

-

Enforcing coinbase maturity at the consensus level for Sapling outputs would incur significant complexity in the consensus rules, because it would require special-casing coinbase note commitments in the Sapling commitment tree. The standard recommendation when spending a note is to select an anchor 10 blocks back from the current chain tip, which acts as a de-facto 10-block maturity on all notes, coinbase included. This might be proposed as a consensus rule in future.

-

There is another reason for shielded coinbase maturity being unnecessary: shielded coinbase outputs have the same effect on economic activity as regular shielded outputs. When a transparent address receives a coin in some "parent" transaction and later spends it, a tree of "direct child" transactions is created that all require the original parent transaction to be valid. However, most wallets treat unspent transparent outputs as a single "bucket of money", and select coins to spend without direct user input. This can create a disconnect between the economic activity of users (who might be intending to spend funds that they just received, creating "logical child" transactions), and their on-chain transaction graph.

-

For example, a mining pool that successfully mines a block will receive a coinbase output, but their subsequent payout to miners might instead spend ZEC that they already had before the block was mined. If the mining pool pays out for block X, and then a reorg or rollback occurs that causes the transparent coinbase in block X to become invalid, the payout transaction might still be mined on the new chain, even though the funds that the miner was logically spending do not exist there.

-

By contrast, when a reorg or rollback occurs that would cause a shielded coinbase output to disappear, it will also invalidate every shielded transaction that uses an anchor descending from the tree that the shielded coinbase output had been appended to. That is, all shielded economic activity would be rolled back in addition to the shielded coinbase output disappearing, ensuring that all logical child transactions are invalidated, not just direct child transactions. Therefore, there is no reason to make shielded coinbase a special case when the same behaviour already occurs in regular shielded notes.

-

Requiring that note commitments are valid when recovering using a fixed outgoing viewing key implies that target addresses and values for all Sapling outputs within the coinbase are revealed. This would be necessary to correctly enforce shielded Founders' Reward or funding stream outputs, and it is simpler to enforce this on all outputs. Additionally, this maintains the ability for network observers to track miners and mining pools. Meanwhile, the miners and mining pools could put useful or identifying text in the memo fields of the outputs, instead of storing it ad-hoc elsewhere in the coinbase transaction.

-
-

Security and Privacy Considerations

-

Sapling outputs in coinbase transactions are by design publicly viewable, in contrast to Sapling outputs in normal transactions. This does not introduce any privacy regressions relative to existing coinbase transactions, because coinbase output values and recipient addresses have always been public information. However, users with threat models that rely on keeping their Sapling address private (for example, to maintain post-quantum privacy), and who are also miners or mining pools, should use a coinbase-specific address when creating blocks.

-

Revealing the coinbase output notes does not enable anyone else to detect when the note is spent, which removes the need for a separate shielding step like is enforced for transparent coinbase outputs.

-
-

Deployment

-

This proposal will be deployed with the Heartwood network upgrade. 5

-
-

Reference Implementation

-

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

-
-

References

- - - - - - - -
1Information 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"
- - - - - - - -
2ZIP 200: Network Upgrade Mechanism
- - - - - - - -
3ZIP 205: Deployment of the Sapling Network Upgrade
- - - - - - - -
4ZIP 207: Split Founders' Reward
- - - - - - - -
5ZIP 250: Deployment of the Heartwood Network Upgrade
- - - - - - - -
6ZIP 252: Deployment of the NU5 Network Upgrade
-
-
- - \ No newline at end of file diff --git a/rendered/zip-0214.html b/rendered/zip-0214.html deleted file mode 100644 index d8ead7e6d..000000000 --- a/rendered/zip-0214.html +++ /dev/null @@ -1,477 +0,0 @@ - - - - ZIP 214: Consensus rules for a Zcash Development Fund - - - -
-
ZIP: 214
-Title: Consensus rules for a Zcash Development Fund
-Owners: Daira-Emma Hopwood <daira-emma@electriccoin.co>
-        Kris Nuttycombe <kris@nutty.land>
-Status: Revision 0: Final, Revision 1: Draft
-Category: Consensus
-Created: 2020-02-28
-License: MIT
-Discussions-To: <https://forum.zcashcommunity.com/t/community-sentiment-polling-results-nu4-and-draft-zip-1014/35560>
-

Terminology

-

The key words "MUST", "SHALL", "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 "Zcash" in this document is to be interpreted as described in the Zcash Trademark Donation and License Agreement (6 or successor agreement) while that agreement is in effect. On termination of that agreement, the term "Zcash" will refer to the continuations of the same Mainnet and Testnet block chains as determined by social consensus.

-

The term "network upgrade" in this document is to be interpreted as described in ZIP 200 8 and the Zcash Trademark Donation and License Agreement (6 or successor agreement).

-

The term "block subsidy" in this document is to be interpreted as described in section 3.10 of the Zcash Protocol Specification 3.

-

The term "halving" in this document are to be interpreted as described in sections 7.8 of the Zcash Protocol Specification 5.

-

The terms "Bootstrap Project" (or "BP"), "Electric Coin Company" (or "ECC"), "Zcash Foundation" (or "ZF"), "Major Grants", "BP slice", "ZF slice", and "MG slice" in this document are to be interpreted as described in ZIP 1014 13.

-

The terms "Zcash Community Grants (or "ZCG") and "Financial Privacy Foundation" (or "FPF") in this document are to be interpreted as described in ZIP 1015 14.

-

The terms "Testnet" and "Mainnet" are to be interpreted as described in section 3.12 of the Zcash Protocol Specification 4.

-

"Canopy" is the code-name for the fifth Zcash network upgrade, also known as Network Upgrade 4.

-

"NU6" is the code-name for the seventh Zcash network upgrade, also known as Network Upgrade 6.

-
-

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.

-
-

Applicability

-

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

-
-

Motivation

-

Motivation for the Zcash Development Fund itself is considered in ZIPs 1014 13 and 1015 14, which give high-level descriptions of the intended structure of the funds.

-

An important motivation for describing the consensus rules in a separate ZIP is to avoid making unintended changes to ZIPs 1014 and 1015, which have already been agreed between ECC, ZF, and the Zcash community. This facilitates critically assessing whether the consensus rule changes accurately reflect the intent of ZIPs 1014 and 1015.

-
-

Requirements

-

The primary requirement of this ZIP is to make changes to consensus rules necessary and sufficient to implement the intent of ZIPs 1014 and 1015.

-

The Zcash Development Fund distributes funding in ZEC obtained from block subsidies on Mainnet. This ZIP should also specify corresponding rules, addresses, and activation height for Testnet, in order to allow testing and auditing of the design and implementation within sufficient lead time before activation on Mainnet.

-
-

Non-requirements

-

This ZIP is not required to enforce provisions of ZIP 1014 or ZIP 1015 that fall outside what is implementable by Zcash consensus rules.

-
-

Specification

-

Revisions

-
    -
  • Revision 0: The initial version of this specification, as agreed upon by the Zcash community in ZIP 1014 13.
  • -
-
    -
  • Revision 1: Funding streams defined to start at Zcash's second halving, and last for one year, as agreed upon in ZIP 1015 14.
  • -
-
-

Activation

-

The Blossom network upgrade changed the height of the first halving to block height 1046400 10, as a consequence of reducing the block target spacing from 150 seconds to 75 seconds.

-

Since ZIP 1014 specifies that the Zcash Development Fund starts at the first halving, the activation height of Canopy on Mainnet therefore SHALL be 1046400.

-

Revision 0 of ZIP 207 9 SHALL be activated in Canopy.

-

Since ZIP 1015 specifies that the specified funding streams start at the second halving, the activation height of NU6 on Mainnet therefore SHALL be 2726400.

-

Revision 1 of ZIP 207 9 SHALL be activated in NU6.

-

As specified in 9, a funding stream is active for a span of blocks that includes the block at its start height, but excludes the block at its end height.

-
-

Funding Streams

-

As of Revision 0, the following funding streams are defined for Mainnet:

-
- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
StreamNumeratorDenominatorStart heightEnd height
FS_ZIP214_BP710010464002726400
FS_ZIP214_ZF510010464002726400
FS_ZIP214_MG810010464002726400
-
-

As of Revision 0, the following funding streams are defined for Testnet:

-
- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
StreamNumeratorDenominatorStart heightEnd height
FS_ZIP214_BP710010285002796000
FS_ZIP214_ZF510010285002796000
FS_ZIP214_MG810010285002796000
-
-

As of Revision 1, the following additional streams are defined for Mainnet:

- - - - - - - - - - - - - - - - - - - - - - - - - - -
StreamNumeratorDenominatorStart heightEnd height
FS_FPF_ZCG810027264003146400
FS_DEFERRED1210027264003146400
-

As of Revision 1, the following additional streams are defined for Testnet:

- - - - - - - - - - - - - - - - - - - - - - - - - - -
StreamNumeratorDenominatorStart heightEnd height
FS_FPF_ZCG810029760003396000
FS_DEFERRED1210029760003396000
-

Notes for Revision 0:

-
    -
  • The block heights of halvings are different between Testnet and Mainnet, as a result of different activation heights for the Blossom network upgrade (which changed the block target spacing). The end height of these funding streams corresponds to the second halving on each network.
  • -
  • On Testnet, the activation height of Canopy will be before the first halving. Therefore, the consequence of the above rules for Testnet is that the amount sent to each Zcash Development Fund recipient address will initially (before Testnet block height 1116000) be double the number of currency units as the corresponding initial amount on Mainnet. This reduces to the same number of currency units as on Mainnet, from Testnet block heights 1116000 (inclusive) to 2796000 (exclusive).
  • -
-

Notes for Revision 1:

-
    -
  • The new funding streams begin at the second halving for Mainnet, but the second halving on Testnet occurred prior to the introduction of the new funding streams. For both new funding streams on each network, the associated duration corresponds to approximately one year's worth of blocks.
  • -
-
-
-

Dev Fund Recipient Addresses for Revision 0

-

For each of Testnet and Mainnet, before deploying this ZIP in a node implementation with the activation height set for that network, each of the parties (ECC on behalf of BP; and ZF) SHALL generate sequences of recipient addresses to be used for each stream in each funding period:

-
    -
  • ECC SHALL generate the addresses for the FS_ZIP214_BP funding stream, which on Mainnet corresponds to the BP slice;
  • -
  • ZF SHALL generate the addresses for the FS_ZIP214_ZF and FS_ZIP214_MG funding streams, which on Mainnet correspond to the ZF slice and MG slice respectively.
  • -
-

Within each stream, the addresses MAY be independent, or MAY be repeated between funding periods. Each party SHOULD take account of operational security issues associated with potential compromise of the associated spending keys.

-

Funds sent to each Mainnet funding stream SHALL be governed by all requirements on the corresponding slice specified in ZIP 1014 13.

-

No requirements are imposed on the use of funds sent to Testnet funding streams.

-

Direct-grant option

-

ZIP 1014 specified a "direct-grant option" by which, if agreed upon by both ECC and ZF before Canopy activation, some portion of the MG slice may be directly assigned to the grantee(s), rather than accepted and disbursed by ZF. 13 However, this option was never taken up.

-
-
-
-

Mainnet Recipient Addresses for Revision 0

-
FS_ZIP214_BP.AddressList[0..47] = [
-  "t3LmX1cxWPPPqL4TZHx42HU3U5ghbFjRiif",
-  "t3Toxk1vJQ6UjWQ42tUJz2rV2feUWkpbTDs",
-  "t3ZBdBe4iokmsjdhMuwkxEdqMCFN16YxKe6",
-  "t3ZuaJziLM8xZ32rjDUzVjVtyYdDSz8GLWB",
-  "t3bAtYWa4bi8VrtvqySxnbr5uqcG9czQGTZ",
-  "t3dktADfb5Rmxncpe1HS5BRS5Gcj7MZWYBi",
-  "t3hgskquvKKoCtvxw86yN7q8bzwRxNgUZmc",
-  "t3R1VrLzwcxAZzkX4mX3KGbWpNsgtYtMntj",
-  "t3ff6fhemqPMVujD3AQurxRxTdvS1pPSaa2",
-  "t3cEUQFG3KYnFG6qYhPxSNgGi3HDjUPwC3J",
-  "t3WR9F5U4QvUFqqx9zFmwT6xFqduqRRXnaa",
-  "t3PYc1LWngrdUrJJbHkYPCKvJuvJjcm85Ch",
-  "t3bgkjiUeatWNkhxY3cWyLbTxKksAfk561R",
-  "t3Z5rrR8zahxUpZ8itmCKhMSfxiKjUp5Dk5",
-  "t3PU1j7YW3fJ67jUbkGhSRto8qK2qXCUiW3",
-  "t3S3yaT7EwNLaFZCamfsxxKwamQW2aRGEkh",
-  "t3eutXKJ9tEaPSxZpmowhzKhPfJvmtwTEZK",
-  "t3gbTb7brxLdVVghSPSd3ycGxzHbUpukeDm",
-  "t3UCKW2LrHFqPMQFEbZn6FpjqnhAAbfpMYR",
-  "t3NyHsrnYbqaySoQqEQRyTWkjvM2PLkU7Uu",
-  "t3QEFL6acxuZwiXtW3YvV6njDVGjJ1qeaRo",
-  "t3PdBRr2S1XTDzrV8bnZkXF3SJcrzHWe1wj",
-  "t3ZWyRPpWRo23pKxTLtWsnfEKeq9T4XPxKM",
-  "t3he6QytKCTydhpztykFsSsb9PmBT5JBZLi",
-  "t3VWxWDsLb2TURNEP6tA1ZSeQzUmPKFNxRY",
-  "t3NmWLvZkbciNAipauzsFRMxoZGqmtJksbz",
-  "t3cKr4YxVPvPBG1mCvzaoTTdBNokohsRJ8n",
-  "t3T3smGZn6BoSFXWWXa1RaoQdcyaFjMfuYK",
-  "t3gkDUe9Gm4GGpjMk86TiJZqhztBVMiUSSA",
-  "t3eretuBeBXFHe5jAqeSpUS1cpxVh51fAeb",
-  "t3dN8g9zi2UGJdixGe9txeSxeofLS9t3yFQ",
-  "t3S799pq9sYBFwccRecoTJ3SvQXRHPrHqvx",
-  "t3fhYnv1S5dXwau7GED3c1XErzt4n4vDxmf",
-  "t3cmE3vsBc5xfDJKXXZdpydCPSdZqt6AcNi",
-  "t3h5fPdjJVHaH4HwynYDM5BB3J7uQaoUwKi",
-  "t3Ma35c68BgRX8sdLDJ6WR1PCrKiWHG4Da9",
-  "t3LokMKPL1J8rkJZvVpfuH7dLu6oUWqZKQK",
-  "t3WFFGbEbhJWnASZxVLw2iTJBZfJGGX73mM",
-  "t3L8GLEsUn4QHNaRYcX3EGyXmQ8kjpT1zTa",
-  "t3PgfByBhaBSkH8uq4nYJ9ZBX4NhGCJBVYm",
-  "t3WecsqKDhWXD4JAgBVcnaCC2itzyNZhJrv",
-  "t3ZG9cSfopnsMQupKW5v9sTotjcP5P6RTbn",
-  "t3hC1Ywb5zDwUYYV8LwhvF5rZ6m49jxXSG5",
-  "t3VgMqDL15ZcyQDeqBsBW3W6rzfftrWP2yB",
-  "t3LC94Y6BwLoDtBoK2NuewaEbnko1zvR9rm",
-  "t3cWCUZJR3GtALaTcatrrpNJ3MGbMFVLRwQ",
-  "t3YYF4rPLVxDcF9hHFsXyc5Yq1TFfbojCY6",
-  "t3XHAGxRP2FNfhAjxGjxbrQPYtQQjc3RCQD"
-]
-
-FS_ZIP214_ZF.AddressList[0..47] = ["t3dvVE3SQEi7kqNzwrfNePxZ1d4hUyztBA1"] * 48
-
-FS_ZIP214_MG.AddressList[0..47] = ["t3XyYW8yBFRuMnfvm5KLGFbEVz25kckZXym"] * 48
-

(i.e. FS_ZIP214_ZF.AddressList and FS_ZIP214_MG.AddressList for Mainnet each consist of 48 repetitions of the same address).

-
-
-

Mainnet Recipient Addresses for Revision 1

-
-

FS_FPF_ZCG.AddressList[0..11] = ["t3cFfPt1Bcvgez9ZbMBFWeZsskxTkPzGCow"] * 12

-
-
-
-

Testnet Recipient Addresses for Revision 0

-
FS_ZIP214_BP.AddressList[0..50] = [
-  "t26ovBdKAJLtrvBsE2QGF4nqBkEuptuPFZz",
-  "t26ovBdKAJLtrvBsE2QGF4nqBkEuptuPFZz",
-  "t26ovBdKAJLtrvBsE2QGF4nqBkEuptuPFZz",
-  "t26ovBdKAJLtrvBsE2QGF4nqBkEuptuPFZz",
-  "t2NNHrgPpE388atmWSF4DxAb3xAoW5Yp45M",
-  "t2VMN28itPyMeMHBEd9Z1hm6YLkQcGA1Wwe",
-  "t2CHa1TtdfUV8UYhNm7oxbzRyfr8616BYh2",
-  "t2F77xtr28U96Z2bC53ZEdTnQSUAyDuoa67",
-  "t2ARrzhbgcpoVBDPivUuj6PzXzDkTBPqfcT",
-  "t278aQ8XbvFR15mecRguiJDQQVRNnkU8kJw",
-  "t2Dp1BGnZsrTXZoEWLyjHmg3EPvmwBnPDGB",
-  "t2KzeqXgf4ju33hiSqCuKDb8iHjPCjMq9iL",
-  "t2Nyxqv1BiWY1eUSiuxVw36oveawYuo18tr",
-  "t2DKFk5JRsVoiuinK8Ti6eM4Yp7v8BbfTyH",
-  "t2CUaBca4k1x36SC4q8Nc8eBoqkMpF3CaLg",
-  "t296SiKL7L5wvFmEdMxVLz1oYgd6fTfcbZj",
-  "t29fBCFbhgsjL3XYEZ1yk1TUh7eTusB6dPg",
-  "t2FGofLJXa419A76Gpf5ncxQB4gQXiQMXjK",
-  "t2ExfrnRVnRiXDvxerQ8nZbcUQvNvAJA6Qu",
-  "t28JUffLp47eKPRHKvwSPzX27i9ow8LSXHx",
-  "t2JXWPtrtyL861rFWMZVtm3yfgxAf4H7uPA",
-  "t2QdgbJoWfYHgyvEDEZBjHmgkr9yNJff3Hi",
-  "t2QW43nkco8r32ZGRN6iw6eSzyDjkMwCV3n",
-  "t2DgYDXMJTYLwNcxighQ9RCgPxMVATRcUdC",
-  "t2Bop7dg33HGZx3wunnQzi2R2ntfpjuti3M",
-  "t2HVeEwovcLq9RstAbYkqngXNEsCe2vjJh9",
-  "t2HxbP5keQSx7p592zWQ5bJ5GrMmGDsV2Xa",
-  "t2TJzUg2matao3mztBRJoWnJY6ekUau6tPD",
-  "t29pMzxmo6wod25YhswcjKv3AFRNiBZHuhj",
-  "t2QBQMRiJKYjshJpE6RhbF7GLo51yE6d4wZ",
-  "t2F5RqnqguzZeiLtYHFx4yYfy6pDnut7tw5",
-  "t2CHvyZANE7XCtg8AhZnrcHCC7Ys1jJhK13",
-  "t2BRzpMdrGWZJ2upsaNQv6fSbkbTy7EitLo",
-  "t2BFixHGQMAWDY67LyTN514xRAB94iEjXp3",
-  "t2Uvz1iVPzBEWfQBH1p7NZJsFhD74tKaG8V",
-  "t2CmFDj5q6rJSRZeHf1SdrowinyMNcj438n",
-  "t2ErNvWEReTfPDBaNizjMPVssz66aVZh1hZ",
-  "t2GeJQ8wBUiHKDVzVM5ZtKfY5reCg7CnASs",
-  "t2L2eFtkKv1G6j55kLytKXTGuir4raAy3yr",
-  "t2EK2b87dpPazb7VvmEGc8iR6SJ289RywGL",
-  "t2DJ7RKeZJxdA4nZn8hRGXE8NUyTzjujph9",
-  "t2K1pXo4eByuWpKLkssyMLe8QKUbxnfFC3H",
-  "t2TB4mbSpuAcCWkH94Leb27FnRxo16AEHDg",
-  "t2Phx4gVL4YRnNsH3jM1M7jE4Fo329E66Na",
-  "t2VQZGmeNomN8c3USefeLL9nmU6M8x8CVzC",
-  "t2RicCvTVTY5y9JkreSRv3Xs8q2K67YxHLi",
-  "t2JrSLxTGc8wtPDe9hwbaeUjCrCfc4iZnDD",
-  "t2Uh9Au1PDDSw117sAbGivKREkmMxVC5tZo",
-  "t2FDwoJKLeEBMTy3oP7RLQ1Fihhvz49a3Bv",
-  "t2FY18mrgtb7QLeHA8ShnxLXuW8cNQ2n1v8",
-  "t2L15TkDYum7dnQRBqfvWdRe8Yw3jVy9z7g"
-]
-
-FS_ZIP214_ZF.AddressList[0..50] = ["t27eWDgjFYJGVXmzrXeVjnb5J3uXDM9xH9v"] * 51
-
-FS_ZIP214_MG.AddressList[0..50] = ["t2Gvxv2uNM7hbbACjNox4H6DjByoKZ2Fa3P"] * 51
-

(i.e. FS_ZIP214_ZF.AddressList and FS_ZIP214_MG.AddressList for Testnet each consist of 51 repetitions of the same address).

-
-
-

Testnet Recipient Addresses for Revision 1

-
-

FS_FPF_ZCG.AddressList[0..12] = ["t2HifwjUj9uyxr9bknR8LFuQbc98c3vkXtu"] * 13

-
-
-
-
-

Rationale for Revision 0

-

The rationale for ZF generating the addresses for the FS_ZIP214_MG funding stream is that ZF is the financial recipient of the MG slice as specified in ZIP 1014. 13

-

Generation of recipient addresses for Testnet is specified to be done by the same parties as on Mainnet, in order to allow practicing each party's security procedures.

-

It was judged to be unnecessary to have a mechanism to update funding stream definitions (in case of security breach or changes to direct grant recipients) other than at network upgrades.

-
-

Deployment

-

Revision 0 of this proposal was deployed with Canopy. 11 Revision 1 of this proposal is intended to be deployed with NU6. 12

-
-

References

- - - - - - - -
1Information 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"
- - - - - - - -
2Zcash Protocol Specification, Version 2024.5.1 or later
- - - - - - - -
3Zcash Protocol Specification, Version 2024.5.1 [NU6]. Section 3.10: Block Subsidy, Funding Streams, and Founders' Reward
- - - - - - - -
4Zcash Protocol Specification, Version 2024.5.1 [NU6]. Section 3.12: Mainnet and Testnet
- - - - - - - -
5Zcash Protocol Specification, Version 2024.5.1 [NU6]. Section 7.8: Calculation of Block Subsidy, Funding Streams, and Founders' Reward
- - - - - - - -
6Zcash Trademark Donation and License Agreement
- - - - - - - -
7The Open Source Definition
- - - - - - - -
8ZIP 200: Network Upgrade Mechanism
- - - - - - - -
9ZIP 207: Funding Streams
- - - - - - - -
10ZIP 208: Shorter Block Target Spacing
- - - - - - - -
11ZIP 251: Deployment of the Canopy Network Upgrade
- - - - - - - -
12ZIP 253: Deployment of the NU6 Network Upgrade
- - - - - - - -
13ZIP 1014: Establishing a Dev Fund for ECC, ZF, and Major Grants
- - - - - - - -
14ZIP 1015: Block Reward Allocation for Non-Direct Development Funding
-
-
- - \ No newline at end of file diff --git a/rendered/zip-0215.html b/rendered/zip-0215.html deleted file mode 100644 index 4fe952bc9..000000000 --- a/rendered/zip-0215.html +++ /dev/null @@ -1,134 +0,0 @@ - - - - ZIP 215: Explicitly Defining and Modifying Ed25519 Validation Rules - - - - -
-
ZIP: 215
-Title: Explicitly Defining and Modifying Ed25519 Validation Rules
-Owners: Henry de Valence <hdevalence@zfnd.org>
-Status: Final
-Category: Consensus
-Created: 2020-04-27
-License: BSD-2-Clause
-

Terminology

-

The key words "MUST" and "MUST NOT" in this document is to be interpreted as described in BCP 14 1 when, and only when, they appear in all capitals.

-
-

Abstract

-

Zcash uses Ed25519 signatures as part of Sprout transactions. However, Ed25519 does not clearly define criteria for signature validity, and implementations conformant to RFC 8032 2 need not agree on whether signatures are valid. This is unacceptable for a consensus-critical application like Zcash. Currently, Zcash inherits criteria for signature validity from an obsolete version of libsodium. Instead, this ZIP settles the situation by explicitly defining the Ed25519 validity criteria and changing them to be compatible with batch validation.

-
-

Motivation

-

The lack of clear validity criteria for Ed25519 signatures poses a maintenance burden. The initial implementation of Zcash consensus in zcashd inherited validity criteria from a then-current version of libsodium (1.0.15). Due to a bug in libsodium, this was different from the intended criteria documented in the Zcash protocol specification 3 (before the specification was changed to match libsodium 1.0.15 in specification version 2020.1.2). Also, libsodium never guaranteed stable validity criteria, and changed behavior in a later point release. This forced zcashd to use an older version of the library before eventually patching a newer version to have consistent validity criteria. To be compatible, Zebra had to implement a special library, ed25519-zebra to provide Zcash-flavored Ed25519, attempting to match libsodium 1.0.15 exactly. And the initial attempt to implement ed25519-zebra was also incompatible, because it precisely matched the wrong compile-time configuration of libsodium.

-

In addition, the validity criteria used by Zcash preclude the use of batch validation of Ed25519 signatures. While signature validation is not the primary bottleneck for Zcash, it would be nice to be able to batch-validate signatures, as is the case for RedJubjub.

-
-

Specification

-

After activation of this ZIP, the - \(\mathsf{JoinSplitSig}\) - validation rules in 5 are changed to the following:

-
    -
  • - \(\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. 2
  • -
-

The language about - \(\mathsf{ExcludedPointEncodings}\) - in §5.4.5 of the Zcash specification 5 no longer applies.

-

It is not required that - \(\underline{A}\) - and - \(\underline{R}\) - are canonical encodings; in other words, the integer encoding the - \(y\) - -coordinate of the points may be unreduced modulo - \(2^{255}-19\) - .

-

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

-
-

Rationale

-

This change simplifies the Ed25519 validation logic and reduces future maintenance burden. Because multiplication by the cofactor admits more solutions to the validation equation, not fewer, it is compatible with all existing Ed25519 signatures on the chain.

-

It also allows the use of batch validation, which requires multiplication by the cofactor in the validation equation.

-
-

Security and Privacy Considerations

-

This change has no effect on honestly-generated signatures. Unlike the current validation rules, it makes it possible for a user to generate weak signing keys or to generate signing keys with nonzero torsion component and submit them to the blockchain. However, doing so provides them with no advantage, only compromise to their own security. Moreover, these cases are not a failure mode of any deployed implementation.

-
-

Deployment

-

This is intended to be deployed with the Canopy Network Upgrade 6, which is scheduled to activate on Mainnet 4 at block height 1046400.

-
-

References

- - - - - - - -
1Information 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"
- - - - - - - -
2RFC 8032: Edwards-Curve Digital Signature Algorithm (EdDSA)
- - - - - - - -
3Zcash Protocol Specification, Version 2020.1.1
- - - - - - - -
4Zcash Protocol Specification, Version 2021.2.16. Section 3.12: Mainnet and Testnet
- - - - - - - -
5Zcash Protocol Specification, Version 2021.2.16. Section 5.4.6: Ed25519
- - - - - - - -
6ZIP 251: Deployment of the Canopy Network Upgrade
-
-
- - \ No newline at end of file diff --git a/rendered/zip-0216.html b/rendered/zip-0216.html deleted file mode 100644 index 52bc7adab..000000000 --- a/rendered/zip-0216.html +++ /dev/null @@ -1,332 +0,0 @@ - - - - ZIP 216: Require Canonical Jubjub Point Encodings - - - - -
-
ZIP: 216
-Title: Require Canonical Jubjub Point Encodings
-Owners: Jack Grigg <jack@electriccoin.co>
-        Daira-Emma Hopwood <daira-emma@electriccoin.co>
-Status: Final
-Category: Consensus
-Created: 2021-02-11
-License: MIT
-Discussions-To: <https://github.com/zcash/zips/issues/400>
-

Terminology

-

The key word "MUST" in this document is 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. 12

-
-

Abstract

-

This ZIP fixes an oversight in the implementation of the Sapling consensus rules, by rejecting all non-canonical representations of Jubjub points.

-
-

Motivation

-

The Sapling specification was originally written with the intent that all values, including Jubjub points, are strongly typed with canonical representations. 6 This has significant advantages for security analysis, because it allows the protocol to be modelled with just the abstract types.

-

The intention of the Jubjub implementation (both in the jubjub crate 15 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 - \(u\!\) - -coordinate is zero, there are two encodings that will be accepted:

-
// Fix the sign of `u` if necessary
-let flip_sign = Choice::from((u.to_bytes()[0] ^ sign) & 1);
-let u_negated = -u;
-let final_u = Fq::conditional_select(&u, &u_negated, flip_sign);
-

This code accepts either sign bit, because u_negated == u.

-

There are two points on the Jubjub curve with - \(u\!\) - -coordinate zero:

-
    -
  • - \((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 - \(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.

-

Adjustments to the protocol specification were made in versions 2020.1.8, 2020.1.9, 2020.1.15, and 2021.1.17 to match the zcashd implementation. (The fact that this required 4 specification revisions to get right, conclusively demonstrates the problem.)

-
-

Specification

-

Let - \(\mathsf{abst}_{\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\) - , 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, - \(\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 - \(\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 3:

-
-
    -
  • the - \(\underline{R}\) - component (i.e. the first - \(32\) - bytes) of the - \(\mathtt{spendAuthSig}\) - RedDSA signature.
  • -
-
-

In transactions 10:

-
-
    -
  • the - \(\underline{R}\) - component (i.e. the first - \(32\) - bytes) of the - \(\mathtt{bindingSigSapling}\) - RedDSA signature.
  • -
-
-

In the plaintext obtained by decrypting the - \(\mathsf{C^{out}}\) - field of a Sapling transmitted note ciphertext 5:

-
-
    -
  • - \(\mathsf{pk}\star_{\mathsf{d}}\) - .
  • -
-
-

(This affects decryption of - \(\mathsf{C^{out}}\) - in all cases, but is consensus-critical only in the case of a shielded coinbase output. 10)

-

There are some additional fields in the consensus protocol that encode Jubjub points, but where non-canonical encodings MUST already be rejected as a side-effect of existing consensus rules.

-

In Sapling Spend descriptions:

-
-
    -
  • - \(\mathtt{cv}\) -
  • -
  • - \(\mathtt{rk}\) -
  • -
-
-

In Sapling Output descriptions 4:

-
-
    -
  • - \(\mathtt{cv}\) -
  • -
  • - \(\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)}\) - . These requirements MAY be enforced in advance of NU5 activation.

-

In Sapling addresses 8:

-
-
    -
  • the encoding of - \(\mathsf{pk_d}\) - .
  • -
-
-

In Sapling full viewing keys 9 and extended full viewing keys 11:

-
-
    -
  • the encoding of - \(\mathsf{ak}\) - .
  • -
-
-

( - \(\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 key formats.

-
-

Rationale

-

Zcash previously had a similar issue with non-canonical representations of points in Ed25519 public keys and signatures. In that case, given the prevalence of Ed25519 signatures in the wider ecosystem, the decision was made in ZIP 215 13 (which activated with the Canopy network upgrade 14) to allow non-canonical representations of points.

-

In Sapling, we are motivated instead to reject these non-canonical points:

-
    -
  • The chance of the identity occurring anywhere within the Sapling components of transactions from implementations following the standard protocol is cryptographically negligible.
  • -
  • This re-enables the aforementioned simpler security analysis of the Sapling protocol.
  • -
  • The Jubjub curve has a vastly-smaller scope of usage in the general cryptographic ecosystem than Curve25519 and Ed25519.
  • -
-

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}\) - 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 ( - \(\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\) - , 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 7 are also not affected.

-
-

Security and Privacy Considerations

-

This ZIP eliminates a potential source of consensus divergence between differing full node implementations. At the time of writing (February 2021), no such divergence exists for any production implementation of Zcash, but the alpha-stage zebrad node implementation would be susceptible to this issue.

-
-

Deployment

-

This ZIP is proposed to activate with Network Upgrade 5. Requirements on points encoded in payment addresses and full viewing keys MAY be enforced in advance of NU5 activation.

-
-

References

- - - - - - - -
1Information 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"
- - - - - - - -
2Zcash Protocol Specification, Version 2021.2.16 or later [NU5 proposal]
- - - - - - - -
3Zcash Protocol Specification, Version 2021.2.16 [NU5 proposal]. Section 4.4: Spend Descriptions
- - - - - - - -
4Zcash Protocol Specification, Version 2021.2.16 [NU5 proposal]. Section 4.5: Output Descriptions
- - - - - - - -
5Zcash Protocol Specification, Version 2021.2.16 [NU5 proposal]. Section 4.19.3 Decryption using a Full Viewing Key (Sapling and Orchard)
- - - - - - - -
6Zcash Protocol Specification, Version 2021.2.16 [NU5 proposal]. Section 5.4.9.3: Jubjub
- - - - - - - -
7Zcash Protocol Specification, Version 2021.2.16 [NU5 proposal]. Section 5.4.9.6: Pallas and Vesta
- - - - - - - -
8Zcash Protocol Specification, Version 2021.2.16 [NU5 proposal]. Section 5.6.3.1: Sapling Payment Addresses
- - - - - - - -
9Zcash Protocol Specification, Version 2021.2.16 [NU5 proposal]. Section 5.6.3.3: Sapling Full Viewing Keys
- - - - - - - -
10Zcash Protocol Specification, Version 2021.2.16 [NU5 proposal]. Section 7.1: Transaction Encoding and Consensus
- - - - - - - -
11ZIP 32: Shielded Hierarchical Deterministic Wallets. Sapling extended full viewing keys
- - - - - - - -
12ZIP 200: Network Upgrade Mechanism
- - - - - - - -
13ZIP 215: Explicitly Defining and Modifying Ed25519 Validation Rules
- - - - - - - -
14ZIP 251: Deployment of the Canopy Network Upgrade
- - - - - - - -
15jubjub Rust crate
-
-
- - \ No newline at end of file diff --git a/rendered/zip-0217.html b/rendered/zip-0217.html deleted file mode 100644 index 822e1fb60..000000000 --- a/rendered/zip-0217.html +++ /dev/null @@ -1,17 +0,0 @@ - - - - ZIP 217: Aggregate Signatures - - - -
-
ZIP: 217
-Title: Aggregate Signatures
-Owners: Daira-Emma Hopwood <daira-emma@electriccoin.co>
-Status: Reserved
-Category: Consensus
-Discussions-To: <https://github.com/zcash/zcash/issues/2914>
-
- - \ No newline at end of file diff --git a/rendered/zip-0219.html b/rendered/zip-0219.html deleted file mode 100644 index 296aa847b..000000000 --- a/rendered/zip-0219.html +++ /dev/null @@ -1,17 +0,0 @@ - - - - ZIP 219: Disabling Addition of New Value to the Sapling Chain Value Pool - - - -
-
ZIP: 219
-Title: Disabling Addition of New Value to the Sapling Chain Value Pool
-Owners: Daira-Emma Hopwood <daira-emma@electriccoin.co>
-Status: Reserved
-Category: Consensus
-Discussions-To: <https://github.com/zcash/zips/issues/428>
-
- - \ No newline at end of file diff --git a/rendered/zip-0220.html b/rendered/zip-0220.html deleted file mode 100644 index a557d39a1..000000000 --- a/rendered/zip-0220.html +++ /dev/null @@ -1,19 +0,0 @@ - - - - ZIP 220: Zcash Shielded Assets - - - -
-
ZIP: 220
-Title: Zcash Shielded Assets
-Owners: Jack Grigg <jack@electriccoin.co>
-        Daira-Emma Hopwood <daira-emma@electriccoin.co>
-Status: Withdrawn
-Category: Consensus
-Discussions-To: <https://github.com/zcash/zcash/issues/830>
-Pull-Request: <https://github.com/zcash/zips/pull/269>
-
- - \ No newline at end of file diff --git a/rendered/zip-0221.html b/rendered/zip-0221.html deleted file mode 100644 index a4e119e7b..000000000 --- a/rendered/zip-0221.html +++ /dev/null @@ -1,771 +0,0 @@ - - - - ZIP 221: FlyClient - Consensus-Layer Changes - - - - -
-
ZIP: 221
-Title: FlyClient - Consensus-Layer Changes
-Owners: Jack Grigg <jack@electriccoin.co>
-Original-Authors: Ying Tong Lai
-                  James Prestwich
-                  Georgios Konstantopoulos
-Status: Final
-Category: Consensus
-Created: 2019-03-30
-License: MIT
-

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 terms "consensus branch", "epoch", and "network upgrade" in this document are to be interpreted as described in ZIP 200. 8

-
-
Light client
-
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)\) - , where - \(\lambda\) - is a security parameter.
-
Negligible probability
-
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 new leaves without changing the value of existing nodes.
-
-
-

Abstract

-

This ZIP specifies modifications to the Zcash block header semantics and consensus rules in order to support the probabilistic verification FlyClient protocol 2. The hashFinalSaplingRoot commitment in the block header is replaced with a commitment to the root of a Merkle Mountain Range (MMR), that in turn commits to various features of the chain's history, including the Sapling commitment tree.

-
-

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 - \(\log(n)\) - operations and only requires knowledge of the previous subtree roots, of which there are fewer than - \(\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:

-
   /\
-  /  \
- /\  /\
-/\/\/\/\ /\ /
-

Note that the first leftmost peak is always the highest. We can number this structure in the order by which nodes would be created, if the leaves were inserted from left to right:

-
Altitude
-
-    3              14
-                 /    \
-                /      \
-               /        \
-              /          \
-    2        6            13
-           /   \        /    \
-    1     2     5      9     12     17
-         / \   / \    / \   /  \   /  \   /
-    0   0   1 3   4  7   8 10  11 15  16 18
-

and represent this numbering in a flat list:

-
- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
Position0123456789101112131415161718
Altitude0010012001001230010
-
-

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 algorithm:

-
    -
  1. Generate a node connecting the 2 left-most peaks, forming a new peak.
  2. -
  3. Repeat 1. until we have a single peak.
  4. -
-

Note that the extra nodes generated during the bagging process do not follow the above rules for jumping between nodes.

-
Altitude
-
-    5                     20g
-                         /  \
-    4                  19g   \
-                      /   \   \
-                     /     \   \
-                    /       \   \
-    3              14        \   \
-                 /    \       \   \
-                /      \       \   \
-               /        \       \   \
-              /          \       \   \
-    2        6           13       \   \
-           /   \       /    \      \   \
-    1     2     5      9     12     17  \
-         / \   / \    / \   /  \   /  \  \
-    0   0   1 3   4  7   8 10  11 15  16 18
-

MMR trees allow for efficient incremental set update operations (push, pop, prune). In addition, MMR update operations and Merkle proofs for recent additions to the leaf set are more efficient than other incremental Merkle tree implementations (e.g. Bitcoin's padded leafset, sparse Merkle trees, and Zcash's incremental note commitment trees).

-
-

Motivation

-

MMR proofs are used in the FlyClient protocol 2, to reduce the proof size needed for light clients to verify:

-
    -
  • the validity of a block chain received from a full node, 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 - \((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\) - .

-

( - \(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.

-
-

Specification

-

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 - \(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 of selected properties of a range of blocks without transmitting the entire range of blocks or headers.

-

Tree Node specification

-

Unless otherwise noted, all hashes use BLAKE2b-256 with the personalization field set to 'ZcashHistory' || CONSENSUS_BRANCH_ID. CONSENSUS_BRANCH_ID is the 4-byte little-endian encoding of the consensus branch ID for the epoch of the block containing the commitment. 8 Which is to say, each node in the tree commits to the consensus branch that produced it.

-

Each MMR node is defined as follows:

-
    -
  1. hashSubtreeCommitment -
    -
    Leaf node
    -
    -

    The consensus-defined block hash for the corresponding block.

    -
      -
    • 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 - \(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
    -
    -
      -
    • Both child nodes are serialized.
    • -
    • hashSubtreeCommitment is the BLAKE2b-256 hash of left_child || right_child.
    • -
    • For clarity, this digest uses the BLAKE2b-256 personalization string described above.
    • -
    -
    -
    -

    Serialized as char[32].

    -
  2. -
  3. nEarliestTimestamp -
    -
    Leaf node
    -
    The header's timestamp.
    -
    Internal or root node
    -
    Inherited from the left child.
    -
    -

    Serialized as nTime (uint32).

    -

    Note that a uint32 time value would overflow on 2106-02-07, but this field (and nLatestTimestamp below) can only hold values that occur in the nTime field of a block header, which is also of type uint32.

    -
  4. -
  5. nLatestTimestamp -
    -
    Leaf node
    -
    The header's timestamp.
    -
    Internal or root node
    -
    Inherited from the right child.
    -
    -

    Note that due to timestamp consensus rules, nLatestTimestamp may be smaller than nEarliestTimestamp in some subtrees. This may occur within subtrees smaller than PoWMedianBlockSpan blocks.

    -

    Serialized as nTime (uint32).

    -
  6. -
  7. nEarliestTargetBits -
    -
    Leaf node
    -
    The header's nBits field.
    -
    Internal or root node
    -
    Inherited from the left child.
    -
    -

    Serialized as nBits (uint32).

    -
  8. -
  9. nLatestTargetBits -
    -
    Leaf node
    -
    The header's nBits field.
    -
    Internal or root node
    -
    Inherited from the right child.
    -
    -

    Serialized as nBits (uint32).

    -
  10. -
  11. hashEarliestSaplingRoot -
    -
    Leaf node
    -
    Calculated as hashFinalSaplingRoot, as implemented in Sapling.
    -
    Internal or root node
    -
    Inherited from the left child.
    -
    -

    Serialized as char[32].

    -
  12. -
  13. hashLatestSaplingRoot -
    -
    Leaf node
    -
    Calculated as hashFinalSaplingRoot, as implemented in Sapling.
    -
    Internal or root node
    -
    Inherited from the right child.
    -
    -

    Serialized as char[32].

    -
  14. -
  15. nSubTreeTotalWork -
    -
    Leaf node
    -
    The protocol-defined work of the block: - \(\mathsf{floor}(2^{256} / (\mathsf{ToTarget}(\mathsf{nBits}) + 1))\) - . 4
    -
    Internal or root node
    -
    -

    The sum of the nSubTreeTotalWork fields of both children.

    -

    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 - \(2^{256}\) - or more is infeasible in practice.

    -
    -
    -

    Serialized as uint256.

    -
  16. -
  17. nEarliestHeight -
    -
    Leaf node
    -
    The height of the block.
    -
    Internal or root node
    -
    Inherited from the left child.
    -
    -

    Serialized as CompactSize uint.

    -
  18. -
  19. nLatestHeight -
    -
    Leaf node
    -
    The height of the block.
    -
    Internal or root node
    -
    Inherited from the right child.
    -
    -

    Serialized as CompactSize uint.

    -
  20. -
  21. nSaplingTxCount -
    -
    Leaf node
    -
    The number of transactions in the leaf block where either of vSpendsSapling or vOutputsSapling is non-empty.
    -
    Internal or root node
    -
    The sum of the nSaplingTxCount field of both children.
    -
    -

    Serialized as CompactSize uint.

    -
  22. -
  23. [NU5 onward] hashEarliestOrchardRoot -
    -
    Leaf node
    -
    Calculated as the note commitment root of the final Orchard treestate (similar to hashEarliestSaplingRoot in Sapling).
    -
    Internal or root node
    -
    Inherited from the left child.
    -
    -

    Serialized as char[32].

    -
  24. -
  25. [NU5 onward] hashLatestOrchardRoot -
    -
    Leaf node
    -
    Calculated as the note commitment root of the final Orchard treestate (similar to hashLatestSaplingRoot in Sapling).
    -
    Internal or root node
    -
    Inherited from the right child.
    -
    -

    Serialized as char[32].

    -
  26. -
  27. [NU5 onward] nOrchardTxCount -
    -
    Leaf node
    -
    The number of transactions in the leaf block where vActionsOrchard is non-empty.
    -
    Internal or root node
    -
    The sum of the nOrchardTxCount field of both children.
    -
    -

    Serialized as CompactSize uint.

    -
  28. -
-

The fields marked "[NU5 onward]" are omitted before NU5 activation 11.

-

Each node, when serialized, is between 147 and 171 bytes long (between 212 and 244 bytes after NU5 activation). The canonical serialized representation of a node is used whenever creating child commitments for future nodes. Other than the metadata commitments, the MMR tree's construction is standard.

-

Once the MMR has been generated, we produce hashChainHistoryRoot, which we define as the BLAKE2b-256 digest of the serialization of the root node.

-
-

Tree nodes and hashing (pseudocode)

-
def H(msg: bytes, consensusBranchId: bytes) -> bytes:
-    return blake2b256(msg, personalization=b'ZcashHistory' + consensusBranchId)
-
-class ZcashMMRNode():
-    # leaf nodes have no children
-    left_child: Optional[ZcashMMRNode]
-    right_child: Optional[ZcashMMRNode]
-
-    # commitments
-    hashSubtreeCommitment: bytes
-    nEarliestTimestamp: int
-    nLatestTimestamp: int
-    nEarliestTargetBits: int
-    nLatestTargetBits: int
-    hashEarliestSaplingRoot: bytes # left child's Sapling root
-    hashLatestSaplingRoot: bytes # right child's Sapling root
-    nSubTreeTotalWork: int  # total difficulty accumulated within each subtree
-    nEarliestHeight: int
-    nLatestHeight: int
-    nSaplingTxCount: int # number of Sapling transactions in block
-    # NU5 only.
-    hashEarliestOrchardRoot: Optional[bytes] # left child's Orchard root
-    hashLatestOrchardRoot: Optional[bytes] # right child's Orchard root
-    nSaplingTxCount: Optional[int] # number of Orchard transactions in block
-
-    consensusBranchId: bytes
-
-    @classmethod
-    def from_block(Z, block: ZcashBlock) -> ZcashMMRNode:
-        '''Create a leaf node from a block'''
-        return Z(
-            left_child=None,
-            right_child=None,
-            hashSubtreeCommitment=block.header_hash,
-            nEarliestTimestamp=block.timestamp,
-            nLatestTimestamp=block.timestamp,
-            nEarliestTargetBits=block.nBits,
-            nLatestTargetBits=block.nBits,
-            hashEarliestSaplingRoot=block.sapling_root,
-            hashLatestSaplingRoot=block.sapling_root,
-            nSubTreeTotalWork=calculate_work(block.nBits),
-            nEarliestHeight=block.height,
-            nLatestHeight=block.height,
-            nSaplingTxCount=block.sapling_tx_count,
-            hashEarliestOrchardRoot=block.orchard_root,
-            hashLatestOrchardRoot=block.orchard_root,
-            nOrchardTxCount=block.orchard_tx_count,
-            consensusBranchId=block.consensusBranchId)
-
-    def serialize(self) -> bytes:
-        '''serializes a node'''
-        buf = (self.hashSubtreeCommitment
-            + serialize_uint32(self.nEarliestTimestamp)
-            + serialize_uint32(self.nLatestTimestamp)
-            + serialize_uint32(self.nEarliestTargetBits)
-            + serialize_uint32(self.nLatestTargetBits)
-            + hashEarliestSaplingRoot
-            + hashLatestSaplingRoot
-            + serialize_uint256(self.nSubTreeTotalWork)
-            + serialize_compact_uint(self.nEarliestHeight)
-            + serialize_compact_uint(self.nLatestHeight)
-            + serialize_compact_uint(self.nSaplingTxCount))
-        if hashEarliestOrchardRoot is not None:
-            buf += (hashEarliestOrchardRoot
-                + hashLatestOrchardRoot
-                + serialize_compact_uint(self.nOrchardTxCount))
-        return buf
-
-
-def make_parent(
-        left_child: ZcashMMRNode,
-        right_child: ZcashMMRNode) -> ZcashMMRNode:
-    return ZcashMMRNode(
-        left_child=left_child,
-        right_child=right_child,
-        hashSubtreeCommitment=H(left_child.serialize() + right_child.serialize(),
-                                left_child.consensusBranchId),
-        nEarliestTimestamp=left_child.nEarliestTimestamp,
-        nLatestTimestamp=right_child.nLatestTimestamp,
-        nEarliestTargetBits=left_child.nEarliestTargetBits,
-        nLatestTargetBits=right_child.nLatestTargetBits,
-        hashEarliestSaplingRoot=left_child.sapling_root,
-        hashLatestSaplingRoot=right_child.sapling_root,
-        nSubTreeTotalWork=left_child.nSubTreeTotalWork + right_child.nSubTreeTotalWork,
-        nEarliestHeight=left_child.nEarliestHeight,
-        nLatestHeight=right_child.nLatestHeight,
-        nSaplingTxCount=left_child.nSaplingTxCount + right_child.nSaplingTxCount,
-        hashEarliestOrchardRoot=left_child.orchard_root,
-        hashLatestOrchardRoot=right_child.orchard_root,
-        nOrchardTxCount=(left_child.nOrchardTxCount + right_child.nOrchardTxCount
-                         if left_child.nOrchardTxCount is not None and right_child.nOrchardTxCount is not None
-                         else None),
-        consensusBranchId=left_child.consensusBranchId)
-
-def make_root_commitment(root: ZcashMMRNode) -> bytes:
-    '''Makes the root commitment for a blockheader'''
-    return H(root.serialize(), root.consensusBranchId)
-
-

Incremental push and pop (pseudocode)

-

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 2):

-
def get_peaks(node: ZcashMMRNode) -> List[ZcashMMRNode]:
-    peaks: List[ZcashMMRNode] = []
-
-    # Get number of leaves.
-    leaves = latest_height - (earliest_height - 1)
-    assert(leaves > 0)
-
-    # Check if the number of leaves is a power of two.
-    if (leaves & (leaves - 1)) == 0:
-        # Tree is full, hence a single peak. This also covers the
-        # case of a single isolated leaf.
-        peaks.append(node)
-    else:
-        # If the number of leaves is not a power of two, then this
-        # node must be internal, and cannot be a peak.
-        peaks.extend(get_peaks(left_child))
-        peaks.extend(get_peaks(right_child))
-
-    return peaks
-
-
-def bag_peaks(peaks: List[ZcashMMRNode]) -> ZcashMMRNode:
-    '''
-    "Bag" a list of peaks, and return the final root
-    '''
-    root = peaks[0]
-    for i in range(1, len(peaks)):
-        root = make_parent(root, peaks[i])
-    return root
-
-
-def append(root: ZcashMMRNode, leaf: ZcashMMRNode) -> ZcashMMRNode:
-    '''Append a leaf to an existing tree, return the new tree root'''
-    # recursively find a list of peaks in the current tree
-    peaks: List[ZcashMMRNode] = get_peaks(root)
-    merged: List[ZcashMMRNode] = []
-
-    # Merge peaks from right to left.
-    # This will produce a list of peaks in reverse order
-    current = leaf
-    for peak in peaks[::-1]:
-        current_leaves = current.latest_height - (current.earliest_height - 1)
-        peak_leaves = peak.latest_height - (peak.earliest_height - 1)
-
-        if current_leaves == peak_leaves:
-            current = make_parent(peak, current)
-        else:
-            merged.append(current)
-            current = peak
-    merged.append(current)
-
-    # finally, bag the merged peaks
-    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 - \(O(\log(k))\) - where - \(k\) - is the number of leaves in the right subtree of the MMR root.

-
def delete(root: ZcashMMRNode) -> ZcashMMRNode:
-    '''
-    Delete the rightmost leaf node from an existing MMR
-    Return the new tree root
-    '''
-
-    n_leaves = root.latest_height - (root.earliest_height - 1)
-    # if there were an odd number of leaves,
-    # simply replace root with left_child
-    if n_leaves & 1:
-        return root.left_child
-
-    # otherwise, we need to re-bag the peaks.
-    else:
-        # first peak
-        peaks = [root.left_child]
-
-        # we do this traversing the right (unbalanced) side of the tree
-        # we keep the left side (balanced subtree or leaf) of each subtree
-        # until we reach a leaf
-        subtree_root = root.right_child
-        while subtree_root.left_child:
-            peaks.push(subtree_root.left_child)
-            subtree_root = subtree_root.right_child
-
-    new_root = bag_peaks(peaks)
-    return new_root
-
-

Block header semantics and consensus rules

-

The following specification is accurate before NU5 activation. See 9 for header field changes in NU5.

-

The hashFinalSaplingRoot block header field (which was named hashReserved prior to the Sapling network upgrade) is renamed to hashLightClientRoot, to reflect its usage by light clients. (In NU5, this field is renamed again to hashBlockCommitments as specified in 9.)

-

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: 3

-
-

[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. This MUST NOT be interpreted as a root hash.

-

In subsequent blocks, hashLightClientRoot MUST be set to the value of hashChainHistoryRoot as specified above.

-

The block header byte format and version are not altered by this ZIP.

-
-
-

Rationale

-

Tree nodes

-

Nodes in the commitment tree are canonical and immutable. They are cheap to generate, as (with the exception of nSaplingTxCount and nOrchardTxCount) all metadata is already generated during block construction and/or checked during block validation. Nodes are relatively compact in memory. As of the original publication of this ZIP, approximately 140,000 blocks had elapsed since Sapling activation. Assuming a 164-byte commitment to each of these, we would have generated approximately 24 MB of additional storage cost for the set of leaf nodes (and an additional ~24 MB for storage of intermediate nodes).

-

hashSubtreeCommitment forms the structure of the commitment tree. Other metadata commitments were chosen to serve specific purposes. Originally variable-length commitments were placed last, so that most metadata in a node could be directly indexed. We considered using fixed-length commitments here, but opted for variable-length, in order to marginally reduce the memory requirements for managing and updating the commitment trees.

-

Orchard fields are placed last, in order to avoid complicating existing uses of the other fields.

-

In leaf nodes, some information is repeated. We chose to do this so that leaf nodes could be treated identically to internal and root nodes for all algorithms and (de)serializers. Leaf nodes are easily identifiable, as they will show proof of work in the hashSubtreeCommitment field (which commits to the block hash for leaf nodes), and their block range (calculated as nLatestHeight - (nEarliestHeight - 1)) will be precisely 1.

-

Personalized BLAKE2b-256 was selected to match existing Zcash conventions. Adding the consensus branch ID to the hash personalization string ensures that valid nodes from one consensus branch cannot be used to make false statements about parallel consensus branches.

-

FlyClient Requirements and Recommendations

-

These commitments enable FlyClient in the variable-difficulty model. Specifically, they allow light clients to reason about application of the difficulty adjustment algorithm over a range of blocks. They were chosen via discussion with an author of the FlyClient paper.

-
    -
  • nEarliestTimestamp
  • -
  • nLatestTimestamp
  • -
  • nEarliestTargetBits
  • -
  • nLatestTargetBits
  • -
  • nEarliestHeight
  • -
  • nLatestHeight
  • -
  • nSubTreeTotalWork
  • -
-
-

Non-FlyClient Commitments

-

Additional metadata commitments were chosen primarily to improve light client security guarantees. We specified commitments where we could see an obvious security benefit, but there may be other useful metadata that we missed. We're interested in feedback and suggestions from the implementers of the current light client.

-

We considered adding a commitment to the nullifier vector at each block. We would appreciate comments from light client teams on the utility of this commitment, as well as the proper serialization and commitment format for the nullifier vector, for possible inclusion in a future upgrade.

-
    -
  • hashEarliestSaplingRoot -
      -
    • Committing to the earliest Sapling root of a range of blocks allows light clients to check the consistency of treestate transitions over a range of blocks, without recalculating the root from genesis.
    • -
    -
  • -
  • hashLatestSaplingRoot -
      -
    • 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}\) - , 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.
    • -
    -
  • -
  • nSaplingTxCount -
      -
    • By committing to the number of Sapling transactions in blocks (and ranges of blocks), a light client may reliably learn whether a malicious server is witholding any Sapling transactions.
    • -
    • In addition, this commitment allows light clients to avoid syncing header ranges that do not contain Sapling transactions. As the primary cost of a light client is transmission of Equihash solution information in block headers, this optimization would significantly decrease the bandwidth requirements of light clients.
    • -
    • An earlier draft of this ZIP committed to the number of shielded transactions, counting both Sprout and Sapling. This commitment would not have been useful to light clients that only support Sapling addresses; they would not be able to distinguish between Sapling transactions being maliciously withheld, and Sprout transactions not being requested.
    • -
    • A commitment to the number of Sprout transactions in blocks was not included, because Sprout addresses are effectively deprecated at this point, and will not be supported by any light clients.
    • -
    • If a future network upgrade introduced a new shielded pool, a new commitment to that pool's transactions would be added, to similarly enable future light clients that do not support Sapling addresses.
    • -
    -
  • -
  • hashEarliestOrchardRoot, hashLatestOrchardRoot, and nOrchardTxCount -
      -
    • These are included with the same rationale as for Sapling.
    • -
    -
  • -
-
-
-

Header Format Change

-

The primary goal of the original authors was to minimize header changes; in particular, they preferred not to introduce changes that could affect mining hardware or embedded software. Altering the block header format would require changes throughout the ecosystem, so we decided against adding hashChainHistoryRoot to the header as a new field.

-

ZIP 301 states that "[Miner client software] SHOULD alert the user upon receiving jobs containing block header versions they do not know about or support, and MUST ignore such jobs." 12 As the only formally defined block header version is 4, any header version change requires changes to miner client software in order for miners to handle new jobs from mining pools. We therefore do not alter the block version for this semantic change. This does not make block headers ambiguous to interpret, because blocks commit to their block height inside their coinbase transaction, 7 and they are never handled in a standalone context (unlike transactions, which exist in the mempool outside of blocks).

-

Replacing hashFinalSaplingRoot with hashChainHistoryRoot does introduce the theoretical possibility of an attack where a miner constructs a Sapling commitment tree update that results in the same 32-byte value as the MMR root. We don't consider this a realistic attack, both because the adversary would need to find a preimage over 32 layers of Pedersen hash, and because light clients already need to update their code to include the consensus branch ID for the Heartwood network upgrade, and can simultaneously make changes to not rely on the value of this header field being the Sapling tree root.

-

We also considered putting hashChainHistoryRoot in the hashPrevBlock field as it commits to the entire chain history, but quickly realized it would require massive refactoring of the existing code base and would negatively impact performance. Reorgs in particular are fragile, performance-critical, and rely on backwards iteration over the chain history. If a chain were to be designed from scratch there may be some efficient implementation that would join these commitments, but it is clearly not appropriate for Zcash as it exists.

-

The calculation of hashChainHistoryRoot is not well-defined for the genesis block, 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 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.

-
-
-

Security and Privacy Considerations

-

This ZIP imposes an additional validation cost on new blocks. While this validation cost is small, it may exacerbate any existing DoS opportunities, particularly during abnormal events like long reorgs. Fortunately, these costs are logarithmic in the number of delete and append operations. In the worst case scenario, a well-resourced attacker could maintain 2 chains of approximately equal length, and alternate which chain they extend. This would result in repeated reorgs of increasing length.

-

Given the performance of BLAKE2b, we expect this validation cost to be negligible. However, it seems prudent to benchmark potential MMR implementations during the implementation process. Should the validation cost be higher than expected, there are several potential mitigations, e.g. holding recently seen nodes in memory after a reorg.

-

Generally, header commitments have no impact on privacy. However, FlyClient has additional security and privacy implications. Because FlyClient is a motivating factor for this ZIP, it seems prudent to include a brief overview. A more in-depth security analysis of FlyClient should be performed before designing a FlyClient-based light client ecosystem for Zcash.

-

FlyClient, like all light clients, requires a connection to a light client server. That server may collect information about client requests, and may use that information to attempt to deanonymize clients. However, because FlyClient proofs are non-interactive and publicly verifiable, they could be shared among many light clients after the initial server interaction.

-

FlyClient proofs are probabilistic. When properly constructed, there is negligible probability that a dishonest chain commitment will be accepted by the verifier. The security analysis assumes adversary mining power is bounded by a known fraction of combined mining power of honest nodes, and cannot drop or tamper with messages between client and full nodes. It also assumes the client is connected to at least one full node and knows the genesis block.

-

In addition, 2 only analyses these security properties in chain models with slowly adjusting difficulty, such as Bitcoin. That paper leaves their analysis in chains with rapidly adjusting difficulty –such as Zcash or Ethereum– as an open problem, and states that the FlyClient protocol provides only heuristic security guarantees in that case. However, as mentioned in FlyClient Requirements and Recommendations, additional commitments allowing light clients to reason about application of the difficulty adjustment algorithm were added in discussion with an author of the FlyClient paper. The use of these fields has not been analysed in the academic security literature. It would be possible to update them in a future network upgrade if further security analysis were to find any deficiencies.

-
-

Deployment

-

On the Zcash Mainnet and Testnet, this proposal will be deployed with the Heartwood network upgrade. 10

-

Additional fields are added on activation of the NU5 network upgrade 11, to support the new Orchard shielded protocol.

-
-

Additional Reading

- -
-

References

- - - - - - - -
1Information 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"
- - - - - - - -
2FlyClient protocol
- - - - - - - -
3Zcash Protocol Specification, Version 2021.2.16. Section 7.6: Block Header Encoding and Consensus
- - - - - - - -
4Zcash Protocol Specification, Version 2021.2.16. Section 7.7.5: Definition of Work
- - - - - - - -
5Zcash block primitive
- - - - - - - -
6MimbleWimble Grin MMR implementation
- - - - - - - -
7BIP 34: Block v2, Height in Coinbase
- - - - - - - -
8ZIP 200: Network Upgrade Mechanism
- - - - - - - -
9ZIP 244: Transaction Identifier Non-Malleability
- - - - - - - -
10ZIP 250: Deployment of the Heartwood Network Upgrade
- - - - - - - -
11ZIP 252: Deployment of the NU5 Network Upgrade
- - - - - - - -
12ZIP 301: Zcash Stratum Protocol
- - - - - - - -
13ZIP 307: Light Client Protocol for Payment Detection
-
-
- - \ No newline at end of file diff --git a/rendered/zip-0222.html b/rendered/zip-0222.html deleted file mode 100644 index 8bac39fa6..000000000 --- a/rendered/zip-0222.html +++ /dev/null @@ -1,380 +0,0 @@ - - - - ZIP 222: Transparent Zcash Extensions - - - -
-
ZIP: 222
-Title: Transparent Zcash Extensions
-Owners: Jack Grigg <jack@electriccoin.co>
-        Kris Nuttycombe <kris@electriccoin.co>
-Credits: Zaki Manian
-         Daira-Emma Hopwood
-         Sean Bowe
-Status: Draft
-Category: Consensus
-Created: 2019-07-01
-License: MIT
-

Terminology

-

The key words "MUST" 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 6.

-

The term "prefix-free" in this document is to be interpreted as to mean that no valid encoding of a value may have the same binary representation as any prefix of the binary encoding of another value of the same type.

-

The term "non-malleable" in this document is to be interpreted as described in ZIP 244 7.

-

The value MAX_MONEY is as defined in section 5.3 of the Zcash Protocol Specification 3.

-
-

Abstract

-

This proposal defines a modification to the consensus rules that enables complex forms of transparent output preconditions to be deployed in network upgrades. This in turn enables the creation of "transparent Zcash extensions" that augment the network's functionality in a carefully-defined and auditable fashion.

-
-

Motivation

-

Zcash supports a limited set of preconditions that may be imposed upon how funds, both transparent and shielded, may be spent. Spending limitations on transparent funds are defined by what may be encoded in Bitcoin script, and spending of shielded funds is even more restricted. As such, some use cases (for example, integration of BOLT support 9) are not yet supportable.

-

Transparent Zcash Extensions are intended to make it possible to incrementally add new functionality without modifying interpretation of the existing Bitcoin script, which is complex and potentially error-prone. Extensions may also serve as laboratories for evaluating demand for functionality which may eventually be candidates for inclusion in the consensus rules for shielded transactions.

-
-

Definitions

-
-
encumber
-
To set conditions that must be satisfied in order to spend some or all of a transaction's outputs.
-
precondition
-
A challenge that must be satisfied in order to gain spending authority over an encumbered amount.
-
witness
-
Evidence to be evaluated against the challenge encoded by a precondition.
-
-
-

Specification

-

Transparent Extensions

-

Transparent Extensions are modular software components that are distributed as part of the code of consensus implementations. An extension defines interpretation rules for several new pieces of data that are included as part of a transaction.

-

A Transparent Extension is identified by a numeric type. A Transparent Extension may also have several modes of operation, corresponding to different kinds of encumbrance within the extension's overall protocol.

-

The following three values are made available to the extension (in addition to type):

-
    -
  • A numeric mode.
  • -
  • A byte sequence precondition containing an encoding of the precondition that is prefix-free within this (type, mode).
  • -
  • A byte sequence witness containing an encoding of evidence purporting to satisfy the precondition. This encoding MUST be prefix-free within this (type, mode).
  • -
-

The extension is responsible for providing mode-specific parsing and serialization of these data fields. In addition, the extension MUST implement a deterministic verification algorithm tze_verify that takes as arguments mode, precondition, witness, and a context object. The context object provides deterministic public information about the transaction as well as the block chain (up to and including the block that the transaction is mined in). It returns true if the precondition is satisfied in that context, and false otherwise.

-

An extension MAY request that arbitrary public information about the transaction and block chain be included in the context object provided to it; these requirements MUST be satisfied by a caller integrating the extension at the integration point. Extensions SHOULD restrict the information requested to that which may be provided by node implementations in an efficient manner. For example, an extension SHOULD NOT require that it be provided full blocks in order to be able to construct or validate a precondition, and SHOULD minimize transaction data requested to that which are essential for its computational needs. In addition, while some preprocessing by the consensus-validating node may be requested, construction of such contextual data SHOULD NOT impose significant computational costs.

-

ZIPs that define a new transparent extension MUST completely specify the structure of all three of the specified values for each defined mode, as well as the behavior of tze_verify and any contextual information required.

-

The encoded forms of precondition and witness are not required to be constant-length, but SHOULD be solely determined by the pair (type, mode).

-

The introduction of TZEs by this ZIP produces a new transparent unspent outpoint set, distinct from the UTXO set, such that indices into this set of outpoints may be referred to by TZE inputs in spending transactions.

-
-

Encoding in transactions

-

We define a new transaction format that contains two new fields:

-
    -
  • tze_outputs: A list of pairs of: -
      -
    • The value being encumbered.
    • -
    • The precondition that must be satisfied to spend the value.
    • -
    -
  • -
  • tze_inputs: A list of pairs of: -
      -
    • An outpoint referencing a prior precondition.
    • -
    • A witness that satisfies it.
    • -
    -
  • -
-

The transaction format is required to be non-malleable, in the sense that any change to the effects of the transaction will change its transaction ID, but any valid change to a witness inside tze_inputs will not change the transaction ID. This will be specified in a separate ZIP.

-

A new version <TBD> transaction format and corresponding version group identifier <TBD> will be introduced in the hard-fork network upgrade that introduces TZE functionality. The version <TBD> format differs from the version 4 transaction format as follows: a length-prefixed encoding of TZE inputs and outputs are added to the serialized transaction format immediately following the fields representing transparent inputs and outputs.

- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
VersionFieldDescriptionType
...... as before......
>= 1tx_in_countvariable-length integercompactSize
>= 1tx_inlist of inputsvector
>= 1tx_out_countvariable-length integercompactSize
>= 1tx_outlist of outputsvector
>= <TBD>tze_in_countvariable-length integercompactSize
>= <TBD>tze_inlist of TZE inputsvector
>= <TBD>tze_out_countvariable-length integercompactSize
>= <TBD>tze_outlist of TZE outputsvector
>= 1lock_timeblock height or timestampuint32
...... as before......
-

Both tze_in and tze_out vectors make use of the common serialized form tze_data described below. Serialization of all integer and vector types is as with Bitcoin.

-

tze_data encoding:

- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
FieldDescriptionType
tze_idextension typecompactSize
tze_modeextension modecompactSize
tze_data_payload_lenlength of precondition/witness datacompactSize
tze_data_payloadserialized precondition/witness datatze_data_payload_len bytes
-

TZE Input Encoding:

- - - - - - - - - - - - - - - - - - - - - - - - - -
FieldDescriptionType
prevout_hashprevious txiduint256
prevout_inindex into previous txn's outputsuint32
witnesswitness for prevout's preconditiontze_data
-

TZE Output Encoding:

- - - - - - - - - - - - - - - - - - - - -
FieldDescriptionType
amountspendable amount, in zatoshiint64
preconditionencodes a precondition encumbering amounttze_data
-
-

Consensus rules

-

Once this ZIP becomes active, the following new consensus rules are enforced:

-
    -
  • For each (outpoint, witness) pair in tze_inputs: -
      -
    • outpoint MUST reference a precondition of the same type and mode in an already-mined transaction.
    • -
    • tze_verify(mode, precondition, witness, context) MUST return true.
    • -
    -
  • -
  • If a transaction has non-empty tze_inputs and non-empty tze_outputs, then every element in both fields MUST have the same type in order to eliminate the possibility for cross-extension attacks. As this is not a consideration in the case that only tze_inputs or only tze_outputs are present, the extension type MAY vary between elements in that case.
  • -
  • Non-coinbase transactions MUST have at least one of the following: - nonempty transparent inputs - nonempty shielded inputs - nonempty tze_inputs
  • -
-

The above rule replaces [Sapling onward] At least one of tx_in_count, -nShieldedSpend, and nJoinSplit MUST be nonzero in 4.

-
    -
  • Transactions MUST have at least one of the following: - nonempty transparent outputs - nonempty shielded outputs - nonempty tze_outputs
  • -
  • All amount field values of tze_output records MUST be nonnegative and not greater than MAX_MONEY.
  • -
  • The sum of amounts going out of the transparent value pool of a transaction (that is, Bitcoin-style outputs and TZE outputs, plus JoinSplit vpub_old values) MUST NOT exceed the sum of amounts going into that pool (that is, Bitcoin-style inputs and TZE inputs, plus JoinSplit vpub_new values, plus the Sapling valueBalance amount).
  • -
-
-

Changes to signatures over transaction digests

-

This ZIP MUST be deployed in conjunction with or after ZIP 244 7, which defines new non-malleable transaction identifier and signature digest algorithms.

-

The newly added parts of the transaction, excluding witness information (i.e. not the witness fields of TZE Input Encodings), will be included in transaction digests for transaction identifiers and signatures. See ZIP 245 8 for the specification of these new digests. If the changes in this ZIP are deployed, those described in ZIP 245 MUST be deployed as well.

-
-
-

Rationale

-

Transactions that have both TZE inputs and outputs are required to use a single extension type, in order to prevent cross-protocol attacks. The downside is that this prevents all TZE-encumbered value from being spent directly into a different TZE type; the value needs to go through a regular address in between. This restriction might be relaxed in future ZIPs for specific combinations of (type, mode) pairs that have been analyzed for cross-protocol attacks, but we opt here for a fail-safe default behaviour.

-

Transactions with TZE inputs which do not contain TZE outputs are not subject to single-extension or single-mode restrictions; likewise, transactions which contain TZE outputs without any TZE inputs may produce TZE outputs for multiple extension-type/mode pairs as the potential for cross-protocol attacks in this situation is negligible.

-

An earlier draft version of this ZIP stored the payloads inside transparent inputs and outputs. Although this had the advantage of not requiring a transaction format change, the consensus rules were significantly more complicated, and the design coupled the extension logic too tightly to the transparent address logic. Instead, this ZIP uses dedicated transaction fields, and a separate unspent output set.

-
-

Security and Privacy Considerations for Future TZE Implementations

-

This ZIP assumes that the base transaction format is non-malleable. However, the precondition and witness byte sequences are treated here as opaque. It is the responsibility of tze_verify to enforce the following:

-
    -
  • precondition MUST be non-malleable: any malleation MUST cause tze_verify to return false.
  • -
  • The output of tze_verify(mode, precondition, witness, context) MUST be deterministic.
  • -
-

ZIPs defining new extension types MUST include a section explaining how any potential sources of malleability are handled.

-

This ZIP includes restrictions to prevent cross-protocol attacks, but the extension mode is another potential attack surface. It is the responsibility of ZIPs defining new extensions to examine the potential for cross-mode attacks within their security analysis, and/or appropriately restrict which modes may be combined within a single transaction.

-
-

Reference Implementation

-
    -
  • Librustzcash reference implementation of TZE API: 10
  • -
  • Zcashd reference implementation of consensus rule changes: 11
  • -
-
-

Acknowledgements

-

The handler semantics of tze_verify were suggested by Zaki Manian, drawing on the design of Cosmos. Daira-Emma Hopwood and Sean Bowe gave useful feedback on an early draft of this ZIP, and helped to analyse the various sources of transaction ID malleability.

-

We would also like to thank the numerous other individuals who participated in discussions at Zcon1 that led to the earlier draft version of this ZIP.

-
-

References

- - - - - - - -
1Information 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"
- - - - - - - -
2Zcash Protocol Specification, Version 2021.2.16 or later
- - - - - - - -
3Zcash Protocol Specification, Version 2021.2.16. Section 5.3: Constants
- - - - - - - -
4Zcash Protocol Specification, Version 2021.2.16. Section 7.1: Transaction Consensus Rules
- - - - - - - -
5ZIP 32: Shielded Hierarchical Deterministic Wallets
- - - - - - - -
6ZIP 200: Network Upgrade Mechanism
- - - - - - - -
7ZIP 244: Transaction Non-Malleability Support
- - - - - - - -
8ZIP 245: Transaction Identifier Digests & Signature Validation for Transparent Zcash Extensions
- - - - - - - -
9Draft ZIP: Add support for Blind Off-chain Lightweight Transactions (Bolt) protocol
- - - - - - - -
10Rust language reference implementation of TZE API
- - - - - - - -
11zcashd reference implementation of consensus rule changes
-
-
- - \ No newline at end of file diff --git a/rendered/zip-0224.html b/rendered/zip-0224.html deleted file mode 100644 index 211d87e21..000000000 --- a/rendered/zip-0224.html +++ /dev/null @@ -1,464 +0,0 @@ - - - - ZIP 224: Orchard Shielded Protocol - - - - -
-
ZIP: 224
-Title: Orchard Shielded Protocol
-Owners: Daira-Emma Hopwood <daira-emma@electriccoin.co>
-        Jack Grigg <jack@electriccoin.co>
-        Sean Bowe <sean@electriccoin.co>
-        Kris Nuttycombe <kris@electriccoin.co>
-Original-Authors: Ying Tong Lai
-Status: Final
-Category: Consensus
-Created: 2021-02-27
-License: MIT
-Discussions-To: <https://github.com/zcash/zips/issues/435>
-

Terminology

-

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

-

The terms "Testnet" and "Mainnet" are to be interpreted as described in section 3.12 of the Zcash Protocol Specification 5.

-
-

Abstract

-

This document proposes the Orchard shielded protocol, which defines a new shielded pool with spending keys and payment addresses that are amenable to future scalability improvements.

-
-

Motivation

-

Zcash currently has two active shielded protocols and associated shielded pools:

-
    -
  • The Sprout shielded protocol (based on the Zerocash paper with improvements and security fixes 21), which as of February 2021 is a "closing" shielded pool into which no new ZEC can be sent.
  • -
  • The Sapling shielded protocol, which consisted of numerous improvements to functionality and improved performance by orders of magnitude, and as of Feburary 2021 is the "active" shielded pool.
  • -
-

Both of these shielded protocols suffer from two issues:

-
    -
  • Neither Sprout nor Sapling are compatible with known efficient scalability techniques. Recursive zero-knowledge proofs (where a proof verifies an earlier instance of itself along with new state) that are suitable for deployment in a block chain like Zcash require a cycle of elliptic curves. The Sprout protocol does not use elliptic curves and thus is an inherently inefficient protocol to implement inside a circuit, while the Sapling protocol uses curves for which there is no known way to construct an efficient curve cycle (or path to one).
  • -
  • The Sprout and Sapling circuits are implemented using a proving system (Groth16) that requires a "trusted setup": the circuit parameters are a Structured Reference String (SRS) with hidden structure, that if known could be used to create fake proofs and thus counterfeit funds. The parameters are in practice generated using a multiparty computation (MPC), where as long as at least one participant was honest and not compromised, the hidden structure is unrecoverable. The MPCs themselves have improved over the years (Zcash had 6 participants in the Sprout MPC, and around 90 per round in the Sapling MPC two years later 2), but it remains the case that generating these parameters is a point of risk within the protocol. For example, the original proving system used for the Sprout circuit (BCTV14) had a bug that made the Sprout shielded protocol vulnerable to counterfeiting, 3 which needed to be resolved by changing the proving system and running a new MPC.
  • -
-

We are thus motivated to deploy a new shielded protocol designed around a curve cycle, using a proving system that is both amenable to recursion and does not require an SRS.

-
-

Specification

-

The Orchard protocol MUST be implemented as specified in the Zcash Protocol Specification 4.

-

Given that the Orchard protocol largely follows the design of the Sapling protocol, we provide here a list of differences, with references to their normative specifications and associated design rationale.

-

Curves

-

The Orchard protocol uses the Pallas / Vesta curve cycle, in place of BLS12-381 and its embedded curve Jubjub:

-
    -
  • Pallas is used as the "application curve", on which the Orchard protocol itself is implemented (c/f 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 - \(\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}\) - : 16
  • -
  • Supporting evidence: 34
  • -
-
-

Proving system

-

Orchard uses the Halo 2 proving system 23 with the PLONKish arithmetization 22, instead of Groth16 and R1CS.

-

This proposal does not make use of Halo 2's support for recursive proofs, but this is expected to be leveraged by future protocol updates.

-
-

Circuit

-

Orchard uses a single circuit for both spends and outputs, similar to Sprout. An "action" contains both a single (possibly dummy) note being spent, and a single (possibly dummy) note being created.

-

An Orchard transaction contains a "bundle" of actions, and a single Halo 2 proof that covers all of the actions in the bundle.

-
    -
  • Action description: 8
  • -
  • Circuit statement: 9
  • -
  • Design rationale: 25
  • -
-
-

Commitments

-

The Orchard protocol has equivalent commitment schemes to Sapling. For non-homomorphic commitments, Orchard uses the PLONKish-efficient Sinsemilla in place of Bowe–Hopwood Pedersen hashes.

-
    -
  • Sinsemilla hash function: 11
  • -
  • Sinsemilla commitments: 14
  • -
  • Design rationale: 26
  • -
-
-

Commitment tree

-

Orchard uses an identical commitment tree structure to Sapling, except that we instantiate it with Sinsemilla instead of a Bowe–Hopwood Pedersen hash.

-
    -
  • Design rationale and considered alternatives: 27
  • -
-
-

Keys and addresses

-

Orchard keys and payment addresses are structurally similar to Sapling, with the following changes:

-
    -
  • 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.
  • -
  • - \(\mathsf{ovk}\) - is derived from - \(\mathsf{fvk}\) - , instead of being a component of the spending key.
  • -
  • All diversifiers now result in valid payment addresses.
  • -
-

There is no Bech32 encoding defined for an individual Orchard shielded payment address, incoming viewing key, or full viewing key. Instead we define unified payment addresses and viewing keys in 32. Orchard spending keys are encoded using Bech32m as specified in 20.

-

Orchard keys may be derived in a hierarchical deterministic (HD) manner. We do not adapt the Sapling HD mechanism from ZIP 32 to Orchard; instead, we define a hardened-only derivation mechanism (similar to Sprout).

-
    -
  • Key components diagram: 6
  • -
  • Key components specification: 10
  • -
  • Encodings: 17 18 19 20
  • -
  • HD key derivation specification: 29
  • -
  • Design rationale: 24
  • -
-
-

Notes

-

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

-
    -
  • Orchard notes: 7
  • -
-
-

Nullifiers

-

Nullifiers for Orchard notes are computed as:

-

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

-

where - \(F\) - is instantiated with Poseidon, and - \(\mathcal{G}\) - is a fixed independent base.

-
    -
  • Poseidon: 12
  • -
  • Design rationale and considered alternatives: 28
  • -
-
-

Signatures

-

Orchard uses RedPallas (RedDSA instantiated with the Pallas curve) as its signature scheme in place of Sapling's RedJubjub (RedDSA instantiated with the Jubjub curve).

-
    -
  • RedPallas: 13
  • -
-
-
-

Additional Rationale

-

The primary motivator for proposing a new shielded protocol and pool is the need to migrate spend authority to a recursion-friendly curve. Spend authority in the Sapling shielded pool is rooted in the Jubjub curve, but there is no known way to construct an efficient curve cycle (or path to one) from either Jubjub or BLS12-381.

-

Despite having recursion-friendliness as a design goal, we do not propose a recursive protocol in this ZIP. Deploying an entire scaling solution in a single upgrade would be a risky endeavour with a lot of moving parts. By focusing just on the components that enable a recursive protocol (namely the curve cycle and the proving system), we can start the migration of value to a scalable protocol before actually deploying the scalable protocol itself.

-

The remainder of the changes we make relative to Sapling are motivated by simplifying the Sapling protocol (and fixing deficiencies), and using protocol primitives that are more efficient in the UltraPLONK arithmetization.

-
-

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 - \(\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 - \(\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 in existing shielded pools cannot cause inflation of the Orchard pool.
  • -
  • Spending funds residing in the Orchard pool to a non-Orchard address will reveal the value of the transaction. This is a necessary side-effect of the transparent turnstile, but can be mitigated by migrating the majority of shielded activity to the Orchard pool and making these transactions a minority. Wallets SHOULD convey within their transaction creation UX that amounts are revealed in these situations. -
      -
    • Wallets SHOULD take steps to migrate their user bases to store funds uniformly within the Orchard pool. Best practices for wallet handling of multiple pools will be covered in a subsequent ZIP. 31
    • -
    -
  • -
-
-

Test Vectors

- -
-

Reference Implementation

- -
-

Deployment

-

This ZIP is proposed to activate with Network Upgrade 5.

-
-

References

- - - - - - - -
1Information 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"
- - - - - - - -
2Parameter Generation
- - - - - - - -
3Zcash Counterfeiting Vulnerability Successfully Remediated
- - - - - - - -
4Zcash Protocol Specification, Version 2021.2.16 or later [NU5 proposal]
- - - - - - - -
5Zcash Protocol Specification, Version 2021.2.16 [NU5 proposal]. Section 3.12: Mainnet and Testnet
- - - - - - - -
6Zcash Protocol Specification, Version 2021.2.16 [NU5 proposal]. Section 3.1: Payment Addresses and Keys
- - - - - - - -
7Zcash Protocol Specification, Version 2021.2.16 [NU5 proposal]. Section 3.2: Notes
- - - - - - - -
8Zcash Protocol Specification, Version 2021.2.16 [NU5 proposal]. Section 3.7: Action Transfers and their Descriptions
- - - - - - - -
9Zcash Protocol Specification, Version 2021.2.16 [NU5 proposal]. Section 4.17.4: Action Statement (Orchard)
- - - - - - - -
10Zcash Protocol Specification, Version 2021.2.16 [NU5 proposal]. Section 4.2.3: Orchard Key Components
- - - - - - - -
11Zcash Protocol Specification, Version 2021.2.16 [NU5 proposal]. Section 5.4.1.9: Sinsemilla Hash Function
- - - - - - - -
12Zcash Protocol Specification, Version 2021.2.16 [NU5 proposal]. Section 5.4.1.10: PoseidonHash Function
- - - - - - - -
13Zcash Protocol Specification, Version 2021.2.16 [NU5 proposal]. Section 5.4.7: RedDSA, RedJubjub, and RedPallas
- - - - - - - -
14Zcash Protocol Specification, Version 2021.2.16 [NU5 proposal]. Section 5.4.8.4: Sinsemilla commitments
- - - - - - - -
15Zcash Protocol Specification, Version 2021.2.16 [NU5 proposal]. Section 5.4.9.6: Pallas and Vesta
- - - - - - - -
16Zcash Protocol Specification, Version 2021.2.16 [NU5 proposal]. Section 5.4.9.8: Group Hash into Pallas and Vesta
- - - - - - - -
17Zcash Protocol Specification, Version 2021.2.16 [NU5 proposal]. Section 5.6.4.2: Orchard Raw Payment Addresses
- - - - - - - -
18Zcash Protocol Specification, Version 2021.2.16 [NU5 proposal]. Section 5.6.4.3: Orchard Raw Incoming Viewing Keys
- - - - - - - -
19Zcash Protocol Specification, Version 2021.2.16 [NU5 proposal]. Section 5.6.4.4: Orchard Raw Full Viewing Keys
- - - - - - - -
20Zcash Protocol Specification, Version 2021.2.16 [NU5 proposal]. Section 5.6.4.5: Orchard Spending Keys
- - - - - - - -
21Zcash Protocol Specification, Version 2021.2.16. Section 8: Differences from the Zerocash paper
- - - - - - - -
22The halo2 Book: 1.2 PLONKish Arithmetization
- - - - - - - -
23The halo2 Book: 3.1. Proving system
- - - - - - - -
24The Orchard Book: 3.1. Keys and addresses
- - - - - - - -
25The Orchard Book: 3.2. Actions
- - - - - - - -
26The Orchard Book: 3.3. Commitments
- - - - - - - -
27The Orchard Book: 3.4. Commitment tree
- - - - - - - -
28The Orchard Book: 3.5. Nullifiers
- - - - - - - -
29ZIP 32: Shielded Hierarchical Deterministic Wallets
- - - - - - - -
30ZIP 212: Allow Recipient to Derive Sapling Ephemeral Secret from Note Plaintext
- - - - - - - -
31ZIP 315: Best Practices for Wallet Handling of Multiple Pools
- - - - - - - -
32ZIP 316: Unified Addresses and Unified Viewing Keys
- - - - - - - -
33draft-irtf-cfrg-hash-to-curve-10: Hashing to Elliptic Curves
- - - - - - - -
34Pallas/Vesta supporting evidence
-
-
- - \ No newline at end of file diff --git a/rendered/zip-0225.html b/rendered/zip-0225.html deleted file mode 100644 index 1ab6b9415..000000000 --- a/rendered/zip-0225.html +++ /dev/null @@ -1,541 +0,0 @@ - - - - ZIP 225: Version 5 Transaction Format - - - - -
-
ZIP: 225
-Title: Version 5 Transaction Format
-Owners: Daira-Emma Hopwood <daira-emma@electriccoin.co>
-        Jack Grigg <jack@electriccoin.co>
-        Sean Bowe <sean@electriccoin.co>
-        Kris Nuttycombe <kris@electriccoin.co>
-Original-Authors: Ying Tong Lai
-Status: Final
-Category: Consensus
-Created: 2021-02-28
-License: MIT
-Discussions-To: <https://github.com/zcash/zips/issues/440>
-

Terminology

-

The key words "MUST" 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

-

This proposal defines an update to the Zcash peer-to-peer transaction format to include support for data elements required to support the Orchard protocol 2. The new transaction format defines well-bounded regions of the serialized form to serve each of the existing pools of funds, and adds and describes a new region containing Orchard-specific elements.

-

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 7.

-
-

Motivation

-

The new Orchard shielded pool requires serialized data elements that are distinct from any previous Zcash transaction. In addition, with the activation of ZIP 244, the serialized transaction format will no longer be consensus-critical. It makes sense at this point to define a format that can readily accommodate future extension in a systematic fashion, where elements required for support for a given pool are kept separate.

-
-

Requirements

-

The new format must fully support the Orchard 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.

-
-

Non-requirements

-

More general forms of extensibility, such as definining a key/value format that allows for parsers that are unaware of some components, are not required.

-
-

Specification

-

All fields in this specification are encoded as little-endian.

-

The Zcash transaction format for transaction version 5 is as follows:

-

Transaction Format

- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
BytesNameData TypeDescription
Common Transaction Fields
4headeruint32 -
-
Contains:
-
-
    -
  • fOverwintered flag (bit 31, always set)
  • -
  • version (bits 30 .. 0) – transaction version.
  • -
-
-
-
4nVersionGroupIduint32Version group ID (nonzero).
4nConsensusBranchIduint32Consensus branch ID (nonzero).
4lock_timeuint32Unix-epoch UTC time or block height, encoded as in Bitcoin.
4nExpiryHeightuint32A block height in the range {1 .. 499999999} after which the transaction will expire, or 0 to disable expiry. [ZIP-203]
Transparent Transaction Fields
variestx_in_countcompactSizeNumber of transparent inputs in tx_in.
variestx_intx_inTransparent inputs, encoded as in Bitcoin.
variestx_out_countcompactSizeNumber of transparent outputs in tx_out.
variestx_outtx_outTransparent outputs, encoded as in Bitcoin.
Sapling Transaction Fields
variesnSpendsSaplingcompactSizeNumber of Sapling Spend descriptions in vSpendsSapling.
96 * nSpendsSaplingvSpendsSaplingSpendDescriptionV5[nSpendsSapling]A sequence of Sapling Spend descriptions, encoded per protocol §7.3 ‘Spend Description Encoding and Consensus’.
variesnOutputsSaplingcompactSizeNumber of Sapling Output Decriptions in vOutputsSapling.
756 * nOutputsSaplingvOutputsSaplingOutputDescriptionV5[nOutputsSapling]A sequence of Sapling Output descriptions, encoded per protocol §7.4 ‘Output Description Encoding and Consensus’.
8valueBalanceSaplingint64The net value of Sapling Spends minus Outputs
32anchorSaplingbyte[32]A root of the Sapling note commitment tree at some block height in the past.
192 * nSpendsSaplingvSpendProofsSaplingbyte[192 * nSpendsSapling]Encodings of the zk-SNARK proofs for each Sapling Spend.
64 * nSpendsSaplingvSpendAuthSigsSaplingbyte[64 * nSpendsSapling]Authorizing signatures for each Sapling Spend.
192 * nOutputsSaplingvOutputProofsSaplingbyte[192 * nOutputsSapling]Encodings of the zk-SNARK proofs for each Sapling Output.
64bindingSigSaplingbyte[64]A Sapling binding signature on the SIGHASH transaction hash.
Orchard Transaction Fields
variesnActionsOrchardcompactSizeThe number of Orchard Action descriptions in vActionsOrchard.
820 * nActionsOrchardvActionsOrchardOrchardAction[nActionsOrchard]A sequence of Orchard Action descriptions, encoded per §7.5 ‘Action Description Encoding and Consensus’.
1flagsOrchardbyte -
-
An 8-bit value representing a set of flags. Ordered from LSB to MSB:
-
-
    -
  • enableSpendsOrchard
  • -
  • enableOutputsOrchard
  • -
  • The remaining bits are set to 0.
  • -
-
-
-
8valueBalanceOrchardint64The net value of Orchard spends minus outputs.
32anchorOrchardbyte[32]A root of the Orchard note commitment tree at some block height in the past.
variessizeProofsOrchardcompactSizeLength in bytes of proofsOrchard. Value is - \(2720 + 2272 \cdot \mathtt{nActionsOrchard}\) - .
sizeProofsOrchardproofsOrchardbyte[sizeProofsOrchard]Encoding of aggregated zk-SNARK proofs for Orchard Actions.
64 * nActionsOrchardvSpendAuthSigsOrchardbyte[64 * nActionsOrchard]Authorizing signatures for each Orchard Action.
64bindingSigOrchardbyte[64]An Orchard binding signature on the SIGHASH transaction hash.
-
    -
  • 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}}`\) - is defined to be 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 - \(\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 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.
  • -
-

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.

-
-

Sapling Spend Description (SpendDescriptionV5)

- - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
BytesNameData TypeDescription
32cvbyte[32]A value commitment to the net value of the input note.
32nullifierbyte[32]The nullifier of the input note.
32rkbyte[32]The randomized validating key for the element of spendAuthSigsSapling corresponding to this Spend.
-

The encodings of each of these elements are defined in §7.3 ‘Spend Description Encoding and Consensus’ of the Zcash Protocol Specification 3.

-
-

Sapling Output Description (OutputDescriptionV5)

- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
BytesNameData TypeDescription
32cvbyte[32]A value commitment to the net value of the output note.
32cmubyte[32]The u-coordinate of the note commitment for the output note.
32ephemeralKeybyte[32]An encoding of an ephemeral Jubjub public key.
580encCiphertextbyte[580]The encrypted contents of the note plaintext.
80outCiphertextbyte[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 4.

-
-

Orchard Action Description (OrchardAction)

- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
BytesNameData TypeDescription
32cvbyte[32]A value commitment to the net value of the input note minus the output note.
32nullifierbyte[32]The nullifier of the input note.
32rkbyte[32]The randomized validating key for the element of spendAuthSigsOrchard corresponding to this Action.
32cmxbyte[32]The x-coordinate of the note commitment for the output note.
32ephemeralKeybyte[32]An encoding of an ephemeral Pallas public key
580encCiphertextbyte[580]The encrypted contents of the note plaintext.
80outCiphertextbyte[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 5.

-
-
-

Alternatives

-

The original version of ZIP-225 included Sprout-related fields nJoinSplit, vJoinSplit, joinSplitPubKey, and joinSplitSig in the V5 transaction format. The Electric Coin Company and Zcash Foundation teams have elected to remove these fields from the V5 transaction format as part of the continuing process of deprecation of the Sprout shielded pool. As a consequence of these fields being removed:

-
    -
  • This effectively prohibits migration transactions that would directly move funds from the Sprout pool to the Orchard pool. Sprout -> Transparent and Sprout -> Sapling migration transactions will still be supported when using the V4 transaction format.
  • -
-

Removing these fields reduces the complexity of the NU5 upgrade in the following ways:

-
    -
  • V5 parsing and serialization code does not need to take these fields into account.
  • -
  • ZIP 244 7 transaction identifier, signature hash, and authorizing data commitment computations are simplified by excluding consideration of these fields.
  • -
-

Removal of these fields means that that in the future, removing the support for the V4 transaction format will also effectively end support for Sprout transactions on the Zcash network, though it might be possible to restore limited support for migration via a future ZIP 222 6 extension or by other means not yet determined.

-

The original definitions for the transaction fields that have been removed are:

- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
Sprout Transaction Fields
variesnJoinSplitcompactSizeThe number of JoinSplit descriptions in vJoinSplit.
1698 * nJoinSplitvJoinSplitJSDescriptionGroth16[nJoinSplit]A sequence of JoinSplit descrptions using Groth16 proofs, encoded per §7.2 ‘JoinSplit Description Encoding and Consensus’.
32joinSplitPubKeybyte[32]An encoding of a JoinSplitSig public validating key.
64joinSplitSigbyte[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 - \(\mathtt{nJoinSplit} > 0\) - .
  • -
-
-

Reference implementation

- -
-

References

- - - - - - - -
1Information 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"
- - - - - - - -
2Zcash Protocol Specification, Version 2021.2.16 or later [NU5 proposal]
- - - - - - - -
3Zcash Protocol Specification, Version 2021.2.16 [NU5 proposal]. Section 4.4: Spend Descriptions
- - - - - - - -
4Zcash Protocol Specification, Version 2021.2.16 [NU5 proposal]. Section 4.5: Output Descriptions
- - - - - - - -
5Zcash Protocol Specification, Version 2021.2.16 [NU5 proposal]. Section 4.6: Action Descriptions
- - - - - - - -
6ZIP 222: Transparent Zcash Extensions
- - - - - - - -
7ZIP 244: Transaction Identifier Non-Malleability
- - - - - - - -
8ZIP 307: Light Client Protocol for Payment Detection
-
-
- - \ No newline at end of file diff --git a/rendered/zip-0226.html b/rendered/zip-0226.html deleted file mode 100644 index dfa6cf2ba..000000000 --- a/rendered/zip-0226.html +++ /dev/null @@ -1,799 +0,0 @@ - - - - ZIP 226: Transfer and Burn of Zcash Shielded Assets - - - - -
-
ZIP: 226
-Title: Transfer and Burn of Zcash Shielded Assets
-Owners: Pablo Kogan <pablo@qed-it.com>
-        Vivek Arte <vivek@qed-it.com>
-        Daira-Emma Hopwood <daira-emma@electriccoin.co>
-        Jack Grigg <str4d@electriccoin.co>
-Credits: Daniel Benarroch
-         Aurelien Nicolas
-         Deirdre Connolly
-         Teor
-Status: Draft
-Category: Consensus
-Created: 2022-05-01
-License: MIT
-Discussions-To: <https://github.com/zcash/zips/issues/618>
-Pull-Request: <https://github.com/zcash/zips/pull/680>
-

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 terms "Orchard" and "Action" in this document are to be interpreted as described in ZIP 224 4.

-

The terms "Asset", "Custom Asset" and "Wrapped Asset" in this document are to be interpreted as described in ZIP 227 5.

-

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 - \(\mathsf{AssetBase}\) - (see 6) 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

-

This ZIP (ZIP 226) proposes the Zcash Shielded Assets (ZSA) protocol, in conjunction with ZIP 227 5. The ZSA protocol is an extension of the Orchard protocol that enables the issuance, transfer and burn of custom Assets on the Zcash chain. The issuance of such Assets is defined in ZIP 227 5, while the transfer and burn of such Assets is defined in this ZIP (ZIP 226). While the proposed ZSA protocol is a modification to the Orchard protocol, it has been designed with adaptation to possible future shielded protocols in mind.

-
-

Motivation

-

None of the currently deployed Zcash transfer protocols support Custom Assets. Enabling multi-asset support on the Zcash chain will open the door for a host of applications, and enhance the ecosystem with application developers and Asset custody institutions for issuance and bridging purposes. This ZIP builds on the issuance mechanism introduced in ZIP 227 5.

-
-

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 - \(\mathsf{AssetId}\!\) - . This Asset Identifier maps to an Asset Base - \(\mathsf{AssetBase}\) - that is stored in Orchard-based ZSA notes. These terms are formally defined in ZIP 227 5.

-

The Asset Identifier (via means of the Asset Digest and Asset Base) will be used to enforce that the balance of an Action Description 15 28 is preserved across Assets (see the Orchard Binding Signature 18), 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 29 30, 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 20, 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 25, and as the base point in the value commitment 24. 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 17 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 5.

-

We include the ability to pause the ZSA functionality, via a - \(\mathsf{enableZSA}\) - boolean flag. When this flag is set to false, it is not possible to perform transactions involving Custom Assets (the Action statement as modified for ZSAs will not be satisfied).

-

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

-

Most of the protocol is kept the same as the Orchard protocol released with NU5, except for the following.

-

Asset Identifiers

-

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 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}}\!\) - .

-

Rationale for Asset Identifiers

-

In future network and protocol upgrades, the same Asset description string can be carried on, potentially mapping into a different shielded pool. In that case, nodes should know how to transform the Asset Identifier, the Asset Digest, and the Asset Base from one shielded pool to another, while ensuring there are no balance violations 3.

-
-
-

Note Structure & Commitment

-

Let - \(\mathsf{Note^{OrchardZSA}}\) - be the type of a ZSA note, i.e. - \(\mathsf{Note^{OrchardZSA}} := \mathsf{Note^{Orchard}} \times \mathbb{P}^*\!\) - .

-

An Orchard ZSA note differs from an Orchard note 14 by additionally including the Asset Base, - \(\mathsf{AssetBase}\!\) - . So a ZSA note is a tuple - \((\mathsf{g_d}, \mathsf{pk_d}, \mathsf{v}, \text{ρ}, \text{ψ}, \mathsf{AssetBase})\!\) - , where

-
    -
  • - \(\mathsf{AssetBase} : \mathbb{P}^*\) - is the unique element of the Pallas group 26 that identifies each Asset in the Orchard protocol, defined as the Asset Base in ZIP 227 5, 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 - \(\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}\)
-

where - \(\mathbb{P}, \ell_{\mathbb{P}}, q_{\mathbb{P}}\) - are as defined for the Pallas curve 26, and where - \(\mathsf{NoteCommit^{Orchard}}.\!\mathsf{Trapdoor}\) - and - \(\mathsf{Orchard}.\!\mathsf{Output}\) - are as defined in the Zcash protocol specification 16. This note commitment scheme is instantiated using the Sinsemilla Commitment 25 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}\)
-

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}\)
-

Note that - \(\mathsf{repr}_{\mathbb{P}}\) - and - \(\mathsf{GroupHash}^{\mathbb{P}}\) - are as defined for the Pallas curve 26, - \(\ell^{\mathsf{Orchard}}_{\mathsf{base}}\) - is as defined in §5.3 22, and - \(\mathsf{I2LEBSP}\) - is as defined in §5.1 21 of the Zcash protocol specification.

-

The nullifier is generated in the same manner as in the Orchard protocol 19.

-

The ZSA note plaintext also includes the Asset Base in addition to the components in the Orchard note plaintext 27. It consists of

-
\((\mathsf{leadByte} : \mathbb{B}^{\mathbb{Y}}, \mathsf{d} : \mathbb{B}^{[\ell_{\mathsf{d}}]}, \mathsf{v} : \{0 .. 2^{\ell_{\mathsf{value}}} - 1\}, \mathsf{rseed} : \mathbb{B}^{\mathbb{Y}[32]}, \mathsf{asset\_base} : \mathbb{B}^{[\ell_{\mathbb{P}}]}, \mathsf{memo} : \mathbb{B}^{\mathbb{Y}[512]})\)
-

Rationale for Note Commitment

-

In the ZSA 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 25 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 23. ZSA 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}\)
-

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 ZSA notes.

-
-
-

Value Commitment

-

In the case of the Orchard-based ZSA protocol, the value of different Asset Identifiers in a given transaction will be committed using a different value base point. The value commitment becomes:

-
\(\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.

-

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 - \(\mathsf{ValueCommit^{Orchard}_{rcv}}(\mathsf{v})\) - as defined in 4 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 24 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.

-
-
-

Burn Mechanism

-

The burn mechanism is a transparent extension to the transfer protocol that enables a specific amount of any Asset Identifier to be "destroyed". The burn mechanism does NOT send Assets to a non-spendable address, it simply reduces the total number of units of a given Custom Asset in circulation at the consensus level. It is enforced at the consensus level, by using an extension of the value balance mechanism used for ZEC Assets. Burning makes it globally provable that a given amount of an Asset has been destroyed.

-

The sender includes a - \(\mathsf{v_{AssetId}}\) - variable for every Asset Identifier that is being burnt, which represents the amount of that Asset being burnt. As described in the Orchard-ZSA Transaction Structure, this is separate from the regular - \(\mathsf{valueBalance^{Orchard}}\) - that is the default transparent value for the ZEC Asset, and represents either the transaction fee, or the amount of ZEC changing pools (e.g. to Sapling or Transparent).

-

For every Custom Asset that is burnt, we add to the - \(\mathsf{assetBurn}\) - set the tuple - \((\mathsf{AssetBase_{AssetId}}, \mathsf{v_{AssetId}})\) - such that the validator of the transaction can compute the value commitment with the corresponding value base point of that Asset. This ensures that the values are all balanced out with respect to the Asset Identifiers in the transfer.

-
\(\mathsf{assetBurn} := \{ (\mathsf{AssetBase}_{\mathsf{AssetId}} : \mathbb{P}^*, \mathsf{v_{AssetId}} : \{1 .. 2^{\ell_{\mathsf{value}}} - 1\}) \,|\, \mathsf{AssetId} \in \mathsf{AssetIdsToBurn} \}\)
-

We denote by - \(L\) - the cardinality of the - \(\mathsf{assetBurn}\) - set.

-

Additional Consensus Rules

-
    -
  1. We require that for every - \((\mathsf{AssetBase_{AssetId}}, \mathsf{v_{AssetId}}) \in \mathsf{assetBurn}, \mathsf{AssetBase_{AssetId}} \neq \mathcal{V}^{\mathsf{Orchard}}\!\) - . That is, ZEC or TAZ is not allowed to be burnt by this mechanism.
  2. -
  3. We require that for every - \((\mathsf{AssetBase_{AssetId}}, \mathsf{v_{AssetId}}) \in \mathsf{assetBurn}, \mathsf{v_{AssetId}} \neq 0\!\) - .
  4. -
  5. We require that there be no duplication of Custom Assets in the - \(\mathsf{assetBurn}\) - set. That is, every - \(\mathsf{AssetBase_{AssetId}}\) - has at most one entry in - \(\mathsf{assetBurn}\!\) - .
  6. -
-

Note: Even if this mechanism allows having transparent ↔ shielded Asset transfers in theory, the transparent protocol will not be changed with this ZIP to adapt to a multiple Asset structure. This means that unless future consensus rules changes do allow it, unshielding will not be possible for Custom Assets.

-
-
-

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 18, with the addition of the burn information.

-

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:

-
\(\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 - \(\mathsf{bvk}\!\) - , the verifier MUST use it to verify the binding signature on the SIGHASH transaction hash.

-

Rationale for Value Balance Verification

-

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:

-
\(((\sum_{i \in S_{\mathsf{ZEC}}} \mathsf{cv}^{\mathsf{net}}_i) + (\sum_{j \in S_{\mathsf{CA}}} \mathsf{cv}^{\mathsf{net}}_j)) - ([\mathsf{v^{balanceOrchard}}]\,\mathcal{V}^{\mathsf{Orchard}} + [0]\,\mathcal{R}^{\mathsf{Orchard}}) - (\sum_{(\mathsf{AssetBase}, \mathsf{v}) \in \mathsf{assetBurn}} [\mathsf{v}]\,\mathsf{AssetBase} + [0]\,\mathcal{R}^{\mathsf{Orchard}})\)
-

This equation contains the balance check of the Orchard protocol 18. 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 - \(\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 - \(\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, - \(\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

-

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 - \(\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.

-

When the number of input notes of a particular Asset Base is smaller than the required number of output notes for the same Asset Base, the sender creates Split Inputs of the same Asset Base as padding for the input-less Actions. Note that we do not care about whether the previously issued note copied to create a Split Input is owned by the sender, or whether it was nullified before.

-

Wallets and other clients have to choose from the following to ensure the Asset Base is preserved for the output note of a Split Action:

-
    -
  1. The Split Input note could be another note containing the same Asset Base that is being spent by this transaction (but not by this Split Input).
  2. -
  3. The Split Input note could be a different unspent note containing the same Asset Base (note that the note will not actually be spent).
  4. -
  5. The Split Input note could be an already spent note containing the same Asset Base (note that by zeroing the value in the circuit, we prevent double spending).
  6. -
-

For Split Notes, the nullifier is generated as follows:

-
\(\mathsf{nf_{old}} = \mathsf{Extract}_{\mathbb{P}} ([(\mathsf{PRF^{nfOrchard}_{nk}} (\text{ρ}^{\mathsf{old}}) + \text{ψ}') \bmod q_{\mathbb{P}}]\,\mathcal{K}^\mathsf{Orchard} + \mathsf{cm^{old}} + \mathcal{L}^\mathsf{Orchard})\)
-

where - \(\text{ψ}'\) - is sampled uniformly at random on - \(\mathbb{F}_{q_{\mathbb{P}}}\!\) - , - \(\mathcal{K}^{\mathsf{Orchard}}\) - is the Orchard Nullifier Base as defined in 19, and - \(\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 17 to the Actions that have not been assigned input notes.

-

The Orchard technique requires modification for the ZSA 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 ZSA 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.

-
-
-

Circuit Statement

-

Every ZSA Action statement is closely similar to the Orchard Action statement 20, except for a few additions that ensure the security of the Asset Identifier system. We detail these changes below.

-

All modifications in the Circuit are detailed in 31.

-

Asset Base Equality

-

The following constraints must be added to ensure that the input and output note are of the same - \(\mathsf{AssetBase}\!\) - :

-
    -
  • 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 20, - \(\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 20, - \(\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 - \(\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 - \(\mathsf{enableZSA}\) - Flag

-

The following constraints must be added to disable transactions involving Custom Assets when the - \(\mathsf{enableZSA}\) - flag is set to false:

-
    -
  • 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, - \(\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

-

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}})\) -
    • -
    -
    -
    -
  • -
  • -
    -
    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 - \((\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

-

The input note in the old note commitment integrity check must either include an Asset Base (ZSA note) or not (pre-ZSA Orchard note). If the note is a pre-ZSA Orchard note, the note commitment is computed in the original Orchard fashion 16. If the note is a ZSA note, the note commitment is computed as defined in the Note Structure & Commitment section.

-
-
-
-

Orchard-ZSA Transaction Structure

-

The transaction format for v6 transactions is described in ZIP 230 10.

-
-

TxId Digest

-

The transaction digest algorithm defined in ZIP 244 11 is modified by the ZSA protocol to add a new branch for issuance information, along with modifications within the orchard_digest to account for the inclusion of the Asset Base. The details of these changes are described in this section, and highlighted using the [UPDATED FOR ZSA] or [ADDED FOR ZSA] text label. We omit the details of the sections that do not change for the ZSA protocol.

-

txid_digest

-

A BLAKE2b-256 hash of the following values

-
T.1: header_digest       (32-byte hash output)
-T.2: transparent_digest  (32-byte hash output)
-T.3: sapling_digest      (32-byte hash output)
-T.4: orchard_digest      (32-byte hash output)  [UPDATED FOR ZSA]
-T.5: issuance_digest     (32-byte hash output)  [ADDED FOR ZSA]
-

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

-

T.4: orchard_digest

-

When Orchard Actions are present in the transaction, this digest is a BLAKE2b-256 hash of the following values

-
T.4a: orchard_actions_compact_digest      (32-byte hash output)          [UPDATED FOR ZSA]
-T.4b: orchard_actions_memos_digest        (32-byte hash output)          [UPDATED FOR ZSA]
-T.4c: orchard_actions_noncompact_digest   (32-byte hash output)          [UPDATED FOR ZSA]
-T.4d: flagsOrchard                        (1 byte)
-T.4e: valueBalanceOrchard                 (64-bit signed little-endian)
-T.4f: anchorOrchard                       (32 bytes)
-
T.4a: orchard_actions_compact_digest
-

A BLAKE2b-256 hash of the subset of Orchard Action information intended to be included in an updated version of the ZIP-307 12 CompactBlock format for all Orchard Actions belonging to the transaction. For each Action, the following elements are included in the hash:

-
T.4a.i  : nullifier            (field encoding bytes)
-T.4a.ii : cmx                  (field encoding bytes)
-T.4a.iii: ephemeralKey         (field encoding bytes)
-T.4a.iv : encCiphertext[..84]  (First 84 bytes of field encoding)  [UPDATED FOR ZSA]
-

The personalization field of this hash is the same as in ZIP 244:

-
"ZTxIdOrcActCHash"
-
-
T.4b: orchard_actions_memos_digest
-

A BLAKE2b-256 hash of the subset of Orchard shielded memo field data for all Orchard Actions belonging to the transaction. For each Action, the following elements are included in the hash:

-
T.4b.i: encCiphertext[84..596] (contents of the encrypted memo field)  [UPDATED FOR ZSA]
-

The personalization field of this hash remains identical to ZIP 244:

-
"ZTxIdOrcActMHash"
-
-
T.4c: orchard_actions_noncompact_digest
-

A BLAKE2b-256 hash of the remaining subset of Orchard Action information not intended for inclusion in an updated version of the the ZIP 307 12 CompactBlock format, for all Orchard Actions belonging to the transaction. For each Action, the following elements are included in the hash:

-
T.4d.i  : cv                    (field encoding bytes)
-T.4d.ii : rk                    (field encoding bytes)
-T.4d.iii: encCiphertext[596..]  (post-memo suffix of field encoding)  [UPDATED FOR ZSA]
-T.4d.iv : outCiphertext         (field encoding bytes)
-

The personalization field of this hash is defined identically to ZIP 244:

-
"ZTxIdOrcActNHash"
-
-
-

T.5: issuance_digest

-

The details of the computation of this value are in ZIP 227 7.

-
-
-
-

Signature Digest and Authorizing Data Commitment

-

The details of the changes to these algorithms are in ZIP 227 8 9.

-
-

Security and Privacy Considerations

-
    -
  • After the protocol upgrade, the Orchard shielded pool will be shared by the Orchard protocol and the Orchard-ZSA protocol.
  • -
  • Deploying the Orchard-ZSA protocol does not necessitate disabling the Orchard protocol. Both can co-exist and be addressed via different transaction versions (V5 for Orchard and V6 for Orchard-ZSA). Due to this, Orchard note commitments can be distinguished from Orchard-ZSA note commitments. This holds whether or not the two protocols are active simultaneously.
  • -
  • Orchard-ZSA note commitments for the native asset (ZEC) are indistinguishable from Orchard-ZSA note commitments for non-native Assets.
  • -
  • When including new Assets we would like to maintain the amount and identifiers of Assets private, which is achieved with the design.
  • -
  • We prevent a potential malleability attack on the Asset Identifier by ensuring the output notes receive an Asset Base that exists on the global state.
  • -
-
-

Other Considerations

-

Transaction Fees

-

The fee mechanism for the upgrades proposed in this ZIP will follow the mechanism described in ZIP 317 for the ZSA protocol upgrade 13.

-
-

Backward Compatibility

-

In order to have backward compatibility with the ZEC notes, we have designed the circuit to support both ZEC and ZSA 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 - \(\mathsf{AssetBase}\) - value as well.
  • -
  • The existing Orchard shielded pool will continue to be used for the new ZSA 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 ZSA-based Actions will include split input notes and will not include dummy input notes.
  • -
-
-

Deployment

-

The Zcash Shielded Assets protocol will be deployed in a subsequent Network Upgrade.

-
-
-

Test Vectors

- -
-

Reference Implementation

- -
-

References

- - - - - - - -
1Information 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"
- - - - - - - -
2ZIP 200: Network Upgrade Mechanism
- - - - - - - -
3ZIP 209: Prohibit Negative Shielded Chain Value Pool Balances
- - - - - - - -
4ZIP 224: Orchard
- - - - - - - -
5ZIP 227: Issuance of Zcash Shielded Assets
- - - - - - - -
6ZIP 227: Issuance of Zcash Shielded Assets: Specification: Asset Identifier
- - - - - - - -
7ZIP 227: Issuance of Zcash Shielded Assets: TxId Digest - Issuance
- - - - - - - -
8ZIP 227: Issuance of Zcash Shielded Assets: Signature Digest
- - - - - - - -
9ZIP 227: Issuance of Zcash Shielded Assets: Authorizing Data Commitment
- - - - - - - -
10ZIP 230: Version 6 Transaction Format
- - - - - - - -
11ZIP 244: Transaction Identifier Non-Malleability
- - - - - - - -
12ZIP 307: Light Client Protocol for Payment Detection
- - - - - - - -
13ZIP 317: Proportional Transfer Fee Mechanism - Pull Request #667 for ZSA Protocol ZIPs
- - - - - - - -
14Zcash Protocol Specification, Version 2023.4.0. Section 3.2: Notes
- - - - - - - -
15Zcash Protocol Specification, Version 2023.4.0. Section 3.7: Action Transfers and their Descriptions
- - - - - - - -
16Zcash Protocol Specification, Version 2023.4.0. Section 4.1.8: Commitment
- - - - - - - -
17Zcash Protocol Specification, Version 2023.4.0. Section 4.8.3: Dummy Notes (Orchard)
- - - - - - - -
18Zcash Protocol Specification, Version 2023.4.0. Section 4.14: Balance and Binding Signature (Orchard)
- - - - - - - -
19Zcash Protocol Specification, Version 2023.4.0. Section 4.16: Note Commitments and Nullifiers
- - - - - - - -
20Zcash Protocol Specification, Version 2023.4.0. Section 4.17.4: Action Statement (Orchard)
- - - - - - - -
21Zcash Protocol Specification, Version 2023.4.0. Section 5.1: Integers, Bit Sequences, and Endianness
- - - - - - - -
22Zcash Protocol Specification, Version 2023.4.0. Section 5.3: Constants
- - - - - - - -
23Zcash Protocol Specification, Version 2023.4.0. Section 5.4.1.9: Sinsemilla hash function
- - - - - - - -
24Zcash Protocol Specification, Version 2023.4.0. Section 5.4.8.3: Homomorphic Pedersen commitments (Sapling and Orchard)
- - - - - - - -
25Zcash Protocol Specification, Version 2023.4.0. Section 5.4.8.4: Sinsemilla commitments
- - - - - - - -
26Zcash Protocol Specification, Version 2023.4.0. Section 5.4.9.6: Pallas and Vesta
- - - - - - - -
27Zcash Protocol Specification, Version 2023.4.0. Section 5.5: Encodings of Note Plaintexts and Memo Fields
- - - - - - - -
28Zcash Protocol Specification, Version 2023.4.0. Section 7.5: Action Description Encoding and Consensus
- - - - - - - -
29User-Defined Assets and Wrapped Assets
- - - - - - - -
30Comment on Generalized Value Commitments
- - - - - - - -
31Modifications to the Orchard circuit for the ZSA Protocol
-
-
- - \ No newline at end of file diff --git a/rendered/zip-0227.html b/rendered/zip-0227.html deleted file mode 100644 index 0b0fa59b5..000000000 --- a/rendered/zip-0227.html +++ /dev/null @@ -1,988 +0,0 @@ - - - - ZIP 227: Issuance of Zcash Shielded Assets - - - - -
-
ZIP: 227
-Title: Issuance of Zcash Shielded Assets
-Owners: Pablo Kogan <pablo@qed-it.com>
-        Vivek Arte <vivek@qed-it.com>
-        Daira-Emma Hopwood <daira-emma@electriccoin.co>
-        Jack Grigg <str4d@electriccoin.co>
-Credits: Daniel Benarroch
-         Aurelien Nicolas
-         Deirdre Connolly
-         Teor
-Status: Draft
-Category: Consensus
-Created: 2022-05-01
-License: MIT
-Discussions-To: <https://github.com/zcash/zips/issues/618>
-Pull-Request: <https://github.com/zcash/zips/pull/680>
-

Terminology

-

The key words "MUST", "MUST NOT", "SHOULD", "RECOMMENDED", 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 7.

-

The terms "Orchard" and "Action" in this document are to be interpreted as described in ZIP 224 8.

-

We define the following additional terms:

-
    -
  • Asset: A type of note that can be transferred on the Zcash blockchain. Each Asset is identified by an Asset Identifier Specification: Asset Identifier. -
      -
    • ZEC is the default (and currently the only defined) Asset for the Zcash mainnet.
    • -
    • TAZ is the default (and currently the only defined) Asset for the Zcash testnet.
    • -
    • We use the term "Custom Asset" to refer to any Asset other than ZEC and TAZ.
    • -
    -
  • -
  • Native Asset: a Custom Asset with issuance defined on the Zcash blockchain.
  • -
  • Wrapped Asset: a Custom Asset with native issuance defined outside the Zcash blockchain.
  • -
  • Issuance Action: an instance of a single issuance of a Zcash Shielded Asset. It defines the issuance of a single Asset Identifier.
  • -
  • Issuance Bundle: the bundle in the transaction that contains all the issuance actions of that transaction.
  • -
-
-

Abstract

-

This ZIP (ZIP 227) proposes the Zcash Shielded Assets (ZSA) protocol, in conjunction with ZIP 226 9. This protocol is an extension of the Orchard protocol that enables the creation, transfer and burn of Custom Assets on the Zcash chain. The creation of such Assets is defined in this ZIP (ZIP 227), while the transfer and burn of such Assets is defined in ZIP 226 9. This ZIP must only be implemented in conjunction with ZIP 226 9. The proposed issuance mechanism is only valid for the Orchard-ZSA transfer protocol, because it produces notes that can only be transferred under ZSA.

-
-

Motivation

-

This ZIP introduces the issuance mechanism for Custom Assets on the Zcash chain. While originally part of a single ZSA ZIP, the issuance mechanism turned out to be substantial enough to stand on its own and justify the creation of this supporting ZIP for ZIP 226 9.

-

This ZIP only enables transparent issuance. As a first step, transparency will allow for proper testing of the applications that will be most used in the Zcash ecosystem, and will enable the supply of Assets to be tracked.

-

The issuance mechanism described in this ZIP is broad enough for issuers to either create Assets on Zcash (i.e. Assets that originate on the Zcash blockchain), as well as for institutions to create bridges from other chains and import Wrapped Assets. This enables what we hope will be a useful set of applications.

-
-

Use Cases

-

The design presented in this ZIP enables issuance of shielded Assets in various modes:

-
    -
  • The issuer may or may not know the receivers of the issued Asset in advance.
  • -
  • The Asset can be of non-fungible type, where each Asset type can be made part of a single “series”.
  • -
  • The supply of the Asset can be limited in advance or not.
  • -
  • The Asset can be a wrapped version of an Asset issued by another chain (as long as there is a bridge that supports transfer of that Asset between chains).
  • -
-

See the Concrete Applications section for more details.

-
-

Requirements

-
    -
  • Any user of the Zcash blockchain can issue Custom Assets on chain.
  • -
  • The issuance mechanism should enable public tracking of the supply of the Assets on the Zcash blockchain.
  • -
  • 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 - \(\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

-

The Orchard-ZSA Protocol adds the following keys to the key components 18 19:

-
    -
  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. -
  3. 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.
  4. -
-

The relations between these keys are shown in the following diagram:

-
- -
Diagram of Issuance Key Components for the Orchard-ZSA Protocol
-
-

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 16.

-

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 - \(\mathsf{IssueAuthSig}\) - signature scheme are as follows:

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

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 17.

-

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

-

Issuance authorizing key generation for hierarchical deterministic wallets

-

The issuance authorizing key is generated using the Orchard master key derivation procedure defined in ZIP 32 3. We reuse the functions defined there in what follows in this section.

-

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{MasterKeyGen}(\texttt{"ZIP32ZSAIssue_V1"}, S)\!\) - .

-

As in ZIP 32 for Orchard 4, we only use hardened child key derivation for the issuance authorizing key. We reuse the - \(\mathsf{CDKsk}\) - function for Orchard child key derivation from ZIP 32.

-

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:

-
    -
  • - \(\mathit{purpose}\) - : a constant set to - \(227\) - (i.e. - \(\mathtt{0xe3}\!\) - ). - \(\mathit{purpose}'\) - is thus - \(227'\) - (or - \(\mathtt{0x800000e3}\!\) - ) following the BIP 43 recommendation.
  • -
  • - \(\mathit{coin\_type}\) - : Defined as in ZIP 32 5.
  • -
  • - \(\mathit{account}\) - : fixed to index - \(0\!\) - .
  • -
-

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 - \(\mathsf{IssueAuthSig}.\!\mathsf{DerivePublic}\; : \; (\mathsf{isk}\; : \; \mathsf{IssueAuthSig}.\!\mathsf{Private}) \to \mathsf{IssueAuthSig}.\!\mathsf{Public}\) - as:

-
    -
  • - \(\mathsf{ik} := \textit{PubKey}(\mathsf{isk})\) -
  • -
  • Return - \(\bot\) - if the - \(\textit{PubKey}\) - algorithm invocation fails, otherwise return - \(\mathsf{ik}\!\) - .
  • -
-

where the - \(\textit{PubKey}\) - algorithm is defined in BIP 340 16. 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}\) - 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.

-
-
-

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}\) - as:

-
    -
  • 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 - \(\mathsf{Sign}\) - algorithm is defined in BIP 340 and - \(a\) - denotes the auxiliary data used in BIP 340 16. Note that - \(\mathsf{IssueAuthSig}.\!\mathsf{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}\) - as:

-
    -
  • Return - \(0\) - if - \(\text{σ} = \bot\!\) - .
  • -
  • Return - \(1\) - if - \(\mathsf{Verify}(\mathsf{ik}, M, \text{σ})\) - succeeds, otherwise - \(0\!\) - .
  • -
-

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

-
-
-

Specification: Asset Identifier

-

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 Orchard-ZSA 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

-
    -
  • - \(\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 - \(\mathsf{AssetDigest_{AssetId}} := \textsf{BLAKE2b-512}(\texttt{"ZSA-Asset-Digest"},\; \mathsf{EncodeAssetId}(\mathsf{AssetId}))\!\) - , where

-
    -
  • - \(\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 - \(\mathsf{AssetBase_{AssetId}} := \mathsf{ZSAValueBase}(\mathsf{AssetDigest_{AssetId}})\) -

-

In the case of the Orchard-ZSA 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 20.

-

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

-
- -
Diagram relating the Asset Identifier, Asset Digest, and Asset Base in the ZSA Protocol
-
-

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 - \(\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.
  • -
-
-

Specification: Global Issuance State

-

Issuance requires the following additions to the global state defined at block boundaries:

-
    -
  • - \(\mathsf{previously\_finalized}\!\) - , a set of - \(\mathsf{AssetId}\) - that have been finalized (i.e.: the - \(\mathsf{finalize}\) - flag has been set to - \(1\) - in some issuance transaction preceding the block boundary).
  • -
-
-

Specification: Issuance Action, Issuance Bundle and Issuance Protocol

-

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 - \(0\) - and - \(512\!\) - , stored in two bytes.
  • -
  • 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 - \(\mathsf{finalize}\) - boolean that defines whether the issuance of that specific Custom Asset is finalized or not.
  • -
-

An asset's - \(\mathsf{AssetDigest}\) - is added to the - \(\mathsf{previously\_finalized}\) - set after a block that contains any issuance transaction for that asset with - \(\mathsf{finalize} = 1\!\) - . It then cannot be removed from this set. For Assets with - \(\mathsf{AssetDigest} \in \mathsf{previously\_finalized}\!\) - , no further tokens can be issued, so as seen below, the validators will reject the transaction. For Assets with - \(\mathsf{AssetDigest} \not\in \mathsf{previously\_finalized}\!\) - , new issuance actions can be issued in future transactions. These must use the same Asset description, - \(\mathsf{asset\_desc}\!\) - , and can either maintain - \(\mathsf{finalize} = 0\) - or change it to - \(\mathsf{finalize} = 1\!\) - , denoting that this Custom Asset cannot be issued after the containing block.

- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
BytesNameData TypeDescription
2assetDescSizebyteThe length of the asset_desc string in bytes.
assetDescSizeasset_descbyte[assetDescSize]A byte sequence of length assetDescSize bytes which SHOULD be a well-formed UTF-8 code unit sequence according to Unicode 15.0.0 or later.
variesnNotescompactSizeThe number of notes in the issuance action.
noteSize * nNotesvNotesNote[nNotes]A sequence of note descriptions within the issuance action, where noteSize is the size, in bytes, of a Note.
1flagsIssuancebyte -
-
An 8-bit value representing a set of flags. Ordered from LSB to MSB:
-
-
    -
  • - \(\mathsf{finalize}\) -
  • -
  • The remaining bits are set to - \(0\!\) - .
  • -
-
-
-
-

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, IssueBundle, 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}\) - : 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}\) - : the signature of the transaction SIGHASH, signed by the issuance authorizing key, - \(\mathsf{isk}\!\) - , that validates the issuance.
  • -
-

The issuance bundle is then added within the transaction format as a new bundle. That is, issuance requires the addition of the following information to the transaction format 22.

- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
BytesNameData TypeDescription
variesnIssueActionscompactSizeThe number of issuance actions in the bundle.
IssueActionSize * nIssueActionsvIssueActionsIssueAction[nIssueActions]A sequence of issuance action descriptions, where IssueActionSize is the size, in bytes, of an IssueAction description.
32ikbyte[32]The issuance validating key of the issuer, used to validate the signature.
64issueAuthSigbyte[64]The signature of the transaction SIGHASH, signed by the issuer, validated as in Issuance Authorization Signature Scheme.
-
-

Issuance Protocol

-

The issuer program performs the following operations:

-

For all actions IssueAction:

-
    -
  • 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 Orchard-ZSA 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 - \(\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.

-
-
-

Specification: Consensus Rule Changes

-

For the IssueBundle:

-
    -
  • Validate the issuance authorization signature, - \(\mathsf{issueAuthSig}\!\) - , on the SIGHASH transaction hash, - \(\mathsf{SigHash}\!\) - , by invoking - \(\mathsf{IssueAuthSig}.\!\mathsf{Validate}(\mathsf{ik}, \mathsf{SigHash}, \mathsf{issueAuthSig})\!\) - .
  • -
-

For each IssueAction in IssueBundle:

-
    -
  • check that - \(0 < \mathtt{assetDescSize} \leq 512\!\) - .
  • -
  • check that - \(\mathsf{asset\_desc}\) - is a string of length - \(\mathtt{assetDescSize}\) - bytes.
  • -
  • retrieve - \(\mathsf{AssetBase}\) - from the first note in the sequence and check that - \(\mathsf{AssetBase}\) - is derived from the issuance validating key - \(\mathsf{ik}\) - and - \(\mathsf{asset\_desc}\) - as described in the Specification: Asset Identifier section.
  • -
  • check that the - \(\mathsf{AssetDigest}\) - does not exist in the - \(\mathsf{previously\_finalized}\) - set in the global state.
  • -
  • check that every note in the IssueAction contains the same - \(\mathsf{AssetBase}\) - and is properly constructed as - \(\mathsf{note} = (\mathsf{g_d}, \mathsf{pk_d}, \mathsf{v}, \text{ρ}, \mathsf{rseed}, \mathsf{AssetBase})\!\) - .
  • -
-

If all of the above checks pass, do the following:

-
    -
  • For each note, compute the note commitment as - \(\mathsf{cm} = \mathsf{NoteCommit^{OrchardZSA}_{rcm}}(\mathsf{repr}_{\mathbb{P}}(\mathsf{g_d}), \mathsf{repr}_{\mathbb{P}}(\mathsf{pk_d}), \mathsf{v}, \text{ρ}, \text{ψ}, \mathsf{AssetBase})\) - as defined in the Note Structure and Commitment section of ZIP 226 10 and
  • -
  • Add - \(\mathsf{cm}\) - to the Merkle tree of note commitments.
  • -
  • If - \(\mathsf{finalize} = 1\!\) - , add - \(\mathsf{AssetDigest}\) - to the - \(\mathsf{previously\_finalized}\) - set immediately after the block in which this transaction occurs.
  • -
  • (Replay Protection) If issue bundle is present, the fees MUST be greater than zero.
  • -
-
-

Rationale

-

The following is a list of rationale for different decisions made in the proposal:

-
    -
  • The issuance key structure is independent of the original key tree, but derived in an analogous manner (via ZIP 32). This is in order to keep the issuance details and the Asset Identifiers consistent across multiple shielded pools.
  • -
  • The design decision is not to have a chosen name to describe the Custom Asset, but to delegate it to an off-chain mapping, as this would imply a land-grab “war”.
  • -
  • 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 require a check whether the - \(\mathsf{finalize}\) - flag only has been set in a previous block rather than a previous transaction in the same block. In other words, we only update the - \(\mathsf{previously\_finalized}`\) - set at the block boundary. This is in keeping with the current property which allows for a miner to reorder transactions in a block without changing the meaning, which we aim to preserve.
  • -
  • 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.
  • -
-

Concrete Applications

-

Asset Features

-
    -
  • By using the - \(\mathsf{finalize}\) - boolean and the burning mechanism defined in 9, issuers can control the supply production of any Asset associated to their issuer keys. For example, -
      -
    • 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 - \(\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).
    • -
    • Note in the above cases, that the setting of the - \(\mathsf{finalize}\) - flag will take effect at the block boundary, that is, after all the transactions in the block.
    • -
    -
  • -
  • 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 - \(\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.
  • -
-
-
-

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 Orchard-ZSA protocol can be found in ZIP 226 11. As in ZIP 244 12, 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
-│   ├── issue_notes_digest
-│   ├── assetDescription
-│   └── flagsIssuance
-└── issuanceValidatingKey
-

In the specification below, nodes of the tree are presented in depth-first order.

-

T.5: issuance_digest

-

A BLAKE2b-256 hash of the following values

-
T.5a: issue_actions_digest    (32-byte hash output)
-T.5b: issuanceValidatingKey   (32 bytes)
-

The personalization field of this hash is set to:

-
"ZTxIdSAIssueHash"
-

In case the transaction has no issuance components, ''issue_actions_digest'' is:

-
BLAKE2b-256("ZTxIdSAIssueHash", [])
-

T.5a: issue_actions_digest

-

A BLAKE2b-256 hash of Issue Action information for all Issuance Actions belonging to the transaction. For each Action, the following elements are included in the hash:

-
T.5a.i  : notes_digest            (32-byte hash output)
-T.5a.ii : assetDescription        (field encoding bytes)
-T.5a.iii: flagsIssuance           (1 byte)
-

The personalization field of this hash is set to:

-
"ZTxIdIssuActHash"
-
T.5a.i: issue_notes_digest
-

A BLAKE2b-256 hash of Note information for all Notes belonging to the Issuance Action. For each Note, the following elements are included in the hash:

-
T.5a.i.1: recipient                    (field encoding bytes)
-T.5a.i.2: value                        (field encoding bytes)
-T.5a.i.3: assetBase                    (field encoding bytes)
-T.5a.i.4: rho                          (field encoding bytes)
-T.5a.i.5: rseed                        (field encoding bytes)
-

The personalization field of this hash is set to:

-
"ZTxIdIAcNoteHash"
-
T.5a.i.1: recipient
-

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

-
-
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.

-
-
T.5a.i.3: assetBase
-

Asset Base encoded as the 32-byte representation of a point on the Pallas curve.

-
-
T.5a.i.4: rho
-

Nullifier encoded as 32-byte representation of a point on the Pallas curve.

-
-
T.5a.i.5: rseed
-

The ZIP 212 32-byte seed randomness for a note.

-
-
-
T.5a.ii: assetDescription
-

The Asset description byte string.

-
-
T.5a.iii: flagsIssuance
-

An 8-bit value representing a set of flags. Ordered from LSB to MSB:

-
    -
  • - \(\mathsf{finalize}\) -
  • -
  • The remaining bits are set to 0!.
  • -
-
-
-

T.5b: issuanceValidatingKey

-

A byte encoding of issuance validating key for the bundle as defined in the Issuance Key Derivation section.

-
-
-
-

Signature Digest

-

The per-input transaction digest algorithm to generate the signature digest in ZIP 244 13 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 Orchard-ZSA protocol via the [ADDED FOR ZSA] text label, and we omit the descriptions of the sections that do not change for the Orchard-ZSA protocol:

-
signature_digest
-├── header_digest
-├── transparent_sig_digest
-├── sapling_digest
-├── orchard_digest
-└── issuance_digest         [ADDED FOR ZSA]
-

signature_digest

-

A BLAKE2b-256 hash of the following values

-
S.1: header_digest          (32-byte hash output)
-S.2: transparent_sig_digest (32-byte hash output)
-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 12.

-

S.5: issuance_digest

-

Identical to that specified for the transaction identifier.

-
-
-
-

Authorizing Data Commitment

-

The transaction digest algorithm defined in ZIP 244 14 which commits to the authorizing data of a transaction is modified by the Orchard-ZSA protocol to have the following structure. We highlight the changes for the Orchard-ZSA protocol via the [ADDED FOR ZSA] text label, and we omit the descriptions of the sections that do not change for the Orchard-ZSA protocol:

-
auth_digest
-├── transparent_scripts_digest
-├── sapling_auth_digest
-├── orchard_auth_digest
-└── issuance_auth_digest        [ADDED FOR ZSA]
-

The pair (Transaction Identifier, Auth Commitment) constitutes a commitment to all the data of a serialized transaction that may be included in a block.

-

auth_digest

-

A BLAKE2b-256 hash of the following values

-
A.1: transparent_scripts_digest (32-byte hash output)
-A.2: sapling_auth_digest        (32-byte hash output)
-A.3: orchard_auth_digest        (32-byte hash output)
-A.4: issuance_auth_digest       (32-byte hash output)  [ADDED FOR ZSA]
-

The personalization field of this hash remains the same as in ZIP 244.

-

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)
-

The personalization field of this hash is set to:

-
"ZTxAuthZSAOrHash"
-

In the case that the transaction has no Orchard Actions, issuance_auth_digest is

-
BLAKE2b-256("ZTxAuthZSAOrHash", [])
-
-
-
-

Security and Privacy Considerations

-

Displaying Asset Identifier information to users

-

Wallets need to communicate the names of the Assets in a non-confusing way to users, since the byte representation of the Asset Identifier would be hard to read for an end user. Possible solutions are provided in the Specification: Asset Identifier section.

-
-

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 - \(\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

-

For bridging purposes, the secure method of off-boarding Assets is to burn an Asset with the burning mechanism in ZIP 226 9. 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

-

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 - \(\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

-

The fee mechanism described in this ZIP will follow the mechanism described in ZIP 317 15.

-
-
-

Test Vectors

-
    -
  • LINK TBD
  • -
-
-

Reference Implementation

-
    -
  • LINK TBD
  • -
  • LINK TBD
  • -
-
-

Deployment

-

TBD

-
-

References

- - - - - - - -
1Information 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"
- - - - - - - -
2ZIP 32: Shielded Hierarchical Deterministic Wallets
- - - - - - - -
3ZIP 32: Shielded Hierarchical Deterministic Wallets - Orchard master key generation
- - - - - - - -
4ZIP 32: Shielded Hierarchical Deterministic Wallets - Orchard child key derivation
- - - - - - - -
5ZIP 32: Shielded Hierarchical Deterministic Wallets - Key path levels
- - - - - - - -
6ZIP 32: Shielded Hierarchical Deterministic Wallets - Orchard key path
- - - - - - - -
7ZIP 200: Network Upgrade Mechanism
- - - - - - - -
8ZIP 224: Orchard
- - - - - - - -
9ZIP 226: Transfer and Burn of Zcash Shielded Assets
- - - - - - - -
10ZIP 226: Transfer and Burn of Zcash Shielded Assets - Note Structure & Commitment
- - - - - - - -
11ZIP 226: Transfer and Burn of Zcash Shielded Assets - TxId Digest
- - - - - - - -
12ZIP 244: Transaction Identifier Non-Malleability
- - - - - - - -
13ZIP 244: Transaction Identifier Non-Malleability: Signature Digest
- - - - - - - -
14ZIP 244: Transaction Identifier Non-Malleability: Authorizing Data Commitment
- - - - - - - -
15ZIP 317: Proportional Transfer Fee Mechanism
- - - - - - - -
16BIP 340: Schnorr Signatures for secp256k1
- - - - - - - -
17Zcash Protocol Specification, Version 2023.4.0. Section 2: Notation
- - - - - - - -
18Zcash Protocol Specification, Version 2023.4.0. Section 3.1: Payment Addresses and Keys
- - - - - - - -
19Zcash Protocol Specification, Version 2023.4.0. Section 4.2.3: Orchard Key Components
- - - - - - - -
20Zcash Protocol Specification, Version 2023.4.0. Section 5.4.9.8: Group Hash into Pallas and Vesta
- - - - - - - -
21Zcash Protocol Specification, Version 2023.4.0. Section 5.6.4.2: Orchard Raw Payment Addresses
- - - - - - - -
22Zcash Protocol Specification, Version 2023.4.0. Section 7.1: Transaction Encoding and Consensus (Transaction Version 5)
-
-
- - \ No newline at end of file diff --git a/rendered/zip-0228.html b/rendered/zip-0228.html deleted file mode 100644 index e43bedfe8..000000000 --- a/rendered/zip-0228.html +++ /dev/null @@ -1,22 +0,0 @@ - - - - ZIP 228: Asset Swaps for Zcash Shielded Assets - - - -
-
ZIP: 228
-Title: Asset Swaps for Zcash Shielded Assets
-Owners: Pablo Kogan <pablo@qed-it.com>
-        Vivek Arte <vivek@qed-it.com>
-        Daira-Emma Hopwood <daira-emma@electriccoin.co>
-        Jack Grigg <str4d@electriccoin.co>
-Credits: Daniel Benarroch
-         Aurelien Nicolas
-Status: Reserved
-Category: Consensus
-Discussions-To: <https://github.com/zcash/zips/issues/776>
-
- - \ No newline at end of file diff --git a/rendered/zip-0230.html b/rendered/zip-0230.html deleted file mode 100644 index 2afcac67b..000000000 --- a/rendered/zip-0230.html +++ /dev/null @@ -1,646 +0,0 @@ - - - - ZIP 230: Version 6 Transaction Format - - - - -
-
ZIP: 230
-Title: Version 6 Transaction Format
-Owners: Daira-Emma Hopwood <daira-emma@electriccoin.co>
-        Jack Grigg <jack@electriccoin.co>
-        Sean Bowe <sean@electriccoin.co>
-        Kris Nuttycombe <kris@electriccoin.co>
-        Pablo Kogan <pablo@qed-it.com>
-        Vivek Arte <vivek@qed-it.com>
-Original-Authors: Greg Pfeil
-                  Deirdre Connolly
-Credits: Ying Tong Lai
-Status: Draft
-Category: Consensus
-Created: 2023-04-18
-License: MIT
-Discussions-To: <https://github.com/zcash/zips/issues/686>
-

Terminology

-

The key words "MUST", "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

-

This proposal defines a new Zcash peer-to-peer transaction format, which includes data that supports the Orchard-ZSA 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 8.

-
-

Motivation

-

The Orchard-ZSA 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.

-
-

Requirements

-

The new format must fully support the Orchard-ZSA 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.

-
-

Non-requirements

-

More general forms of extensibility, such as definining a key/value format that allows for parsers that are unaware of some components, are not required.

-
-

Specification

-

All fields in this specification are encoded as little-endian.

-

The Zcash transaction format for transaction version 6 is as follows:

-

Transaction Format

- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
BytesNameData TypeDescription
Common Transaction Fields
4headeruint32 -
-
Contains:
-
-
    -
  • fOverwintered flag (bit 31, always set)
  • -
  • version (bits 30 .. 0) – transaction version.
  • -
-
-
-
4nVersionGroupIduint32Version group ID (nonzero).
4nConsensusBranchIduint32Consensus branch ID (nonzero).
4lock_timeuint32Unix-epoch UTC time or block height, encoded as in Bitcoin.
4nExpiryHeightuint32A block height in the range {1 .. 499999999} after which the transaction will expire, or 0 to disable expiry. [ZIP-203]
8feeint64The fee to be paid by this transaction, in zatoshis.
Transparent Transaction Fields
variestx_in_countcompactSizeNumber of transparent inputs in tx_in.
variestx_intx_inTransparent inputs, encoded as in Bitcoin.
variestx_out_countcompactSizeNumber of transparent outputs in tx_out.
variestx_outtx_outTransparent outputs, encoded as in Bitcoin.
Sapling Transaction Fields
variesnSpendsSaplingcompactSizeNumber of Sapling Spend descriptions in vSpendsSapling.
96 * nSpendsSaplingvSpendsSaplingSpendDescriptionV6[nSpendsSapling]A sequence of Sapling Spend descriptions, encoded per protocol §7.3 ‘Spend Description Encoding and Consensus’.
variesnOutputsSaplingcompactSizeNumber of Sapling Output Decriptions in vOutputsSapling.
756 * nOutputsSaplingvOutputsSaplingOutputDescriptionV6[nOutputsSapling]A sequence of Sapling Output descriptions, encoded per protocol §7.4 ‘Output Description Encoding and Consensus’.
8valueBalanceSaplingint64The net value of Sapling Spends minus Outputs
32anchorSaplingbyte[32]A root of the Sapling note commitment tree at some block height in the past.
192 * nSpendsSaplingvSpendProofsSaplingbyte[192 * nSpendsSapling]Encodings of the zk-SNARK proofs for each Sapling Spend.
64 * nSpendsSaplingvSpendAuthSigsSaplingbyte[64 * nSpendsSapling]Authorizing signatures for each Sapling Spend.
192 * nOutputsSaplingvOutputProofsSaplingbyte[192 * nOutputsSapling]Encodings of the zk-SNARK proofs for each Sapling Output.
64bindingSigSaplingbyte[64]A Sapling binding signature on the SIGHASH transaction hash.
Orchard-ZSA Transaction Fields
variesnActionsOrchardcompactSizeThe number of Orchard-ZSA Action descriptions in vActionsOrchard.
852 * nActionsOrchardvActionsOrchardOrchardZsaAction[nActionsOrchard]A sequence of Orchard-ZSA Action descriptions, encoded per the Orchard-ZSA Action Description Encoding.
1flagsOrchardbyte -
-
An 8-bit value representing a set of flags. Ordered from LSB to MSB:
-
-
    -
  • enableSpendsOrchard
  • -
  • enableOutputsOrchard
  • -
  • enableZSAs
  • -
  • The remaining bits are set to - \(0\!\) - .
  • -
-
-
-
8valueBalanceOrchardint64The net value of Orchard spends minus outputs.
32anchorOrchardbyte[32]A root of the Orchard note commitment tree at some block height in the past.
variessizeProofsOrchardZSAcompactSizeLength in bytes of proofsOrchardZSA. Value is (TO UPDATE) - \(2720 + 2272 \cdot \mathtt{nActionsOrchard}\!\) - .
sizeProofsOrchardZSAproofsOrchardZSAbyte[sizeProofsOrchardZSA]Encoding of aggregated zk-SNARK proofs for Orchard-ZSA Actions.
64 * nActionsOrchardvSpendAuthSigsOrchardbyte[64 * nActionsOrchard]Authorizing signatures for each Orchard-ZSA Action.
64bindingSigOrchardbyte[64]An Orchard binding signature on the SIGHASH transaction hash.
Orchard-ZSA Burn Fields
variesnAssetBurncompactSizeThe number of Assets burnt.
40 * nAssetBurnvAssetBurnAssetBurn[nAssetBurn]A sequence of Asset Burn descriptions, encoded per Orchard-ZSA Asset Burn Description.
Orchard-ZSA Issuance Fields
variesnIssueActionscompactSizeThe number of issuance actions in the bundle.
IssueActionSize * nIssueActionsvIssueActionsIssueAction[nIssueActions]A sequence of issuance action descriptions, where IssueActionSize is the size, in bytes, of an IssueAction description.
32ikbyte[32]The issuance validating key of the issuer, used to validate the signature.
64issueAuthSigbyte[64]The signature of the transaction SIGHASH, signed by the issuer, validated as in Issuance Authorization Signature Scheme 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}}`\) - is defined to be - \(0\!\) - .
  • -
  • The field anchorSapling is present if and only if - \(\mathtt{nSpendsSapling} > 0\!\) - .
  • -
  • The fields flagsOrchard, valueBalanceOrchard, anchorOrchard, sizeProofsOrchardZSA, proofsOrchardZSA, and bindingSigOrchard are present if and 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 proof or signature at a given index corresponds to the SpendDescriptionV6 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 OutputDescriptionV6 at the same index.
  • -
  • The proofs aggregated in proofsOrchardZSA, 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 OrchardZsaAction at the same index.
  • -
  • 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 , OrchardZsaAction, AssetBurn and IssueAction 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.

-
-

Sapling Spend Description (SpendDescriptionV6)

- - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
BytesNameData TypeDescription
32cvbyte[32]A value commitment to the net value of the input note.
32nullifierbyte[32]The nullifier of the input note.
32rkbyte[32]The randomized validating key for the element of spendAuthSigsSapling corresponding to this Spend.
-

The encodings of each of these elements are defined in §7.3 ‘Spend Description Encoding and Consensus’ of the Zcash Protocol Specification 3.

-
-

Sapling Output Description (OutputDescriptionV6)

- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
BytesNameData TypeDescription
32cvbyte[32]A value commitment to the net value of the output note.
32cmubyte[32]The - \(u\!\) - -coordinate of the note commitment for the output note.
32ephemeralKeybyte[32]An encoding of an ephemeral Jubjub public key.
580encCiphertextbyte[580]The encrypted contents of the note plaintext.
80outCiphertextbyte[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 4.

-
-

Orchard-ZSA Action Description (OrchardZsaAction)

- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
BytesNameData TypeDescription
32cvbyte[32]A value commitment to the net value of the input note minus the output note.
32nullifierbyte[32]The nullifier of the input note.
32rkbyte[32]The randomized validating key for the element of spendAuthSigsOrchard corresponding to this Action.
32cmxbyte[32]The - \(x\!\) - -coordinate of the note commitment for the output note.
32ephemeralKeybyte[32]An encoding of an ephemeral Pallas public key
612encCiphertextbyte[580]The encrypted contents of the note plaintext.
80outCiphertextbyte[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 5.

-
-

Orchard-ZSA Asset Burn Description

-

An Orchard-ZSA Asset Burn description is encoded in a transaction as an instance of an AssetBurn type:

- - - - - - - - - - - - - - - - - - - - - - - -
BytesNameData TypeDescription
32AssetBasebyte[32]For the Orchard-based ZSA protocol, this is the encoding of the Asset Base - \(\mathsf{AssetBase^{Orchard}}\!\) - .
8valueBurn - \(\{1 .. 2^{64} - 1\}\) - The amount being burnt.
-

The encodings of each of these elements are defined in ZIP 226 6.

-
-

Issuance Action Description (IssueAction)

-

An issuance action, IssueAction, is the instance of issuing a specific Custom Asset, and contains the following fields:

- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
BytesNameData TypeDescription
2assetDescSizebyteThe length of the asset description string in bytes.
assetDescSizeasset_descbyte[assetDescSize]A byte sequence of length assetDescSize bytes which SHOULD be a well-formed UTF-8 code unit sequence according to Unicode 15.0.0 or later.
variesnNotescompactSizeThe number of notes in the issuance action.
noteSize * nNotesvNotesNote[nNotes]A sequence of note descriptions within the issuance action, where noteSize is the size, in bytes, of a Note.
1flagsIssuancebyte -
-
An 8-bit value representing a set of flags. Ordered from LSB to MSB:
-
-
    -
  • - \(\mathsf{finalize}\) -
  • -
  • The remaining bits are set to - \(0\!\) - .
  • -
-
-
-
-

The encodings of each of these elements are defined in ZIP 227 7.

-
-
-

Reference implementation

-

TODO

-
-

References

- - - - - - - -
1Information 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"
- - - - - - - -
2Zcash Protocol Specification, Version 2023.4.0 or later [NU5 proposal]
- - - - - - - -
3Zcash Protocol Specification, Version 2023.4.0 [NU5 proposal]. Section 4.4: Spend Descriptions
- - - - - - - -
4Zcash Protocol Specification, Version 2023.4.0 [NU5 proposal]. Section 4.5: Output Descriptions
- - - - - - - -
5Zcash Protocol Specification, Version 2023.4.0 [NU5 proposal]. Section 4.6: Action Descriptions
- - - - - - - -
6ZIP 226: Transfer and Burn of Zcash Shielded Assets
- - - - - - - -
7ZIP 227: Issuance of Zcash Shielded Assets
- - - - - - - -
8ZIP 244: Transaction Identifier Non-Malleability
-
-
- - \ No newline at end of file diff --git a/rendered/zip-0231.html b/rendered/zip-0231.html deleted file mode 100644 index 877430c9b..000000000 --- a/rendered/zip-0231.html +++ /dev/null @@ -1,21 +0,0 @@ - - - - ZIP 231: Decouple Memos from Transaction Outputs - - - -
-
ZIP: 231
-Title: Decouple Memos from Transaction Outputs
-Owners: Jack Grigg <jack@electriccoin.co>
-        Kris Nuttycombe <kris@electriccoin.co>
-        Daira-Emma Hopwood <daira-emma@electriccoin.co>
-Credits: Sean Bowe
-         Nate Wilcox
-Status: Reserved
-Category: Consensus / Wallet
-Discussions-To: <https://github.com/zcash/zips/issues/627>
-
- - \ No newline at end of file diff --git a/rendered/zip-0233.html b/rendered/zip-0233.html deleted file mode 100644 index e9c1b5254..000000000 --- a/rendered/zip-0233.html +++ /dev/null @@ -1,243 +0,0 @@ - - - - ZIP 233: Establish the Zcash Sustainability Fund on the Protocol Level - - - - - -
ZIP: 233
-Title: Establish the Zcash Sustainability Fund on the Protocol Level
-Owners: Jason McGee <jason@shieldedlabs.com>
-        Mark Henderson <mark@equilibrium.co>
-        Tomek Piotrowski <tomek@eiger.co>
-        Mariusz Pilarek <mariusz@eiger.co>
-Original-Authors: Nathan Wilcox
-Credits:
-Status: Draft
-Category: Consensus / Ecosystem
-Created: 2023-08-16
-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]

-

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 unmined or unissued ZEC is converted -to ZEC available to users of the network

-

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

-

MAX_MONEY” is the ZEC supply cap. For simplicity, this -ZIP defines it to be 21,000,000 ZEC, although this is -slightly larger than the actual supply cap of the original ZEC issuance -mechanism.

-

Abstract

-

This ZIP describes the motivation, the necessary changes for, and the -implementation specifications for the Zcash Sustainability Fund (ZSF). -The ZSF is a proposed alteration to the block rewards system and -accounting of unmined ZEC that allows for other sources of funding -besides unissued ZEC. This new mechanism for deposits – that new -applications or protocol designs can use to strengthen the long-term -sustainability of the network – will likely be an important step for -future economic upgrades, such as a transition to Proof of Stake or -Zcash Shielded Assets, and other potential protocol fees and user -applications.

-

The changes in this ZIP are ultimately minimal, only requiring for -the node to track state in the form of a ZSF_BALANCE, and -for a new transaction field to be added, called -ZSF_DEPOSIT. While wallet developer would be encouraged to -add the ZSF_DEPOSIT field to their UIs, no changes or new -behavior are absolutely required for developers or ZEC holders.

-

This ZIP does not change the current ZEC block subsidy issuance -schedule. Any additional amounts paid into the sustainability fund are -reserved for use in future ZIPs.

-

Motivation

-

The Zcash network’s operation and development relies fundamentally on -the block reward system inherited from Bitcoin. This system currently -looks like this:

-
    -
  • At Every New Block: -
      -
    • Miner and funding streams are rewarded a constant amount via -unissued ZEC (this constant amount halves at specified heights)
    • -
    • Miner is rewarded via Transaction fees -(inputs - outputs)
    • -
  • -
-

The Zcash Sustainability Fund is a proposed replacement to that -payout mechanism, with the relevant parts in bold below:

-
    -
  • Unmined ZEC is now accounted for as -ZSF_BALANCE
  • -
  • Transaction includes optional contributions to ZSF via a -ZSF_DEPOSIT field
  • -
  • Thus, at Every New Block: -
      -
    • Miner and funding streams rewarded the same constant amount, -but from ZSF_BALANCE (this constant amount -still halves at specified heights)
    • -
    • Miner is rewarded via Transaction fees -(inputs - outputs), where outputs -includes the ZSF_DEPOSIT amount
    • -
  • -
-

For example, an end-user wallet application could have an option to -contribute a portion of a transaction to the ZSF, which would be -included in a ZSF_DEPOSIT field in the transaction, to be -taken into account by the Zcash nodes.

-

This quite simple alteration has – in our opinion – a multitude of -benefits:

-
    -
  1. Long Term Consensus Sustainability: This mechanism -supports long-term consensus sustainability by addressing concerns about -the sustainability of the network design shared by Bitcoin-like systems -through the establishment of deposits into the Sustainability Fund to -augment block rewards, ensuring long-term sustainability as the issuance -rate of Zcash drops and newly issued ZEC decreases over time.
  2. -
  3. Benefits to ZEC Holders: Deposits to the ZSF slow -down the payout of ZEC, temporarily reducing its available supply, -benefiting current holders of unencumbered active ZEC in proportion to -their holdings without requiring them to opt into any scheme, -introducing extra risk, active oversight, or accounting complexity.
  4. -
  5. Recovery of “Soft-Burned” Funds: In some instances, -such as miners not claiming all available rewards, some ZEC goes -unaccounted for, though not formally burned. This proposal would recover -it through the ZSF_BALANCE mechanism described below.
  6. -
-

Specification

-

In practice, The Zcash Sustainability Fund is a single global balance -maintained by the node state and contributed to via a single transaction -field. This provides the economic and security support described in the -motivation section, while also importantly keeping the fund payouts -extremely simple to describe and implement.

-

The two modifications are: 1. The re-accounting of unmined ZEC as a -node state field called ZSF_BALANCE 2. The addition of a -transaction field called ZSF_DEPOSIT

-

ZSF_BALANCE

-

The ZEC issuance mechanism is re-defined to remove funds from -ZSF_BALANCE, which is initially set to -MAX_MONEY at the genesis block.

-

Consensus nodes are then required to track new per-block state:

-
    -
  • ZSF_BALANCE[height] : u64 [zatoshi]
  • -
-

The state is a single 64 bit integer (representing units of -zatoshi) at any given block height, height, representing the Sustainability Fund -balance at that height. The ZSF_BALANCE can be calculated -using the following formula:

-

$\mathsf{ZsfBalanceAfter}(\mathsf{height}) -= \mathsf{MAX\_MONEY} + \sum_{h = 0}^{\mathsf{height}} -(\mathsf{ZsfDeposit}(h) + \mathsf{Unclaimed}(h) - -\mathsf{BlockSubsidy}(h))$

-

where Unclaimed(height) is the -portion of the block subsidy and miner fees that are unclaimed for the -block at the given height.

-

The block at height height commits -to ZsfBalanceAfter(height) as part of a -new block commitment in the block header, at the end of the -hashBlockCommitments chain in ZIP-244.

-

TODO ZIP editors: consider introducing a chain state commitment hash -tree. (When we get closer to the network upgrade, we will have a better -idea what commitments that network upgrade needs.)

-

Deposits into the -Sustainability Fund

-

Sustainability fund deposits can be made via the new -zsfDeposit field. This can be done by: - ZEC fund holders, -in non-coinbase transactions; - Zcash miners, in coinbase -transactions.

-

In transaction versions without this new field: - unclaimed miner -fees and rewards in coinbase transactions are -re-defined as deposits into the sustainability fund, and - there are no -sustainability fund deposits from non-coinbase transactions.

-

Note: older transaction versions can continue to be supported after a -network upgrade. For example, NU5 supports both v4 and v5 transaction -formats, for both coinbase and non-coinbase transactions.

-

zsfDeposit -fields in transactions

-

Each transaction can dedicate some of its excess funds to the ZSF, -and the remainder becomes the miner fee, with any excess miner -fee/reward going to the ZSF

-

This is achieved by adding a new field to the common transaction -fields [#zip-0225-transaction-format]:

-
    -
  • zsfDeposit : u64 [zatoshi]
  • -
-

The ZSF_BALANCE[H] for a block at height H -can be calculated given a value of ZSF_BALANCE[H-1] and the -set of transactions contained in that block. First, the -ZSF_DEPOSIT[H] is calculated based solely on -ZSF_BALANCE[H-1]. This is subtracted from the previous -block’s balance to be distributed as part of the block reward. Second, -the sum of all the ZSF_DEPOSIT fields of all transactions -in the block is added to the balance.

-

Non-Coinbase Transactions

-

If the ZSF_DEPOSIT field is not present in an older -transaction version, it is defined to be zero for non-coinbase -transactions.

-

Consensus Rule Changes

-
    -
  • Transparent inputs to a transaction insert value into a transparent -transaction value pool associated with the transaction. Transparent -outputs and sustainability fund deposits remove value -from this pool.
  • -
-

Coinbase Transactions

-

Any excess miner fee/reward is sent to the ZSF.

-

In new blocks, this deposit is tracked via the -ZSF_DEPOSIT field in coinbase transactions.

-

If the ZSF_DEPOSIT field is not present in a coinbase -transaction with an older transaction version, it is defined as the -value of any unspent miner fee and miner reward. This re-defines these -previously unspendable funds as ZSF deposits.

-

Consensus Rule Changes

-
    -
  • The remaining value in the transparent transaction value pool of a -coinbase transaction is deposited in the sustainability -fund.
  • -
-

ZSF_DEPOSIT -Requirements

-
    -
  • ZIP 230 [3] must be updated to include -ZSF_DEPOSIT.
  • -
  • ZIP 244 [4] must be updated as well to include -ZSF_DEPOSIT.
  • -
-

Rationale

-

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

-

ZSF_BALANCE as node -state

-

Tracking the ZSF_BALANCE value as a node state using the -above formula is very simple in terms of implementation, and should work -correctly given that the node implementations calculate the value -according to the specifications.

-

ZSF_DEPOSIT -as explicit transaction field

-

An explicit value distinguishes the ZEC destined to Sustainability -Fund deposits from the implicit 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 (TODO ZIP -editors).

-

References

-

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

-

[2]: ZIP 200: Network -Upgrade Mechanism

-

[3]: ZIP -230: v6 transactions, including ZSAs

-

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

- - diff --git a/rendered/zip-0234.html b/rendered/zip-0234.html deleted file mode 100644 index 5da8eb546..000000000 --- a/rendered/zip-0234.html +++ /dev/null @@ -1,193 +0,0 @@ - - - - ZIP 234: Smooth Out The Block Subsidy Issuance - - - - - -
ZIP: 234
-Title: Smooth Out The Block Subsidy Issuance
-Owners: Jason McGee <jason@shieldedlabs.com>
-        Mark Henderson <mark@equilibrium.co>
-        Tomek Piotrowski <tomek@eiger.co>
-        Mariusz Pilarek <mariusz@eiger.co>
-Original-Authors: Nathan Wilcox
-Credits:
-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” - to be interpreted as described in the Zcash -Protocol Specification (TODO ZIP Editors: link from comment).

-

“Issuance” - the sum of Block Subsidies over time. (TODO ZIP Editors: -work out if this definition is correct or can be removed).

-

ZsfBalanceAfter(h)” is the total ZEC available in the -Zcash Sustainability Fund (ZSF) after the transactions in block -h, described in ZIP draft-zsf.md. In this ZIP, the -Sustainability Fund is used to pay out Block Subsidies from unmined ZEC, -and other fund deposits.

-

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

-

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 slow exponential -“smoothing” of the curve. The new issuance scheme would approximate the -current issuance over 4-year intervals.

-

This ZIP depends on the ZIP introducing the Zcash Sustainability Fund -(ZIP-XXX).

-

Motivation

-

The current Zcash economic model, inherited from Bitcoin, includes a -halving mechanism which 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.

-

To address this, we propose issuing a fixed portion of the pending -funds-to-be-issued in each block. This has the effect of smoothing out -the issuance curve of ZEC, ensuring a more consistent and predictable -rate of coin issuance, while still preserving the overall supply cap of -21,000,000 coins. This mechanism by itself (without other anticipated -changes) seeks to preserve the core aspects of Zcash’s issuance policy -and aims to enhance predictability and avoid sudden changes. By making -this shift, the average block subsidy over time will remain predictable -with very gradual changes.

-

However, we anticipate schemes proposed in [#draft-zsf]_ where the -amount of funds-to-be-issued may increase. In that scenario, this -issuance mechanism would distribute that increase starting in the -immediately following block and subsequent blocks. Because this -distribution mechanism has an exponential decay, such increases will be -spread out in miniscule amounts to future blocks over a long time -period. This issuance mechanism thus provides a way for potential -increases or decreases of issuance while constraining those changes to -be small on a short time scale to avoid unexpected disruptions.

-

Additionally, the current Bitcoin-style issuance does not take into -account the current balance of ZsfBalanceAfter(h). If -[#draft-zsf]_ were to activate without a change to the issuance -mechanism, then some funds would never be disbursed after they are -deposited back into the ZSF.

-

Requirements

-

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

-

Issuance Requirements

-
    -
  1. The issuance can be summarised into a reasonably simple -explanation
  2. -
  3. Block subsidies approximate a continuous function
  4. -
  5. If there are funds in the ZSF, 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 ZSF at the beginning of that 4 year -period, if there are no deposits into the ZSF during those 4 years
  8. -
-

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

-

Specification

-

Goals

-

We want to decrease the short-term impact of the deployment of this -ZIP on block reward recipients, and minimise the potential reputational -risk to Zcash of changing the block reward amount.

-

Constants

-

Define constants:

-

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

-

DEPLOYMENT_BLOCK_HEIGHT” = 2726400

-

Issuance Calculation

-

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

-

Given the block height h define a function -BlockSubsidy(h), such that:

-

BlockSubsidy(h) = Block subsidy for a given -h, that satisfies above requirements.

-

Using an exponential decay function for BlockSubsidy -satisfies requirements R1 and R2 -above:

-

BlockSubsidy(h) = BLOCK_SUBSIDY_FRACTION * ZsfBalanceAfter(h - 1)

-

Finally, to satisfy R3 above we always round up to -the next zatoshi.

-

BlockSubsidy(h) = ceiling(BLOCK_SUBSIDY_FRACTION * ZsfBalanceAfter(h - 1))

-

Rationale

-

BLOCK_SUBSIDY_FRACTION

-

Let IntendedZSFFractionRemainingAfterFourYears = -0.5.

-

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

-

(1 - BLOCK_SUBSIDY_FRACTION)^PostBlossomHalvingInterval ≈ IntendedZSFFractionRemainingAfterFourYears

-

Meaning after a period of 4 years around half of -ZSF_BALANCE will be paid out as block subsidies, thus -satisfying R4.

-

The largest possible amount in the ZSF is MAX_MONEY, in the -theoretically possible case that all issued funds are deposited back -into the ZSF. 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.

-

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.

-

TODO for ZIP owners: How many ZEC per day?

-

DEPLOYMENT_BLOCK_HEIGHT

-

The deployment should happen at the next halving, which is block -2726400.

-

Since there is a planned halving at this point, there will already be -a significant “shock” caused by the drop in issuance caused by the -halving. This reduces surprise and thus increases security. Also, due to -the nature of the smoothed curve having a portion of the curve above the -respective step function line at times, this will maximally -reduce the issuance shock at the -DEPLOYMENT_BLOCK_HEIGHT.

-

Visualization of the -Smoothed Curve

-

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

-
- - -
-

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

-
- - -
-

Deployment

-

The implementation of this ZIP MUST be deployed at the same time or -after the Zcash Sustainability Fund is established (ZIP-XXX).

-

Appendix: Simulation

-

The ZSF -simulator allows us to simulate the effects of this ZIP on the ZSF -balance 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 no ZEC is ever deposited to the ZSF, its -balance 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:
-  ZSF 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),         ZSF/legacy: 1.0001
-

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

-

References

-

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

-

[2] ZIP-200: https://zips.z.cash/zip-0200

-

[3] ZIP-XXX: Placeholder for the ZSF ZIP

- - diff --git a/rendered/zip-0236.html b/rendered/zip-0236.html deleted file mode 100644 index 9f0f3f295..000000000 --- a/rendered/zip-0236.html +++ /dev/null @@ -1,132 +0,0 @@ - - - - ZIP 236: Blocks should balance exactly - - - -
-
ZIP: 236
-Title: Blocks should balance exactly
-Owners: Daira-Emma Hopwood <daira-emma@electriccoin.co>
-Credits: Jack Grigg
-         Kris Nuttycombe
-Status: Draft
-Category: Consensus
-Created: 2024-07-02
-License: MIT
-Discussions-To: <https://github.com/zcash/zips/issues/864>
-

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. 4

-

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

-
-

Abstract

-

In the current Zcash protocol, the miner of a coinbase transaction is permitted to claim up to and including the total amount of miner subsidy plus fees from other transactions in the block, but is not required to claim the full amount.

-

This proposal would require the full amount of miner subsidy and fees to be collected in coinbase transactions.

-
-

Motivation

-

The current semantics of coinbase transactions creates a potential for miners to miscalculate the total amount of miner subsidy plus fees in a block. If they claim a higher amount than the actual miner subsidy plus total fees, the block will be invalid, but if they claim a lower amount, the excess is effectively burnt. As a consequence, the effective ZEC issuance can fall short of the amount calculated from the intended issuance curve.

-

This unnecessarily complicates the question of how much ZEC has been issued: if it is defined as not including the amounts that were left unclaimed by miners, then it is difficult to calculate, and cannot be predicted exactly in advance for any given block height. Alternatively if it is defined to include those amounts, then that introduces potentially confusing discrepancies between different definitions of issuance or total supply.

-
-

Requirements

-

The consensus rule change specified in this ZIP must:

-
    -
  • allow issuance to be predicted exactly in advance, starting from the point at which it activates;
  • -
  • preclude errors by miners in computing the total miner subsidy plus fees for transactions in the mined block;
  • -
  • be deployable in the NU6 network upgrade, which is not expected to define a new transaction version.
  • -
-
-

Non-requirements

-

Since this ZIP is intended to activate in a network upgrade that is not expected to support a new transaction version, it cannot resolve the issue that the amounts of fees are implicit in non-coinbase transactions. That issue results in various potential security difficulties and the potential for users' wallets to inadvertently overpay the fee, but solving that would require an explicit "fee" field.

-

(It would technically be possible to encode the fee as a transparent output, but that would be a more disruptive change than is desirable, since other consensus rules would have to change in order to prevent this output from being spent, and since existing consumers of the transaction format could misinterpret such outputs.)

-

This consensus change is not intended to prevent other methods of provably removing ZEC from the circulating supply, such as sending it to an address for which it would be demonstrably infeasible to find the spending key.

-
-

Specification

-

From the activation block of this ZIP onward, coinbase transactions MUST claim all of the available miner subsidy plus fees in their block. More specifically, the following paragraph and consensus rule in § 3.4 "Transactions and Treestates" of the Zcash Protocol Specification 3:

-
-

Transparent inputs to a transaction insert value into a transparent transaction value pool associated with the transaction, and transparent outputs remove value from this pool. As in Bitcoin, the remaining value in the transparent transaction value pool of a non-coinbase transaction is available to miners as a fee. The remaining value in the transparent transaction value pool of a coinbase transaction is destroyed.

-

Consensus rule: The remaining value in the transparent transaction value pool MUST be nonnegative.

-
-

is modified to become:

-
-

Transparent inputs to a transaction insert value into a transparent transaction value pool associated with the transaction, and transparent outputs remove value from this pool. The effect of Sapling Spends and Outputs, and of Orchard Actions on the transaction value pool are specified in § 4.13 and § 4.14 respectively.

-

As in Bitcoin, the remaining value in the transparent transaction value pool of a non-coinbase transaction is available to miners as a fee. That is, the sum of those values for non-coinbase transactions in each block is treated as an implicit input to the transaction value balance of the block's coinbase transaction (in addition to the implicit input created by issuance).

-

The remaining value in the transparent transaction value pool of coinbase transactions in blocks prior to NU6 is destroyed. From activation of NU6, this remaining value is required to be zero; that is, all of the available balance MUST be consumed by outputs of the coinbase transaction.

-

Consensus rules:

-
    -
  • The remaining value in the transparent transaction value pool of a non-coinbase transaction MUST be nonnegative.
  • -
  • [Pre-NU6] The remaining value in the transparent transaction value pool of a coinbase transaction MUST be nonnegative.
  • -
  • [NU6 onward] The remaining value in the transparent transaction value pool of a coinbase transaction MUST be zero.
  • -
-
-

where "NU6" is to be replaced by the designation of the network upgrade in which this ZIP will be activated.

-

Note that the differences in the first two paragraphs of the above replacement text are clarifications of the protocol, rather than consensus changes. Those could be made independently of this ZIP.

-

This change applies identically to Mainnet and Testnet.

-
-

Deployment

-

This ZIP is proposed to be deployed with NU6. 6

-
-

Reference implementation

- -
-

Acknowledgements

-

The author would like to thank Jack Grigg and Kris Nuttycombe for discussions leading to the submission of this ZIP.

-
-

References

- - - - - - - -
1Information 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"
- - - - - - - -
2Zcash Protocol Specification, Version 2024.5.1 or later
- - - - - - - -
3Zcash Protocol Specification, Version 2024.5.1 [NU6]. Section 3.4: Transactions and Treestates
- - - - - - - -
4Zcash Protocol Specification, Version 2024.5.1 [NU6]. Section 3.12: Mainnet and Testnet
- - - - - - - -
5ZIP 200: Network Upgrade Mechanism
- - - - - - - -
6ZIP 253: Deployment of the NU6 Network Upgrade
-
-
- - \ No newline at end of file diff --git a/rendered/zip-0239.html b/rendered/zip-0239.html deleted file mode 100644 index f4d1626e2..000000000 --- a/rendered/zip-0239.html +++ /dev/null @@ -1,170 +0,0 @@ - - - - ZIP 239: Relay of Version 5 Transactions - - - -
-
ZIP: 239
-Title: Relay of Version 5 Transactions
-Owners: Daira-Emma Hopwood <daira-emma@electriccoin.co>
-        Jack Grigg <jack@electriccoin.co>
-Status: Final
-Category: Network
-Created: 2021-05-29
-License: MIT
-Discussions-To: <https://github.com/zcash/zips/issues/515>
-Pull-Request: <https://github.com/zcash/zips/pull/516>
-

Terminology

-

The key words "MUST", "MUST NOT", "SHOULD", "SHOULD NOT", and "RECOMMENDED" 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. 4

-

The terms "Testnet" and "Mainnet" are to be interpreted as described in section 3.12 of the Zcash Protocol Specification 2.

-

The term "txid" means a transaction identifier, computed as a SHA-256d hash of the transaction data for v4 and earlier transactions, or as specified in 6 for v5 and later transactions.

-

The term "authorizing data commitment" (denoted auth_digest), defined only for v5 and later transactions, is to be interpreted as described in 6.

-

The term "witnessed transaction identifier" ("wtxid"), defined only for v5 and later transactions, is a 64-byte value given by concatenating the txid and the authorizing data commitment of the transaction.

-
-

Abstract

-

This ZIP describes changes to the Zcash peer-to-peer protocol to support transaction relay based on a transaction's authorizing data commitment as well as its txid.

-
-

Motivation

-

Historically, as in Bitcoin, the inv and getdata messages sent on the Zcash peer-to-peer network to announce or request transactions have referred to those transactions by txid.

-

Prior to the introduction of v5 transactions 5 in the NU5 network upgrade 7, a txid was always defined as the SHA-256d hash of the transaction data, the encoding of which is the same in block data and in the peer-to-peer protocol.

-

For v5 transactions, a new transaction digest algorithm is defined that constructs the txid from a tree of hashes, which include only effecting data 6. Witness data is committed to by a separate "authorizing data commitment". Unlike previous transaction versions, the format of serialized v5 transaction data is not consensus-critical.

-

Not committing to the witness data in v5 transaction announcements would create inefficiencies: because a v5 transaction's witness can be malleated without altering the txid, a node in receipt of a v5 transaction that the node does not accept would generally still have to download that same transaction when announced by other peers. This is because the alternative — of not downloading a v5 transaction with a given txid after rejecting a previous transaction with that txid — would allow a third party to interfere with transaction relay by malleating a transaction's witness and announcing the resulting invalid transaction to nodes, preventing relay of the valid version of the transaction as well.

-

This inefficiency was present in Bitcoin for almost 3 years after activation of its Segwit upgrade 8, until the adoption of BIP 339 9. The latter BIP specifies a way to use the Segwit "wtxid" (which commits to both effecting and witness data) in place of the txid when announcing and fetching transactions. In Zcash, the analogous identifier is also called the wtxid, but it encodes the pair (txid, auth_digest).

-

This ZIP is modelled after BIP 339: it adds a MSG_WTX inv type to the peer-to-peer protocol, analogous to BIP 339's MSG_WTX inv type, that announces transactions by their wtxid. Note that the encoding and length of a Zcash wtxid is different to that of a Bitcoin wtxid.

-

This ZIP does not introduce any equivalent of BIP 339's wtxidrelay message, since that is not needed for compatibility given that Zcash full nodes are required to support MSG_WTX based on the negotiated peer protocol version (see Deployment).

-
-

Specification

-

A new inv type MSG_WTX (0x00000005) is added, for use in both inv messages and getdata requests, indicating that the hash being referenced is the wtxid (i.e. the 64-byte value txid || auth_digest). This inv type MUST be used when announcing v5 transactions. The txid and auth_digest are as defined in 6.

-

In the case of getdata requests, the format of a v5 transaction obtained by a MSG_WTX inv type is as given in the Zcash protocol specification. 3

-

An inv or getdata message MUST NOT use the MSG_WTX inv type for v4 or earlier transactions, or on peer connections that have not negotiated at least the peer protocol version specified in Deployment.

-

Note that MSG_WTX might also be used for future transaction versions after v5. Since such versions are not currently consensus-valid, this is left unspecified for now.

-

MSG_TX and MSG_WTX entries may be mixed in arbitrary order in an inv message or a getdata message. Since these entry types are of different lengths (36 bytes or 68 bytes respectively including the 4-byte type field), this implies that the size of the message is not determined by its initial count field, and has to be determined by parsing the whole message.

-

Deployment

-

This ZIP is assumed to be deployed in advance of the network upgrade that introduces v5 transactions, i.e. NU5.

-

The peer protocol version that enables support for this specification is defined to be 170014 (on both Testnet and Mainnet). This is in advance of the minimum protocol version that signals support for NU5 on Testnet. 7

-

As specified in 4, a node that supports a network upgrade will clear its mempool when reaching the block before that upgrade's activation block. Before this point, the node will not accept transactions into its mempool that are invalid according to the pre-upgrade consensus protocol (so, in this case, it would not accept v5 transactions). This means that a correctly functioning node will not use the MSG_WTX inv type until it has received the block preceding the NU5 network upgrade.

-

Nevertheless, it is possible for a node to receive an inv or getdata message containing an inventory entry of type MSG_WTX, on a peer connection that has negotiated protocol version 170014 or later, before NU5 has activated. In this case, the node MUST NOT advertise, fetch, or provide v5 transactions.

-

Note that the behaviour of a node receiving an inv or getdata message with one or more inventory entries of an unrecognized type was previously unspecified. The behaviour of zcashd in such a case was to assume that the length of each inventory entry is 36 bytes (including the type field), regardless of the type. This would result in misparsing the inv or getdata message if the length of the corresponding inventory entry were not 36 bytes.

-

The RECOMMENDED behaviour is to parse the inv or getdata message completely, and reject the message if it contains any inventory entries of an unrecognized type. For a getdata message, the set of recognized inventory types, and corresponding entry lengths including the type field, is:

-
    -
  • MSG_TX (36 bytes);
  • -
  • MSG_BLOCK (36 bytes);
  • -
  • MSG_FILTERED_BLOCK (36 bytes);
  • -
  • [provided version 170014 or later has been negotiated] MSG_WTX (68 bytes).
  • -
-

For an inv message, the set of recognized inventory types is the same, but the MSG_FILTERED_BLOCK type has no useful purpose. Senders of inv messages SHOULD NOT include MSG_FILTERED_BLOCK entries. In order to allow using the same parser for the two message types, a node receiving a MSG_FILTERED_BLOCK entry in an inv message SHOULD ignore it.

-

As the MSG_WTX inv type is only enabled between peers that both support it, older clients remain fully compatible and interoperable before NU5 activates, or on a chain in which it does not activate.

-

Further information on how zcashd handles data propagation in the peer-to-peer network is given in 12.

-
-
-

Rationale

-

A previous draft of this ZIP left as an open question whether to redefine inv and getdata to segregate MSG_TX and MSG_WTX. This could potentially have made these messages simpler or more efficient to parse, by avoiding variable-length entries in the message data. (See 10 and 11 for how inv and getdata respectively are currently defined in Bitcoin.)

-

This option was rejected because the current specification is simple enough.

-
-

Acknowledgements

-

This ZIP is partly based on BIP 339, written by Suhas Daftuar. 9

-
-

References

- - - - - - - -
1Information 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"
- - - - - - - -
2Zcash Protocol Specification, Version 2021.2.16 [NU5 proposal]. Section 3.12 Mainnet and Testnet
- - - - - - - -
3Zcash Protocol Specification, Version 2021.2.16 [NU5 proposal]. Section 7.1: Transaction Encoding and Consensus
- - - - - - - -
4ZIP 200: Network Upgrade Mechanism
- - - - - - - -
5ZIP 225: Version 5 Transaction Format
- - - - - - - -
6ZIP 244: Transaction Identifier Non-Malleability
- - - - - - - -
7ZIP 252: Deployment of the NU5 Network Upgrade
- - - - - - - -
8BIP 141: Segregated Witness (Consensus layer)
- - - - - - - -
9BIP 339: WTXID-based transaction relay
- - - - - - - -
10Bitcoin Developer Reference: P2P Network — Inv
- - - - - - - -
11Bitcoin Developer Reference: P2P Network — GetData
- - - - - - - -
12zcashd book: P2P data propagation
-
-
- - \ No newline at end of file diff --git a/rendered/zip-0243.html b/rendered/zip-0243.html deleted file mode 100644 index e0fa280a3..000000000 --- a/rendered/zip-0243.html +++ /dev/null @@ -1,513 +0,0 @@ - - - - ZIP 243: Transaction Signature Validation for Sapling - - - -
-
ZIP: 243
-Title: Transaction Signature Validation for Sapling
-Owners: Jack Grigg <str4d@electriccoin.co>
-        Daira-Emma Hopwood <daira-emma@electriccoin.co>
-Credits: Simon Liu
-Status: Final
-Category: Consensus
-Created: 2018-04-10
-License: MIT
-

Terminology

-

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

-

The terms "consensus branch", "epoch", and "network upgrade" in this document are to be interpreted as described in ZIP 200. 5

-

The term "Sapling" in this document is to be interpreted as described in ZIP 205. 6

-
-

Abstract

-

This proposal defines a new transaction digest algorithm for signature validation from the Sapling network upgrade, to account for the presence of Sapling shielded inputs and outputs in transactions.

-
-

Motivation

-

The Sapling network upgrade introduced new shielded inputs and outputs. We want these to be covered by the transaction digest algorithm used for signatures, in order to ensure they are correctly bound.

-
-

Specification

-

A new transaction digest algorithm is defined:

-
BLAKE2b-256 hash of the serialization of:
-  1. header of the transaction (4-byte little endian)
-  2. nVersionGroupId of the transaction (4-byte little endian)
-  3. hashPrevouts (32-byte hash)
-  4. hashSequence (32-byte hash)
-  5. hashOutputs (32-byte hash)
-  6. hashJoinSplits (32-byte hash)
-  7. hashShieldedSpends (32-byte hash)
-  8. hashShieldedOutputs (32-byte hash)
-  9. nLockTime of the transaction (4-byte little endian)
- 10. nExpiryHeight of the transaction (4-byte little endian)
- 11. valueBalance of the transaction (8-byte little endian)
- 12. sighash type of the signature (4-byte little endian)
-
- 13. If we are computing a transaction digest for a transparent input (i.e. this hash is not for
-     a JoinSplit signature, Spend authorization signature, or binding signature):
-     a. outpoint (32-byte hash + 4-byte little endian)
-     b. scriptCode of the input (serialized as scripts inside CTxOuts)
-     c. value of the output spent by this input (8-byte little endian)
-     d. nSequence of the input (4-byte little endian)
-

The new algorithm is based on the transaction digest algorithm defined in ZIP 143 4.

-

The new algorithm MUST be used for signatures created over the Sapling transaction format 2. Combined with the new consensus rule that v3 transaction formats will be invalid from the Sapling upgrade, this effectively means that all transaction signatures from the Sapling activation height (as specified in 6) will use the new algorithm.

-

The BLAKE2b-256 personalization field 3 is set to:

-
"ZcashSigHash" || CONSENSUS_BRANCH_ID
-

CONSENSUS_BRANCH_ID is the 4-byte little-endian encoding of the consensus branch ID for the epoch of the block containing the transaction. 5 Domain separation of the signature hash across parallel consensus branches provides replay protection: transactions targeted for one consensus branch will have invalid signatures on other consensus branches.

-

Transaction creators MUST specify the epoch they want their transaction to be mined in. Across a network upgrade, this means that if a transaction is not mined before the activation height, it will never be mined.

-

Semantics of the original sighash types are as in ZIP 143 4.

-

Field definitions

-

The items 1, 2, 3, 4, 5, 9, 10, 12, and 13 have the same meaning as in ZIP 143 4.

-

6: hashJoinSplits

-
    -
  • If vjoinsplits is non-empty, hashJoinSplits is the BLAKE2b-256 hash of the serialization of all JoinSplit descriptions (in their canonical v4 transaction serialization format) concatenated with the joinSplitPubKey; -
      -
    • The BLAKE2b-256 personalization field is set to ZcashJSplitsHash.
    • -
    • Note that while signatures are omitted, the JoinSplit proofs are included in the signature hash, as with v1, v2, and v3 transactions.
    • -
    -
  • -
  • Otherwise, hashJoinSplits is a uint256 of 0x0000......0000.
  • -
-
-

7: hashShieldedSpends

-
    -
  • If vShieldedSpend is non-empty, hashShieldedSpends is the BLAKE2b-256 hash of the serialization of all Spend Descriptions (in their canonical transaction serialization format minus spendAuthSig); -
      -
    • The BLAKE2b-256 personalization field is set to ZcashSSpendsHash.
    • -
    • Note that the Spend proofs are included in the signature hash, as with JoinSplit proofs in v1, v2, and v3 transactions.
    • -
    -
  • -
  • Otherwise, hashShieldedSpends is a uint256 of 0x0000......0000.
  • -
-
-

8: hashShieldedOutputs

-
    -
  • If vShieldedOutput is non-empty, hashShieldedOutputs is the BLAKE2b-256 hash of the serialization of all Output Descriptions (in their canonical transaction serialization format); -
      -
    • The BLAKE2b-256 personalization field is set to ZcashSOutputHash.
    • -
    • Note that the Output proofs are included in the signature hash, as with JoinSplit proofs in v1, v2, and v3 transactions.
    • -
    -
  • -
  • Otherwise, hashShieldedOutputs is a uint256 of 0x0000......0000.
  • -
-
-

11: valueBalance

-

An 8-byte signed two's-complement little-endian value of the net amount, in zatoshi, exiting the Sapling value pool. For clarity, a negative value corresponds to an amount entering the Sapling value pool.

-
-
-

Notes

-

The hashPrevouts, hashSequence, hashOutputs, hashJoinSplits, hashShieldedSpends, and hashShieldedOutputs calculated in an earlier validation can be reused in other inputs of the same transaction, so that the time complexity of the whole hashing process reduces from O(n2) to O(n).

-

Refer to the reference implementation, reproduced below, for the precise algorithm:

-
const unsigned char ZCASH_PREVOUTS_HASH_PERSONALIZATION[16] =
-    {'Z','c','a','s','h','P','r','e','v','o','u','t','H','a','s','h'};
-const unsigned char ZCASH_SEQUENCE_HASH_PERSONALIZATION[16] =
-    {'Z','c','a','s','h','S','e','q','u','e','n','c','H','a','s','h'};
-const unsigned char ZCASH_OUTPUTS_HASH_PERSONALIZATION[16] =
-    {'Z','c','a','s','h','O','u','t','p','u','t','s','H','a','s','h'};
-const unsigned char ZCASH_JOINSPLITS_HASH_PERSONALIZATION[16] =
-    {'Z','c','a','s','h','J','S','p','l','i','t','s','H','a','s','h'};
-const unsigned char ZCASH_SHIELDED_SPENDS_HASH_PERSONALIZATION[16] =
-    {'Z','c','a','s','h','S','S','p','e','n','d','s','H','a','s','h'};
-const unsigned char ZCASH_SHIELDED_OUTPUTS_HASH_PERSONALIZATION[16] =
-    {'Z','c','a','s','h','S','O','u','t','p','u','t','H','a','s','h'};
-
-// The default values are zeroes
-uint256 hashPrevouts;
-uint256 hashSequence;
-uint256 hashOutputs;
-uint256 hashJoinSplits;
-uint256 hashShieldedSpends;
-uint256 hashShieldedOutputs;
-
-if (!(nHashType & SIGHASH_ANYONECANPAY)) {
-    CBLAKE2bWriter ss(SER_GETHASH, 0, ZCASH_PREVOUTS_HASH_PERSONALIZATION);
-    for (unsigned int n = 0; n < txTo.vin.size(); n++) {
-        ss << txTo.vin[n].prevout;
-    }
-    hashPrevouts = ss.GetHash();
-}
-
-if (!(nHashType & SIGHASH_ANYONECANPAY) && (nHashType & 0x1f) != SIGHASH_SINGLE && (nHashType & 0x1f) != SIGHASH_NONE) {
-    CBLAKE2bWriter ss(SER_GETHASH, 0, ZCASH_SEQUENCE_HASH_PERSONALIZATION);
-    for (unsigned int n = 0; n < txTo.vin.size(); n++) {
-        ss << txTo.vin[n].nSequence;
-    }
-    hashSequence = ss.GetHash();
-}
-
-if ((nHashType & 0x1f) != SIGHASH_SINGLE && (nHashType & 0x1f) != SIGHASH_NONE) {
-    CBLAKE2bWriter ss(SER_GETHASH, 0, ZCASH_OUTPUTS_HASH_PERSONALIZATION);
-    for (unsigned int n = 0; n < txTo.vout.size(); n++) {
-        ss << txTo.vout[n];
-    }
-    hashOutputs = ss.GetHash();
-} else if ((nHashType & 0x1f) == SIGHASH_SINGLE && nIn < txTo.vout.size()) {
-    CBLAKE2bWriter ss(SER_GETHASH, 0, ZCASH_OUTPUTS_HASH_PERSONALIZATION);
-    ss << txTo.vout[nIn];
-    hashOutputs = ss.GetHash();
-}
-
-if (!txTo.vjoinsplit.empty()) {
-    CBLAKE2bWriter ss(SER_GETHASH, 0, ZCASH_JOINSPLITS_HASH_PERSONALIZATION);
-    for (unsigned int n = 0; n < txTo.vjoinsplit.size(); n++) {
-        ss << txTo.vjoinsplit[n];
-    }
-    ss << txTo.joinSplitPubKey;
-    hashJoinSplits = ss.GetHash();
-}
-
-if (!txTo.vShieldedSpend.empty()) {
-    CBLAKE2bWriter ss(SER_GETHASH, 0, ZCASH_SHIELDED_SPENDS_HASH_PERSONALIZATION);
-    for (unsigned int n = 0; n < txTo.vShieldedSpend.size(); n++) {
-        ss << txTo.vShieldedSpend[n].cv;
-        ss << txTo.vShieldedSpend[n].anchor;
-        ss << txTo.vShieldedSpend[n].nullifier;
-        ss << txTo.vShieldedSpend[n].rk;
-        ss << txTo.vShieldedSpend[n].zkproof;
-    }
-    hashShieldedSpends = ss.GetHash();
-}
-
-if (!txTo.vShieldedOutput.empty()) {
-    CBLAKE2bWriter ss(SER_GETHASH, 0, ZCASH_SHIELDED_OUTPUTS_HASH_PERSONALIZATION);
-    for (unsigned int n = 0; n < txTo.vShieldedOutput.size(); n++) {
-        ss << txTo.vShieldedOutput[n];
-    }
-    hashShieldedOutputs = ss.GetHash();
-}
-
-uint32_t leConsensusBranchId = htole32(consensusBranchId);
-unsigned char personalization[16] = {};
-memcpy(personalization, "ZcashSigHash", 12);
-memcpy(personalization+12, &leConsensusBranchId, 4);
-
-CBLAKE2bWriter ss(SER_GETHASH, 0, personalization);
-// fOverwintered and nVersion
-ss << txTo.GetHeader();
-// Version group ID
-ss << txTo.nVersionGroupId;
-// Input prevouts/nSequence (none/all, depending on flags)
-ss << hashPrevouts;
-ss << hashSequence;
-// Outputs (none/one/all, depending on flags)
-ss << hashOutputs;
-// JoinSplit descriptions
-ss << hashJoinSplits;
-// Spend descriptions
-ss << hashShieldedSpends;
-// Output descriptions
-ss << hashShieldedOutputs;
-// Locktime
-ss << txTo.nLockTime;
-// Expiry height
-ss << txTo.nExpiryHeight;
-// Sapling value balance
-ss << txTo.valueBalance;
-// Sighash type
-ss << nHashType;
-
-if (nIn != NOT_AN_INPUT) {
-    // The input being signed (replacing the scriptSig with scriptCode + amount)
-    // The prevout may already be contained in hashPrevout, and the nSequence
-    // may already be contained in hashSequence.
-    ss << txTo.vin[nIn].prevout;
-    ss << static_cast<const CScriptBase&>(scriptCode);
-    ss << amount;
-    ss << txTo.vin[nIn].nSequence;
-}
-
-return ss.GetHash();
-
-
-

Example

-

To ensure consistency in consensus-critical behaviour, developers should test their implementations against the ZIP 243 test vectors 7. The first two test vectors are broken out below for clarity. Note that 32-byte values below are exactly as the hash function returns, and are not reversed. Further examples can be found in the SignatureHash test data 8.

-

The sample transactions below and in 8 are intended only for testing implementations of the transaction digest algorithm; they do not necessarily pass full validation.

-

Test vector 1

-

Raw transaction:

-
0400008085202f890002e7719811893e0000095200ac6551ac636565b2835a0805750200025151481cdd86b3cc4318442117623ceb0500031b3d1a027c2c40590958b7eb13d742a997738c46a458965baf276ba92f272c721fe01f7e9c8e36d6a5e29d4e30a73594bf5098421c69378af1e40f64e125946f62c2fa7b2fecbcb64b6968912a6381ce3dc166d56a1d62f5a8d7551db5fd931325c9a138f49b1a537edcf04be34a9851a7af9db6990ed83dd64af3597c04323ea51b0052ad8084a8b9da948d320dadd64f5431e61ddf658d24ae67c22c8d1309131fc00fe7f235734276d38d47f1e191e00c7a1d48af046827591e9733a97fa6b679f3dc601d008285edcbdae69ce8fc1be4aac00ff2711ebd931de518856878f73476f21a482ec9378365c8f7393c94e2885315eb4671098b79535e790fe53e29fef2b3766697ac32b4f473f468a008e72389fc03880d780cb07fcfaabe3f1a84b27db59a4a153d882d2b2103596555ed9494c6ac893c49723833ec8926c1039586a7afcf4a0d9c731e985d99589c8bb838e8aaf745533ed9e8ae3a1cd074a51a20da8aba18d1dbebbc862ded42435e92476930d069896cff30eb414f727b895a4b7be1769367e1fe8ad18de11e58d88a0ad5511d3525122b7b0a6f25d28b16457e745939ffedbd12863ce71a02af117d417adb3d15cc54dcb1fce467500c6b8fb86b12b56da9c382857deecc40a98d5f2935395ee4762dd21afdbb5d47fa9a6dd984d567db2857b927b7fae2db587105415d4642789d38f50b8dbcc129cab3d17d19f3355bcf73cecb8cb8a5da01307152f13936a270572670dc82d39026c6cb4cd4b0f7f5aa2a4f5a5341ec5dd715406f2fdd2afa733f5f641c8c21862a1bafce2609d9eecfa158cfb5cd79f88008e315dc7d8388e76c1782fd2795d18a763624c25fa959cc97489ce75745824b77868c53239cfbdf73caec65604037314faaceb56218c6bd30f8374ac13386793f21a9fb80ad03bc0cda4a44946c00e1b1a1df0e5b87b5bece477a709649e950060591394812951e1fe3895b8cc3d14d2cf6556df6ed4b4ddd3d9a69f53357d7767f4f5ccbdbc596631277f8fecd08cb056b95e3025b9792fff7f244fc716269b926d62e9596fa825c6bf21aff9e68625a6b4cbc4b700a364fa76bd8298bc3ec608d4cf7f3566658d5588714ec9448b0f0396128aef884a646114c9f1a6df56319033c3199cc7a09e9e9567482c92695390229407bbc48985675e3f874a4533f1d63a84dfa3e0f460fe2f57e34fbc75423b6883a50a0d470190dfba10a857f82842d3825b3d6da0573d316eb160dc0b716c48fbd467f75b780149ae8808f4e68f50c0536acddf6f1aeab016b6bc1ec144b4e553acfd670f77e755fc88e0677e31ba459b44e307768958fe3789d41c2b1ff434cb30e15914f01bc6bc2307b488d2556d7b7380ea4ffd712f6b02fe806b94569cd4059f396bf29b99d0a40e5e1711ca944f72d436a102fca4b97693da0b086fe9d2e7162470d02e0f05d4bec9512bfb3f38327296efaa74328b118c27402c70c3a90b49ad4bbc68e37c0aa7d9b3fe17799d73b841e751713a02943905aae0803fd69442eb7681ec2a05600054e92eed555028f21b6a155268a2dd6640a69301a52a38d4d9f9f957ae35af7167118141ce4c9be0a6a492fe79f1581a155fa3a034999c538f7a758bb5b1d28fd218fba1938744bdb77b4a4dfa7a5fae96e8cd49b26907dfc6685c5c99b7141ac626ab4761fd3f41e728e1a28f89db89ffdeca364e4b22d81d9968d0119e4c7a189adf22ad96830a54e40dc73eaba6b2aaf14f7ca942e7370b247c046f8e75ef8e3f8bd821cf577491864e20e6d08fd2e32b555c92c661f19588b72a89599710a88061253ca285b6304b37da2b5294f5cb354a894322848ccbdc7c2545b7da568afac87ffa005c312241c2d57f4b45d6419f0d2e2c5af33ae243785b325cdab95404fc7aed70525cddb41872cfcc214b13232edc78609753dbff930eb0dc156612b9cb434bc4b693392deb87c530435312edcedc6a961133338d786c4a3e103f60110a16b1337129704bf4754ff6ba9fbe65951e610620f71cda8fc877625f2c5bb04cbe1228b1e886f4050afd8fe94e97d2e9e85c6bb748c0042d3249abb1342bb0eebf62058bf3de080d94611a3750915b5dc6c0b3899d41222bace760ee9c8818ded599e34c56d7372af1eb86852f2a732104bdb750739de6c2c6e0f9eb7cb17f1942bfc9f4fd6ebb6b4cdd4da2bca26fac4578e9f543405acc7d86ff59158bd0cba3aef6f4a8472d144d99f8b8d1dedaa9077d4f01d4bb27bbe31d88fbefac3dcd4797563a26b1d61fcd9a464ab21ed550fe6fa09695ba0b2f10eea6468cc6e20a66f826e3d14c5006f0563887f5e1289be1b2004caca8d3f34d6e84bf59c1e04619a7c23a996941d889e4622a9b9b1d59d5e319094318cd405ba27b7e2c084762d31453ec4549a4d97729d033460fcf89d6494f2ffd789e98082ea5ce9534b3acd60fe49e37e4f666931677319ed89f85588741b3128901a93bd78e4be0225a9e2692c77c969ed0176bdf9555948cbd5a332d045de6ba6bf4490adfe7444cd467a09075417fcc0062e49f008c51ad4227439c1b4476ccd8e97862dab7be1e8d399c05ef27c6e22ee273e15786e394c8f1be31682a30147963ac8da8d41d804258426a3f70289b8ad19d8de13be4eebe3bd4c8a6f55d6e0c373d456851879f5fbc282db9e134806bff71e11bc33ab75dd6ca067fb73a043b646a7cf39cab4928386786d2f24141ee120fdc34d6764eafc66880ee0204f53cc1167ed20b43a52dea3ca7cff8ef35cd8e6d7c111a68ef44bcd0c1513ad47ca61c659cc5d325b440f6b9f59aff66879bb6688fd2859362b182f207b3175961f6411a493bffd048e7d0d87d82fe6f990a2b0a25f5aa0111a6e68f37bf6f3ac2d26b84686e569d58d99c1383597fad81193c4c1b16e6a90e2d507cdfe6fbdaa86163e9cf5de3100fbca7e8da047b09079362d7792deb3ca9dc1561b87c82e3cb99eb5837319582216a3226774efa90efb7bfc79f425644e4e98c2d7d8642b9db82aa739bf2d71cc4117227db227cf0a05ad9a95832e23c94f271ca0e4694fac6322282ebac6986b8fdc8ad863084ff10fd11e6a13311fb799c79c641d9da43b33e7ad012e28255398789262275f1175be8462c01491c4d842406d0ec4282c9526174a09878fe8fdde33a29604e5e5e7b2a025d6650b97dbb52befb59b1d30a57433b0a351474444099daa371046613260cf3354cfcdada663ece824ffd7e44393886a86165ddddf2b4c41773554c86995269408b11e6737a4c447586f69173446d8e48bf84cbc000a807899973eb93c5e819aad669413f8387933ad1584aa35e43f4ecd1e2d0407c0b1b89920ffdfdb9bea51ac95b557af71b89f903f5d9848f14fcbeb1837570f544d6359eb23faf38a0822da36ce426c4a2fbeffeb0a8a2e297a9d19ba15024590e3329d9fa9261f9938a4032dd34606c9cf9f3dd33e576f05cd1dd6811c6298757d77d9e810abdb226afcaa4346a6560f8932b3181fd355d5d391976183f8d99388839632d6354f666d09d3e5629ea19737388613d38a34fd0f6e50ee5a0cc9677177f50028c141378187bd2819403fc534f80076e9380cb4964d3b6b45819d3b8e9caf54f051852d671bf8c1ffde2d1510756418cb4810936aa57e6965d6fb656a760b7f19adf96c173488552193b147ee58858033dac7cd0eb204c06490bbdedf5f7571acb2ebe76acef3f2a01ee987486dfe6c3f0a5e234c127258f97a28fb5d164a8176be946b8097d0e317287f33bf9c16f9a545409ce29b1f4273725fc0df02a04ebae178b3414fb0a82d50deb09fcf4e6ee9d180ff4f56ff3bc1d3601fc2dc90d814c3256f4967d3a8d64c83fea339c51f5a8e5801fbb97835581b602465dee04b5922c2761b54245bec0c9eef2db97d22b2b3556cc969fbb13d06509765a52b3fac54b93f421bf08e18d52ddd52cc1c8ca8adfaccab7e5cc2f4573fbbf8239bb0b8aedbf8dad16282da5c9125dba1c059d0df8abf621078f02d6c4bc86d40845ac1d59710c45f07d585eb48b32fc0167ba256e73ca3b9311c62d109497957d8dbe10aa3e866b40c0baa2bc492c19ad1e6372d9622bf163fbffeaeee796a3cd9b6fbbfa4d792f34d7fd6e763cd5859dd26833d21d9bc5452bd19515dff9f4995b35bc0c1f876e6ad11f2452dc9ae85aec01fc56f8cbfda75a7727b75ebbd6bbffb43b63a3b1b671e40feb0db002974a3c3b1a788567231bf6399ff89236981149d423802d2341a3bedb9ddcbac1fe7b6435e1479c72e7089b51bfe2ff345857da9b545e88e3221f3f5f72d1e069c9a85dd2236d390989587be005cda16af4408f3ab06a916eeeb9c9594b70424a4c1d171295b6763b22f4712ba7beff0ff27883afaff26034b895735709cf937bd2231891e70eb2771e9927c97f8764eb48e911d428ec8d861b708e8298acb62155145155ae95f0a1d1501034753146e22d05f586d7f6b4fe12dad9a17f5db70b1db96b8d9a83edadc966c8a5466b61fc998c31f1070d9a5c9a6d268d304fe6b8fd3b4010348611abdcbd49fe4f85b623c7828c71382e1034ea67bc8ae97404b0c50b2a04f559e49950afcb0ef462a2ae024b0f0224dfd73684b88c7fbe92d02b68f759c4752663cd7b97a14943649305521326bde085630864629291bae25ff8822a14c4b666a9259ad0dc42a8290ac7bc7f53a16f379f758e5de750f04fd7cad47701c8597f97888bea6fa0bf2999956fbfd0ee68ec36e4688809ae231eb8bc4369f5fe1573f57e099d9c09901bf39caac48dc11956a8ae905ead86954547c448ae43d315e669c4242da565938f417bf43ce7b2b30b1cd4018388e1a910f0fc41fb0877a5925e466819d375b0a912d4fe843b76ef6f223f0f7c894f38f7ab780dfd75f669c8c06cffa43eb47565a50e3b1fa45ad61ce9a1c4727b7aaa53562f523e73952bbf33d8a4104078ade3eaaa49699a69fdf1c5ac7732146ee5e1d6b6ca9b9180f964cc9d0878ae1373524d7d510e58227df6de9d30d271867640177b0f1856e28d5c8afb095ef6184fed651589022eeaea4c0ce1fa6f085092b04979489172b3ef8194a798df5724d6b05f1ae000013a08d612bca8a8c31443c10346dbf61de8475c0bbec5104b47556af3d514458e2321d146071789d2335934a680614e83562f82dfd405b54a45eb32c165448d4d5d61ca2859585369f53f1a137e9e82b67b8fdaf01bda54a317311896ae10280a032440c420a421e944d1e952b70d5826cd3b08b7db9630fe4fd5f22125de840fcc40b98038af11d55be25432597b4b65b9ec1c7a8bbfd052cbf7e1c1785314934b262d5853754f1f17771cfb7503072655753fa3f54ecc587e9f83b581916092df26e63e18994cb0db91a0bbdc7b6119b32222adf5e61d8d8ae89dae4954b54813bb33f08d562ba513fee1b09c0fcd516055419474dd7fda038a89c84ea7b9468287f0eb0c10c4b132520194d3d8d5351fc10d09c15c8cc101aa1663bbf17b84111f38bb439f07353bdea3596d15e713e1e2e7d3f1c383135b47fa7f81f46df7a902a404699ec912f5656c35b85763e4de583aecaa1dfd5d2677d9c8ffee877f63f40a5ca0d67f6e554124700f805af876aeede53aa8b0f8e5604a73c30cbd09dad963d6f8a5dcc40def40797342113ba206fae8ebe4f3bc3caf69259e462eff9ba8b3f4bfaa1300c26925a87
-
-header:          04000080
-nVersionGroupId: 85202f89
-vin:             00
-vout:            02 e7719811893e0000 095200ac6551ac636565
-                    b2835a0805750200 025151
-nLockTime:       481cdd86
-nExpiryHeight:   b3cc4318
-valueBalance:    442117623ceb0500
-vShieldedSpend:  03
-  cv:           1b3d1a027c2c40590958b7eb13d742a997738c46a458965baf276ba92f272c72
-  anchor:       1fe01f7e9c8e36d6a5e29d4e30a73594bf5098421c69378af1e40f64e125946f
-  nullifier:    62c2fa7b2fecbcb64b6968912a6381ce3dc166d56a1d62f5a8d7551db5fd9313
-  rk:           25c9a138f49b1a537edcf04be34a9851a7af9db6990ed83dd64af3597c04323e
-  zkproof:      a51b0052ad8084a8b9da948d320dadd64f5431e61ddf658d24ae67c22c8d1309131fc00fe7f235734276d38d47f1e191e00c7a1d48af046827591e9733a97fa6b679f3dc601d008285edcbdae69ce8fc1be4aac00ff2711ebd931de518856878f73476f21a482ec9378365c8f7393c94e2885315eb4671098b79535e790fe53e29fef2b3766697ac32b4f473f468a008e72389fc03880d780cb07fcfaabe3f1a84b27db59a4a153d882d2b2103596555ed9494c6ac893c49723833ec8926c103
-  spendAuthSig: 9586a7afcf4a0d9c731e985d99589c8bb838e8aaf745533ed9e8ae3a1cd074a51a20da8aba18d1dbebbc862ded42435e92476930d069896cff30eb414f727b89
-
-  cv:           5a4b7be1769367e1fe8ad18de11e58d88a0ad5511d3525122b7b0a6f25d28b16
-  anchor:       457e745939ffedbd12863ce71a02af117d417adb3d15cc54dcb1fce467500c6b
-  nullifier:    8fb86b12b56da9c382857deecc40a98d5f2935395ee4762dd21afdbb5d47fa9a
-  rk:           6dd984d567db2857b927b7fae2db587105415d4642789d38f50b8dbcc129cab3
-  zkproof:      d17d19f3355bcf73cecb8cb8a5da01307152f13936a270572670dc82d39026c6cb4cd4b0f7f5aa2a4f5a5341ec5dd715406f2fdd2afa733f5f641c8c21862a1bafce2609d9eecfa158cfb5cd79f88008e315dc7d8388e76c1782fd2795d18a763624c25fa959cc97489ce75745824b77868c53239cfbdf73caec65604037314faaceb56218c6bd30f8374ac13386793f21a9fb80ad03bc0cda4a44946c00e1b1a1df0e5b87b5bece477a709649e950060591394812951e1fe3895b8cc3d14d2c
-  spendAuthSig: f6556df6ed4b4ddd3d9a69f53357d7767f4f5ccbdbc596631277f8fecd08cb056b95e3025b9792fff7f244fc716269b926d62e9596fa825c6bf21aff9e68625a
-
-  cv:           6b4cbc4b700a364fa76bd8298bc3ec608d4cf7f3566658d5588714ec9448b0f0
-  anchor:       396128aef884a646114c9f1a6df56319033c3199cc7a09e9e9567482c9269539
-  nullifier:    0229407bbc48985675e3f874a4533f1d63a84dfa3e0f460fe2f57e34fbc75423
-  rk:           b6883a50a0d470190dfba10a857f82842d3825b3d6da0573d316eb160dc0b716
-  zkproof:      c48fbd467f75b780149ae8808f4e68f50c0536acddf6f1aeab016b6bc1ec144b4e553acfd670f77e755fc88e0677e31ba459b44e307768958fe3789d41c2b1ff434cb30e15914f01bc6bc2307b488d2556d7b7380ea4ffd712f6b02fe806b94569cd4059f396bf29b99d0a40e5e1711ca944f72d436a102fca4b97693da0b086fe9d2e7162470d02e0f05d4bec9512bfb3f38327296efaa74328b118c27402c70c3a90b49ad4bbc68e37c0aa7d9b3fe17799d73b841e751713a02943905aae08
-  spendAuthSig: 03fd69442eb7681ec2a05600054e92eed555028f21b6a155268a2dd6640a69301a52a38d4d9f9f957ae35af7167118141ce4c9be0a6a492fe79f1581a155fa3a
-
-vShieldedOutput: 03
-  cv:            4999c538f7a758bb5b1d28fd218fba1938744bdb77b4a4dfa7a5fae96e8cd49b
-  cmu:           26907dfc6685c5c99b7141ac626ab4761fd3f41e728e1a28f89db89ffdeca364
-  ephemeralKey:  e4b22d81d9968d0119e4c7a189adf22ad96830a54e40dc73eaba6b2aaf14f7ca
-  encCiphertext: 942e7370b247c046f8e75ef8e3f8bd821cf577491864e20e6d08fd2e32b555c92c661f19588b72a89599710a88061253ca285b6304b37da2b5294f5cb354a894322848ccbdc7c2545b7da568afac87ffa005c312241c2d57f4b45d6419f0d2e2c5af33ae243785b325cdab95404fc7aed70525cddb41872cfcc214b13232edc78609753dbff930eb0dc156612b9cb434bc4b693392deb87c530435312edcedc6a961133338d786c4a3e103f60110a16b1337129704bf4754ff6ba9fbe65951e610620f71cda8fc877625f2c5bb04cbe1228b1e886f4050afd8fe94e97d2e9e85c6bb748c0042d3249abb1342bb0eebf62058bf3de080d94611a3750915b5dc6c0b3899d41222bace760ee9c8818ded599e34c56d7372af1eb86852f2a732104bdb750739de6c2c6e0f9eb7cb17f1942bfc9f4fd6ebb6b4cdd4da2bca26fac4578e9f543405acc7d86ff59158bd0cba3aef6f4a8472d144d99f8b8d1dedaa9077d4f01d4bb27bbe31d88fbefac3dcd4797563a26b1d61fcd9a464ab21ed550fe6fa09695ba0b2f10eea6468cc6e20a66f826e3d14c5006f0563887f5e1289be1b2004caca8d3f34d6e84bf59c1e04619a7c23a996941d889e4622a9b9b1d59d5e319094318cd405ba27b7e2c084762d31453ec4549a4d97729d033460fcf89d6494f2ffd789e98082ea5ce9534b3acd60fe49e37e4f666931677319ed89f85588741b3128901a93bd78e4be0225a9e2692c77c969ed0176bdf9555948cbd5a332d045de6ba6bf4490adfe7444cd467a09075417fcc0062e49f008c51ad4227439c1b4476c
-  outCiphertext: cd8e97862dab7be1e8d399c05ef27c6e22ee273e15786e394c8f1be31682a30147963ac8da8d41d804258426a3f70289b8ad19d8de13be4eebe3bd4c8a6f55d6e0c373d456851879f5fbc282db9e1348
-  zkproof:       06bff71e11bc33ab75dd6ca067fb73a043b646a7cf39cab4928386786d2f24141ee120fdc34d6764eafc66880ee0204f53cc1167ed20b43a52dea3ca7cff8ef35cd8e6d7c111a68ef44bcd0c1513ad47ca61c659cc5d325b440f6b9f59aff66879bb6688fd2859362b182f207b3175961f6411a493bffd048e7d0d87d82fe6f990a2b0a25f5aa0111a6e68f37bf6f3ac2d26b84686e569d58d99c1383597fad81193c4c1b16e6a90e2d507cdfe6fbdaa86163e9cf5de3100fbca7e8da047b090
-
-  cv:            79362d7792deb3ca9dc1561b87c82e3cb99eb5837319582216a3226774efa90e
-  cmu:           fb7bfc79f425644e4e98c2d7d8642b9db82aa739bf2d71cc4117227db227cf0a
-  ephemeralKey:  05ad9a95832e23c94f271ca0e4694fac6322282ebac6986b8fdc8ad863084ff1
-  encCiphertext: 0fd11e6a13311fb799c79c641d9da43b33e7ad012e28255398789262275f1175be8462c01491c4d842406d0ec4282c9526174a09878fe8fdde33a29604e5e5e7b2a025d6650b97dbb52befb59b1d30a57433b0a351474444099daa371046613260cf3354cfcdada663ece824ffd7e44393886a86165ddddf2b4c41773554c86995269408b11e6737a4c447586f69173446d8e48bf84cbc000a807899973eb93c5e819aad669413f8387933ad1584aa35e43f4ecd1e2d0407c0b1b89920ffdfdb9bea51ac95b557af71b89f903f5d9848f14fcbeb1837570f544d6359eb23faf38a0822da36ce426c4a2fbeffeb0a8a2e297a9d19ba15024590e3329d9fa9261f9938a4032dd34606c9cf9f3dd33e576f05cd1dd6811c6298757d77d9e810abdb226afcaa4346a6560f8932b3181fd355d5d391976183f8d99388839632d6354f666d09d3e5629ea19737388613d38a34fd0f6e50ee5a0cc9677177f50028c141378187bd2819403fc534f80076e9380cb4964d3b6b45819d3b8e9caf54f051852d671bf8c1ffde2d1510756418cb4810936aa57e6965d6fb656a760b7f19adf96c173488552193b147ee58858033dac7cd0eb204c06490bbdedf5f7571acb2ebe76acef3f2a01ee987486dfe6c3f0a5e234c127258f97a28fb5d164a8176be946b8097d0e317287f33bf9c16f9a545409ce29b1f4273725fc0df02a04ebae178b3414fb0a82d50deb09fcf4e6ee9d180ff4f56ff3bc1d3601fc2dc90d814c3256f4967d3a8d64c83fea339c51f5a8e5801fbb97835581b602465dee04b5922c2761b5424
-  outCiphertext: 5bec0c9eef2db97d22b2b3556cc969fbb13d06509765a52b3fac54b93f421bf08e18d52ddd52cc1c8ca8adfaccab7e5cc2f4573fbbf8239bb0b8aedbf8dad16282da5c9125dba1c059d0df8abf621078
-  zkproof:       f02d6c4bc86d40845ac1d59710c45f07d585eb48b32fc0167ba256e73ca3b9311c62d109497957d8dbe10aa3e866b40c0baa2bc492c19ad1e6372d9622bf163fbffeaeee796a3cd9b6fbbfa4d792f34d7fd6e763cd5859dd26833d21d9bc5452bd19515dff9f4995b35bc0c1f876e6ad11f2452dc9ae85aec01fc56f8cbfda75a7727b75ebbd6bbffb43b63a3b1b671e40feb0db002974a3c3b1a788567231bf6399ff89236981149d423802d2341a3bedb9ddcbac1fe7b6435e1479c72e7089
-
-  cv:            b51bfe2ff345857da9b545e88e3221f3f5f72d1e069c9a85dd2236d390989587
-  cmu:           be005cda16af4408f3ab06a916eeeb9c9594b70424a4c1d171295b6763b22f47
-  ephemeralKey:  12ba7beff0ff27883afaff26034b895735709cf937bd2231891e70eb2771e992
-  encCiphertext: 7c97f8764eb48e911d428ec8d861b708e8298acb62155145155ae95f0a1d1501034753146e22d05f586d7f6b4fe12dad9a17f5db70b1db96b8d9a83edadc966c8a5466b61fc998c31f1070d9a5c9a6d268d304fe6b8fd3b4010348611abdcbd49fe4f85b623c7828c71382e1034ea67bc8ae97404b0c50b2a04f559e49950afcb0ef462a2ae024b0f0224dfd73684b88c7fbe92d02b68f759c4752663cd7b97a14943649305521326bde085630864629291bae25ff8822a14c4b666a9259ad0dc42a8290ac7bc7f53a16f379f758e5de750f04fd7cad47701c8597f97888bea6fa0bf2999956fbfd0ee68ec36e4688809ae231eb8bc4369f5fe1573f57e099d9c09901bf39caac48dc11956a8ae905ead86954547c448ae43d315e669c4242da565938f417bf43ce7b2b30b1cd4018388e1a910f0fc41fb0877a5925e466819d375b0a912d4fe843b76ef6f223f0f7c894f38f7ab780dfd75f669c8c06cffa43eb47565a50e3b1fa45ad61ce9a1c4727b7aaa53562f523e73952bbf33d8a4104078ade3eaaa49699a69fdf1c5ac7732146ee5e1d6b6ca9b9180f964cc9d0878ae1373524d7d510e58227df6de9d30d271867640177b0f1856e28d5c8afb095ef6184fed651589022eeaea4c0ce1fa6f085092b04979489172b3ef8194a798df5724d6b05f1ae000013a08d612bca8a8c31443c10346dbf61de8475c0bbec5104b47556af3d514458e2321d146071789d2335934a680614e83562f82dfd405b54a45eb32c165448d4d5d61ca2859585369f53f1a137e9e82b67b8fdaf01bda54a31731189
-  outCiphertext: 6ae10280a032440c420a421e944d1e952b70d5826cd3b08b7db9630fe4fd5f22125de840fcc40b98038af11d55be25432597b4b65b9ec1c7a8bbfd052cbf7e1c1785314934b262d5853754f1f17771cf
-  zkproof:       b7503072655753fa3f54ecc587e9f83b581916092df26e63e18994cb0db91a0bbdc7b6119b32222adf5e61d8d8ae89dae4954b54813bb33f08d562ba513fee1b09c0fcd516055419474dd7fda038a89c84ea7b9468287f0eb0c10c4b132520194d3d8d5351fc10d09c15c8cc101aa1663bbf17b84111f38bb439f07353bdea3596d15e713e1e2e7d3f1c383135b47fa7f81f46df7a902a404699ec912f5656c35b85763e4de583aecaa1dfd5d2677d9c8ffee877f63f40a5ca0d67f6e5541247
-
-vJoinSplit:      00
-
-bindingSig:      f805af876aeede53aa8b0f8e5604a73c30cbd09dad963d6f8a5dcc40def40797342113ba206fae8ebe4f3bc3caf69259e462eff9ba8b3f4bfaa1300c26925a87
-

Transaction digest with nIn = NOT_AN_INPUT and nHashType = 1 (SIGHASH_ALL):

-
hashPrevouts:
-  BLAKE2b-256('ZcashPrevoutHash', '')
-= d53a633bbecf82fe9e9484d8a0e727c73bb9e68c96e72dec30144f6a84afa136
-
-hashSequence:
-  BLAKE2b-256('ZcashSequencHash', '')
-= a5f25f01959361ee6eb56a7401210ee268226f6ce764a4f10b7f29e54db37272
-
-hashOutputs:
-  BLAKE2b-256('ZcashOutputsHash', e7719811893e0000095200ac6551ac636565b2835a0805750200025151)
-= ab6f7f6c5ad6b56357b5f37e16981723db6c32411753e28c175e15589172194a
-
-hashShieldedSpends:
-  BLAKE2b-256('ZcashSSpendsHash', 1b3d1a027c2c40590958b7eb13d742a997738c46a458965baf276ba92f272c721fe01f7e9c8e36d6a5e29d4e30a73594bf5098421c69378af1e40f64e125946f62c2fa7b2fecbcb64b6968912a6381ce3dc166d56a1d62f5a8d7551db5fd931325c9a138f49b1a537edcf04be34a9851a7af9db6990ed83dd64af3597c04323ea51b0052ad8084a8b9da948d320dadd64f5431e61ddf658d24ae67c22c8d1309131fc00fe7f235734276d38d47f1e191e00c7a1d48af046827591e9733a97fa6b679f3dc601d008285edcbdae69ce8fc1be4aac00ff2711ebd931de518856878f73476f21a482ec9378365c8f7393c94e2885315eb4671098b79535e790fe53e29fef2b3766697ac32b4f473f468a008e72389fc03880d780cb07fcfaabe3f1a84b27db59a4a153d882d2b2103596555ed9494c6ac893c49723833ec8926c1035a4b7be1769367e1fe8ad18de11e58d88a0ad5511d3525122b7b0a6f25d28b16457e745939ffedbd12863ce71a02af117d417adb3d15cc54dcb1fce467500c6b8fb86b12b56da9c382857deecc40a98d5f2935395ee4762dd21afdbb5d47fa9a6dd984d567db2857b927b7fae2db587105415d4642789d38f50b8dbcc129cab3d17d19f3355bcf73cecb8cb8a5da01307152f13936a270572670dc82d39026c6cb4cd4b0f7f5aa2a4f5a5341ec5dd715406f2fdd2afa733f5f641c8c21862a1bafce2609d9eecfa158cfb5cd79f88008e315dc7d8388e76c1782fd2795d18a763624c25fa959cc97489ce75745824b77868c53239cfbdf73caec65604037314faaceb56218c6bd30f8374ac13386793f21a9fb80ad03bc0cda4a44946c00e1b1a1df0e5b87b5bece477a709649e950060591394812951e1fe3895b8cc3d14d2c6b4cbc4b700a364fa76bd8298bc3ec608d4cf7f3566658d5588714ec9448b0f0396128aef884a646114c9f1a6df56319033c3199cc7a09e9e9567482c92695390229407bbc48985675e3f874a4533f1d63a84dfa3e0f460fe2f57e34fbc75423b6883a50a0d470190dfba10a857f82842d3825b3d6da0573d316eb160dc0b716c48fbd467f75b780149ae8808f4e68f50c0536acddf6f1aeab016b6bc1ec144b4e553acfd670f77e755fc88e0677e31ba459b44e307768958fe3789d41c2b1ff434cb30e15914f01bc6bc2307b488d2556d7b7380ea4ffd712f6b02fe806b94569cd4059f396bf29b99d0a40e5e1711ca944f72d436a102fca4b97693da0b086fe9d2e7162470d02e0f05d4bec9512bfb3f38327296efaa74328b118c27402c70c3a90b49ad4bbc68e37c0aa7d9b3fe17799d73b841e751713a02943905aae08)
-= 3fd9edb96dccf5b9aeb71e3db3710e74be4f1dfb19234c1217af26181f494a36
-
-hashShieldedOutputs:
-  BLAKE2b-256('ZcashSOutputHash', 4999c538f7a758bb5b1d28fd218fba1938744bdb77b4a4dfa7a5fae96e8cd49b26907dfc6685c5c99b7141ac626ab4761fd3f41e728e1a28f89db89ffdeca364e4b22d81d9968d0119e4c7a189adf22ad96830a54e40dc73eaba6b2aaf14f7ca942e7370b247c046f8e75ef8e3f8bd821cf577491864e20e6d08fd2e32b555c92c661f19588b72a89599710a88061253ca285b6304b37da2b5294f5cb354a894322848ccbdc7c2545b7da568afac87ffa005c312241c2d57f4b45d6419f0d2e2c5af33ae243785b325cdab95404fc7aed70525cddb41872cfcc214b13232edc78609753dbff930eb0dc156612b9cb434bc4b693392deb87c530435312edcedc6a961133338d786c4a3e103f60110a16b1337129704bf4754ff6ba9fbe65951e610620f71cda8fc877625f2c5bb04cbe1228b1e886f4050afd8fe94e97d2e9e85c6bb748c0042d3249abb1342bb0eebf62058bf3de080d94611a3750915b5dc6c0b3899d41222bace760ee9c8818ded599e34c56d7372af1eb86852f2a732104bdb750739de6c2c6e0f9eb7cb17f1942bfc9f4fd6ebb6b4cdd4da2bca26fac4578e9f543405acc7d86ff59158bd0cba3aef6f4a8472d144d99f8b8d1dedaa9077d4f01d4bb27bbe31d88fbefac3dcd4797563a26b1d61fcd9a464ab21ed550fe6fa09695ba0b2f10eea6468cc6e20a66f826e3d14c5006f0563887f5e1289be1b2004caca8d3f34d6e84bf59c1e04619a7c23a996941d889e4622a9b9b1d59d5e319094318cd405ba27b7e2c084762d31453ec4549a4d97729d033460fcf89d6494f2ffd789e98082ea5ce9534b3acd60fe49e37e4f666931677319ed89f85588741b3128901a93bd78e4be0225a9e2692c77c969ed0176bdf9555948cbd5a332d045de6ba6bf4490adfe7444cd467a09075417fcc0062e49f008c51ad4227439c1b4476ccd8e97862dab7be1e8d399c05ef27c6e22ee273e15786e394c8f1be31682a30147963ac8da8d41d804258426a3f70289b8ad19d8de13be4eebe3bd4c8a6f55d6e0c373d456851879f5fbc282db9e134806bff71e11bc33ab75dd6ca067fb73a043b646a7cf39cab4928386786d2f24141ee120fdc34d6764eafc66880ee0204f53cc1167ed20b43a52dea3ca7cff8ef35cd8e6d7c111a68ef44bcd0c1513ad47ca61c659cc5d325b440f6b9f59aff66879bb6688fd2859362b182f207b3175961f6411a493bffd048e7d0d87d82fe6f990a2b0a25f5aa0111a6e68f37bf6f3ac2d26b84686e569d58d99c1383597fad81193c4c1b16e6a90e2d507cdfe6fbdaa86163e9cf5de3100fbca7e8da047b09079362d7792deb3ca9dc1561b87c82e3cb99eb5837319582216a3226774efa90efb7bfc79f425644e4e98c2d7d8642b9db82aa739bf2d71cc4117227db227cf0a05ad9a95832e23c94f271ca0e4694fac6322282ebac6986b8fdc8ad863084ff10fd11e6a13311fb799c79c641d9da43b33e7ad012e28255398789262275f1175be8462c01491c4d842406d0ec4282c9526174a09878fe8fdde33a29604e5e5e7b2a025d6650b97dbb52befb59b1d30a57433b0a351474444099daa371046613260cf3354cfcdada663ece824ffd7e44393886a86165ddddf2b4c41773554c86995269408b11e6737a4c447586f69173446d8e48bf84cbc000a807899973eb93c5e819aad669413f8387933ad1584aa35e43f4ecd1e2d0407c0b1b89920ffdfdb9bea51ac95b557af71b89f903f5d9848f14fcbeb1837570f544d6359eb23faf38a0822da36ce426c4a2fbeffeb0a8a2e297a9d19ba15024590e3329d9fa9261f9938a4032dd34606c9cf9f3dd33e576f05cd1dd6811c6298757d77d9e810abdb226afcaa4346a6560f8932b3181fd355d5d391976183f8d99388839632d6354f666d09d3e5629ea19737388613d38a34fd0f6e50ee5a0cc9677177f50028c141378187bd2819403fc534f80076e9380cb4964d3b6b45819d3b8e9caf54f051852d671bf8c1ffde2d1510756418cb4810936aa57e6965d6fb656a760b7f19adf96c173488552193b147ee58858033dac7cd0eb204c06490bbdedf5f7571acb2ebe76acef3f2a01ee987486dfe6c3f0a5e234c127258f97a28fb5d164a8176be946b8097d0e317287f33bf9c16f9a545409ce29b1f4273725fc0df02a04ebae178b3414fb0a82d50deb09fcf4e6ee9d180ff4f56ff3bc1d3601fc2dc90d814c3256f4967d3a8d64c83fea339c51f5a8e5801fbb97835581b602465dee04b5922c2761b54245bec0c9eef2db97d22b2b3556cc969fbb13d06509765a52b3fac54b93f421bf08e18d52ddd52cc1c8ca8adfaccab7e5cc2f4573fbbf8239bb0b8aedbf8dad16282da5c9125dba1c059d0df8abf621078f02d6c4bc86d40845ac1d59710c45f07d585eb48b32fc0167ba256e73ca3b9311c62d109497957d8dbe10aa3e866b40c0baa2bc492c19ad1e6372d9622bf163fbffeaeee796a3cd9b6fbbfa4d792f34d7fd6e763cd5859dd26833d21d9bc5452bd19515dff9f4995b35bc0c1f876e6ad11f2452dc9ae85aec01fc56f8cbfda75a7727b75ebbd6bbffb43b63a3b1b671e40feb0db002974a3c3b1a788567231bf6399ff89236981149d423802d2341a3bedb9ddcbac1fe7b6435e1479c72e7089b51bfe2ff345857da9b545e88e3221f3f5f72d1e069c9a85dd2236d390989587be005cda16af4408f3ab06a916eeeb9c9594b70424a4c1d171295b6763b22f4712ba7beff0ff27883afaff26034b895735709cf937bd2231891e70eb2771e9927c97f8764eb48e911d428ec8d861b708e8298acb62155145155ae95f0a1d1501034753146e22d05f586d7f6b4fe12dad9a17f5db70b1db96b8d9a83edadc966c8a5466b61fc998c31f1070d9a5c9a6d268d304fe6b8fd3b4010348611abdcbd49fe4f85b623c7828c71382e1034ea67bc8ae97404b0c50b2a04f559e49950afcb0ef462a2ae024b0f0224dfd73684b88c7fbe92d02b68f759c4752663cd7b97a14943649305521326bde085630864629291bae25ff8822a14c4b666a9259ad0dc42a8290ac7bc7f53a16f379f758e5de750f04fd7cad47701c8597f97888bea6fa0bf2999956fbfd0ee68ec36e4688809ae231eb8bc4369f5fe1573f57e099d9c09901bf39caac48dc11956a8ae905ead86954547c448ae43d315e669c4242da565938f417bf43ce7b2b30b1cd4018388e1a910f0fc41fb0877a5925e466819d375b0a912d4fe843b76ef6f223f0f7c894f38f7ab780dfd75f669c8c06cffa43eb47565a50e3b1fa45ad61ce9a1c4727b7aaa53562f523e73952bbf33d8a4104078ade3eaaa49699a69fdf1c5ac7732146ee5e1d6b6ca9b9180f964cc9d0878ae1373524d7d510e58227df6de9d30d271867640177b0f1856e28d5c8afb095ef6184fed651589022eeaea4c0ce1fa6f085092b04979489172b3ef8194a798df5724d6b05f1ae000013a08d612bca8a8c31443c10346dbf61de8475c0bbec5104b47556af3d514458e2321d146071789d2335934a680614e83562f82dfd405b54a45eb32c165448d4d5d61ca2859585369f53f1a137e9e82b67b8fdaf01bda54a317311896ae10280a032440c420a421e944d1e952b70d5826cd3b08b7db9630fe4fd5f22125de840fcc40b98038af11d55be25432597b4b65b9ec1c7a8bbfd052cbf7e1c1785314934b262d5853754f1f17771cfb7503072655753fa3f54ecc587e9f83b581916092df26e63e18994cb0db91a0bbdc7b6119b32222adf5e61d8d8ae89dae4954b54813bb33f08d562ba513fee1b09c0fcd516055419474dd7fda038a89c84ea7b9468287f0eb0c10c4b132520194d3d8d5351fc10d09c15c8cc101aa1663bbf17b84111f38bb439f07353bdea3596d15e713e1e2e7d3f1c383135b47fa7f81f46df7a902a404699ec912f5656c35b85763e4de583aecaa1dfd5d2677d9c8ffee877f63f40a5ca0d67f6e5541247)
-= dafece799f638ba7268bf8fe43f02a5112f0bb32a84c4a8c2f508c41ff1c78b5
-
-Preimage:
-0400008085202f89d53a633bbecf82fe9e9484d8a0e727c73bb9e68c96e72dec30144f6a84afa136a5f25f01959361ee6eb56a7401210ee268226f6ce764a4f10b7f29e54db37272ab6f7f6c5ad6b56357b5f37e16981723db6c32411753e28c175e15589172194a00000000000000000000000000000000000000000000000000000000000000003fd9edb96dccf5b9aeb71e3db3710e74be4f1dfb19234c1217af26181f494a36dafece799f638ba7268bf8fe43f02a5112f0bb32a84c4a8c2f508c41ff1c78b5481cdd86b3cc4318442117623ceb050001000000
-
-  header:              04000080
-  nVersionGroupId:     85202f89
-  hashPrevouts:        d53a633bbecf82fe9e9484d8a0e727c73bb9e68c96e72dec30144f6a84afa136
-  hashSequence:        a5f25f01959361ee6eb56a7401210ee268226f6ce764a4f10b7f29e54db37272
-  hashOutputs:         ab6f7f6c5ad6b56357b5f37e16981723db6c32411753e28c175e15589172194a
-  hashJoinSplits:      0000000000000000000000000000000000000000000000000000000000000000
-  hashShieldedSpends:  3fd9edb96dccf5b9aeb71e3db3710e74be4f1dfb19234c1217af26181f494a36
-  hashShieldedOutputs: dafece799f638ba7268bf8fe43f02a5112f0bb32a84c4a8c2f508c41ff1c78b5
-  nLockTime:           481cdd86
-  nExpiryHeight:       b3cc4318
-  valueBalance:        442117623ceb0500
-  nHashType:           01000000
-
-sighash: 63d18534de5f2d1c9e169b73f9c783718adbef5c8a7d55b5e7a37affa1dd3ff3
-
-

Test vector 2

-

Raw transaction:

-
0400008085202f89020bbe32a598c22adfb48cef72ba5d4287c0cefbacfd8ce195b4963c34a94bba7a175dae4b0465ac656353708915090f47a068e227433f9e49d3aa09e356d8d66d0c0121e91a3c4aa3f27fa1b63396e2b41d090063535300ac53ac514e97056802da071b970d4807000152a844550bdc2002000752526a65520052d7034302011b9a076620edc067ff0200000353e3b8a71face1c9f37745ed36883529304bfd5a390b37bc5a3445241f03f64a818820dfeddd75375159fbd21eca9872104f8d7b3c8c869703a1e7848a5c941e45a9c7943446d0dc9627cb31f80e7aa596d4821dc99a7d777cd57e194842a023471f0f6288a150647b2afe9df7cccf01f5cde5f04680bbfed87f6cf429fb27ad6babe791766611cf5bc20e48bef119259b9b8a0e39c3df28cb9582ea338601cdc481b32fb82adeebb3dade25d1a3df20c37e712506b5d996c49a9f0f30ddcb91fe9004e1e83294a6c9203d94e8dc2cbb449de4155032604e47997016b304fd437d8235045e255a19b743a0a9f2e336b44cae307bb3987bd3e4e777fbb34c0ab8cc3d67466c0a88dd4ccad18a07a8d1068df5b629e5718d0f6df5c957cf71bb00a5178f175caca944e635c5159f738e2402a2d21aa081e10e456afb00b9f62416c8b9c0f7228f510729e0be3f305313d77f7379dc2af24869c6c74ee4471498861d192f0ff0f508285dab6b6a36ccf7d12256cc76b95503720ac672d08268d2cf7773b6ba2a5f664847bf707f2fc10c98f2f006ec22ccb5a8c8b7c40c7c2d49a6639b9f2ce33c25c04bc461e744dfa536b00d94baddf4f4d14044c695a33881477df124f0fcf206a9fb2e65e304cdbf0c4d2390170c130ab849c2f22b5cdd3921640c8cf1976ae1010b0dfd9cb2543e45f99749cc4d61f2e8aabfe98bd905fa39951b33ea769c45ab9531c57209862ad12fd76ba4807e65417b6cd12fa8ec916f013ebb8706a96effeda06c4be24b04846392e9d1e6930eae01fa21fbd700583fb598b92c8f4eb8a61aa6235db60f2841cf3a1c6ab54c67066844711d091eb931a1bd6281aedf2a0e8fab18817202a9be06402ed9cc720c16bfe881e4df4255e87afb7fc62f38116bbe03cd8a3cb11a27d568414782f47b1a44c97c680467694bc9709d32916c97e8006cbb07ba0e4180a3738038c374c4cce8f32959afb25f303f5815c4533124acf9d18940e77522ac5dc4b9570aae8f47b7f57fd8767bea1a24ae7bed65b4afdc8f1278c30e2db98fd172730ac6bbed4f1127cd32b04a95b205526cfcb4c4e1cc955175b3e8de1f5d81b18669692350aaa1a1d797617582e54d7a5b57a683b32fb1098062dad7b0c2eb518f6862e83db25e3dbaf7aed504de932acb99d735992ce62bae9ef893ff6acc0ffcf8e3483e146b9d49dd8c7835f43a37dca0787e3ec9f6605223d5ba7ae0ab9025b73bc03f7fac36c009a56d4d95d1e81d3b3ebca7e54cc1a12d127b57c8138976e791013b015f06a624f521b6ee04ec980893c7e5e01a336203594094f82833d74427880084d35863c8e7ebb5c9eed98e72572ec40c79b26623b58022f489b0893d88be63f3f8c0d23249ebcde13db9312941c36c1d1cbcabac0c78cb3b1912db0dcbfe1893d9b51be4af1d000bac1ad0a3ae2ce1e73225fb114d05af4cefc06e875f074ffeae0cba7da3a516c173be1c513323e119f635e8209a074b216b7023fadc2d25949c90037e71e3e550726d210a2c688342e52440635e9cc14afe10102621a9c9accb782e9e4a5fa87f0a956f5b85509960285c22627c59483a5a4c28cce4b156e551406a7ee8355656a21e43e38ce129fdadb759eddfa08f00fc8e567cef93c6792d01df05e6d580f4d5d48df042451a33590d3e8cf49b2627218f0c292fa66ada945fa55bb23548e33a83a562957a3149a993cc472362298736a8b778d97ce423013d64b32cd172efa551bf7f368f04bdaec6091a3004a757598b801dcf675cb83e43a53ae8b254d333bcda20d4817d3477abfba25bb83df5949c126f149b1d99341e4e6f9120f4d41e629185002c72c012c414d2382a6d47c7b3deaba770c400ca96b2814f6b26c3ef17429f1a98c85d83db20efad48be8996fb1bff591efff360fe1199056c56e5feec61a7b8b9f699d6012c2849232f329fef95c7af370098ffe4918e0ca1df47f275867b739e0a514d3209325e217045927b479c1ce2e5d54f25488cad1513e3f44a21266cfd841633327dee6cf810fbf7393e317d9e53d1be1d5ae7839b66b943b9ed18f2c530e975422332c3439cce49a29f2a336a4851263c5e9bd13d731109e844b7f8c392a5c1dcaa2ae5f50ff63fab9765e016702c35a67cd7364d3fab552fb349e35c15c50250453fd18f7b855992632e2c76c0fbf1ef963ea80e3223de3277bc559251725829ec03f213ba8955cab2822ff21a9b0a4904d668fcd77224bde3dd01f6ffc4828f6b64230b35c6a049873494276ea1d7ed5e92cb4f90ba83a9e49601b194042f2900d99d312d7b70508cf176066d154dbe96ef9d4367e4c840e4a17b5e5122e8ebe2158a3c5f4cbae21ea3fa1ae6c25a9462ebcbb0fd5f14554bc97747c33e34da90c816d8d0d50bfe37618c5812891484fa259322c15092d4155d8696d6f12f24fd364496b3be0871ca3dd9625348a614b59bde45885649bae36de34def8fcec85343475d976ae1e9b27829ce2ac5efd0b399a8b448be6504294ee6b3c1c6a5342d7c01ae9d8ad3070c2b1a91573af5e0c5e4cbbf4acdc6b54c9272200d9970250c17c1036f06085c41858ed3a0c48150bc697e4a695fef335f7ad07e1a46dc767ff822db70e6669080b9816b2232c81a4c66cc586abfe1eaa8ca6cf41fc30eb8dc57c37a3c39c59c94232df9d388dbfa35c2cd5c75f328e9fea78f65568f2bb934c82c4142da69d12ca7de9a7df706400ec79878d868e17e8f71ea31495a8bae7bdc2e48b5118771c2fca078cca1fce0d7ef0af3478cf36f69e85a41dd29b4294a65d3e055ff718dd9dc8c75e7e5b2efe442637371b7c48f6ee99e3ea38a4b0f2f67fc2b908cda657eae754e037e262e9a9f9bd7ec4267ed8e96930e1084783c37d6f9dd15fd29f4cc477e66f130d630430dcc0104899b4f9f46eb090ef7fc90b479abf61f93955ee00e6a1848f1ab14ad334f2b68035808cdf1bb9e9d9a816baf728a955b960b7701fa626687dc3c9cba646337b53e29816e9482ddf5578a8768aae477fce410ac2d5de6095861c111d7feb3e6bb4fbb5a54955495972798350a253f05f66c2ecfcbc0ed43f5ec2e6d8dba15a51254d97b1821107c07dd9a16ef8406f943e282b95d4b362530c913d6ba421df6027de5af1e4745d5868106954be6c1962780a2941072e95131b1679df0637625042c37d48ffb152e5ebc185c8a2b7d4385f1c95af937df78dfd8757fab434968b0b57c66574468f160b447ac8221e5060676a842a1c6b7172dd3340f764070ab1fe091c5c74c95a5dc043390723a4c127da14cdde1dc2675a62340b3e6afd0522a31de26e7d1ec3a9c8a091ffdc75b7ecfdc7c12995a5e37ce3488bd29f8629d68f696492448dd526697476dc061346ebe3f677217ff9c60efce943af28dfd3f9e59692598a6047c23c4c01400f1ab5730eac0ae8d5843d5051c376240172af218d7a1ecfe65b4f75100638983c14de4974755dade8018c9b8f4543fb095961513e67c61dbc59c607f9b51f8d09bdcad28bcfb9e5d2744ea8848b2623ac07f8ef61a81a35910b8a1baf39a919a7b60bc604d63185f759221d847cc54a22765a4c33475b5791e9af3271fc8d9350667090d8184ec50522d804f23c4fb44ffa481bc92ae408d1b9f2b131904f9705c59e2f4bde7a3b2c085d93fd2abc5e14d163001a12f51938d021afa92239b873dc6c357eaa8af4ee6d00540657fe32914103b5d98f68bd3e2b5359f08ccd88d0c811e4c31fbb49f3a90bbd05dce62f344e7077593159ae35050b04c9e6b86bc432dc8b048c73c0018ca5b69411297732a4e1aa99a928c71e7a24fd277856aa42501e51b012aea9446a2104e93f815a0b3a29b458314f3d8be2b9823d342f46213e942a7e19a46e970b5c506708430317b1bb3b35df68ae33a4926a03e6bfeb5510416fcbb0524c9ca5074156cc5a5d6fe1c995edc60a2f550411aa41e3da3bdcf64bcf04a0510571b936d47e55cec0330008dfe73563404f047d7f3a8a3d7743bc554955210f1eb0d08599ea77d5f974d87176d37d98b9c0ad440407209ed6a9f08464d565593e1a63b938536b49244e97d
-
-header:          04000080
-nVersionGroupId: 85202f89
-vin:             02 0bbe32a598c22adfb48cef72ba5d4287c0cefbacfd8ce195b4963c34a94bba7a 175dae4b 0465ac6563 53708915
-                    090f47a068e227433f9e49d3aa09e356d8d66d0c0121e91a3c4aa3f27fa1b633 96e2b41d 090063535300ac53ac51 4e970568
-vout:            02 da071b970d480700 0152
-                    a844550bdc200200 0752526a65520052
-nLockTime:       d7034302
-nExpiryHeight:   011b9a07
-valueBalance:    6620edc067ff0200
-vShieldedSpend:  00
-
-vShieldedOutput: 03
-  cv:            53e3b8a71face1c9f37745ed36883529304bfd5a390b37bc5a3445241f03f64a
-  cmu:           818820dfeddd75375159fbd21eca9872104f8d7b3c8c869703a1e7848a5c941e
-  ephemeralKey:  45a9c7943446d0dc9627cb31f80e7aa596d4821dc99a7d777cd57e194842a023
-  encCiphertext: 471f0f6288a150647b2afe9df7cccf01f5cde5f04680bbfed87f6cf429fb27ad6babe791766611cf5bc20e48bef119259b9b8a0e39c3df28cb9582ea338601cdc481b32fb82adeebb3dade25d1a3df20c37e712506b5d996c49a9f0f30ddcb91fe9004e1e83294a6c9203d94e8dc2cbb449de4155032604e47997016b304fd437d8235045e255a19b743a0a9f2e336b44cae307bb3987bd3e4e777fbb34c0ab8cc3d67466c0a88dd4ccad18a07a8d1068df5b629e5718d0f6df5c957cf71bb00a5178f175caca944e635c5159f738e2402a2d21aa081e10e456afb00b9f62416c8b9c0f7228f510729e0be3f305313d77f7379dc2af24869c6c74ee4471498861d192f0ff0f508285dab6b6a36ccf7d12256cc76b95503720ac672d08268d2cf7773b6ba2a5f664847bf707f2fc10c98f2f006ec22ccb5a8c8b7c40c7c2d49a6639b9f2ce33c25c04bc461e744dfa536b00d94baddf4f4d14044c695a33881477df124f0fcf206a9fb2e65e304cdbf0c4d2390170c130ab849c2f22b5cdd3921640c8cf1976ae1010b0dfd9cb2543e45f99749cc4d61f2e8aabfe98bd905fa39951b33ea769c45ab9531c57209862ad12fd76ba4807e65417b6cd12fa8ec916f013ebb8706a96effeda06c4be24b04846392e9d1e6930eae01fa21fbd700583fb598b92c8f4eb8a61aa6235db60f2841cf3a1c6ab54c67066844711d091eb931a1bd6281aedf2a0e8fab18817202a9be06402ed9cc720c16bfe881e4df4255e87afb7fc62f38116bbe03cd8a3cb11a27d568414782f47b1a44c97c680467694bc9709d32
-  outCiphertext: 916c97e8006cbb07ba0e4180a3738038c374c4cce8f32959afb25f303f5815c4533124acf9d18940e77522ac5dc4b9570aae8f47b7f57fd8767bea1a24ae7bed65b4afdc8f1278c30e2db98fd172730a
-  zkproof:       c6bbed4f1127cd32b04a95b205526cfcb4c4e1cc955175b3e8de1f5d81b18669692350aaa1a1d797617582e54d7a5b57a683b32fb1098062dad7b0c2eb518f6862e83db25e3dbaf7aed504de932acb99d735992ce62bae9ef893ff6acc0ffcf8e3483e146b9d49dd8c7835f43a37dca0787e3ec9f6605223d5ba7ae0ab9025b73bc03f7fac36c009a56d4d95d1e81d3b3ebca7e54cc1a12d127b57c8138976e791013b015f06a624f521b6ee04ec980893c7e5e01a336203594094f82833d744
-
-  cv:            27880084d35863c8e7ebb5c9eed98e72572ec40c79b26623b58022f489b0893d
-  cmu:           88be63f3f8c0d23249ebcde13db9312941c36c1d1cbcabac0c78cb3b1912db0d
-  ephemeralKey:  cbfe1893d9b51be4af1d000bac1ad0a3ae2ce1e73225fb114d05af4cefc06e87
-  encCiphertext: 5f074ffeae0cba7da3a516c173be1c513323e119f635e8209a074b216b7023fadc2d25949c90037e71e3e550726d210a2c688342e52440635e9cc14afe10102621a9c9accb782e9e4a5fa87f0a956f5b85509960285c22627c59483a5a4c28cce4b156e551406a7ee8355656a21e43e38ce129fdadb759eddfa08f00fc8e567cef93c6792d01df05e6d580f4d5d48df042451a33590d3e8cf49b2627218f0c292fa66ada945fa55bb23548e33a83a562957a3149a993cc472362298736a8b778d97ce423013d64b32cd172efa551bf7f368f04bdaec6091a3004a757598b801dcf675cb83e43a53ae8b254d333bcda20d4817d3477abfba25bb83df5949c126f149b1d99341e4e6f9120f4d41e629185002c72c012c414d2382a6d47c7b3deaba770c400ca96b2814f6b26c3ef17429f1a98c85d83db20efad48be8996fb1bff591efff360fe1199056c56e5feec61a7b8b9f699d6012c2849232f329fef95c7af370098ffe4918e0ca1df47f275867b739e0a514d3209325e217045927b479c1ce2e5d54f25488cad1513e3f44a21266cfd841633327dee6cf810fbf7393e317d9e53d1be1d5ae7839b66b943b9ed18f2c530e975422332c3439cce49a29f2a336a4851263c5e9bd13d731109e844b7f8c392a5c1dcaa2ae5f50ff63fab9765e016702c35a67cd7364d3fab552fb349e35c15c50250453fd18f7b855992632e2c76c0fbf1ef963ea80e3223de3277bc559251725829ec03f213ba8955cab2822ff21a9b0a4904d668fcd77224bde3dd01f6ffc4828f6b64230b35c6a049873494276ea1
-  outCiphertext: d7ed5e92cb4f90ba83a9e49601b194042f2900d99d312d7b70508cf176066d154dbe96ef9d4367e4c840e4a17b5e5122e8ebe2158a3c5f4cbae21ea3fa1ae6c25a9462ebcbb0fd5f14554bc97747c33e
-  zkproof:       34da90c816d8d0d50bfe37618c5812891484fa259322c15092d4155d8696d6f12f24fd364496b3be0871ca3dd9625348a614b59bde45885649bae36de34def8fcec85343475d976ae1e9b27829ce2ac5efd0b399a8b448be6504294ee6b3c1c6a5342d7c01ae9d8ad3070c2b1a91573af5e0c5e4cbbf4acdc6b54c9272200d9970250c17c1036f06085c41858ed3a0c48150bc697e4a695fef335f7ad07e1a46dc767ff822db70e6669080b9816b2232c81a4c66cc586abfe1eaa8ca6cf41fc3
-
-  cv:            0eb8dc57c37a3c39c59c94232df9d388dbfa35c2cd5c75f328e9fea78f65568f
-  cmu:           2bb934c82c4142da69d12ca7de9a7df706400ec79878d868e17e8f71ea31495a
-  ephemeralKey:  8bae7bdc2e48b5118771c2fca078cca1fce0d7ef0af3478cf36f69e85a41dd29
-  encCiphertext: b4294a65d3e055ff718dd9dc8c75e7e5b2efe442637371b7c48f6ee99e3ea38a4b0f2f67fc2b908cda657eae754e037e262e9a9f9bd7ec4267ed8e96930e1084783c37d6f9dd15fd29f4cc477e66f130d630430dcc0104899b4f9f46eb090ef7fc90b479abf61f93955ee00e6a1848f1ab14ad334f2b68035808cdf1bb9e9d9a816baf728a955b960b7701fa626687dc3c9cba646337b53e29816e9482ddf5578a8768aae477fce410ac2d5de6095861c111d7feb3e6bb4fbb5a54955495972798350a253f05f66c2ecfcbc0ed43f5ec2e6d8dba15a51254d97b1821107c07dd9a16ef8406f943e282b95d4b362530c913d6ba421df6027de5af1e4745d5868106954be6c1962780a2941072e95131b1679df0637625042c37d48ffb152e5ebc185c8a2b7d4385f1c95af937df78dfd8757fab434968b0b57c66574468f160b447ac8221e5060676a842a1c6b7172dd3340f764070ab1fe091c5c74c95a5dc043390723a4c127da14cdde1dc2675a62340b3e6afd0522a31de26e7d1ec3a9c8a091ffdc75b7ecfdc7c12995a5e37ce3488bd29f8629d68f696492448dd526697476dc061346ebe3f677217ff9c60efce943af28dfd3f9e59692598a6047c23c4c01400f1ab5730eac0ae8d5843d5051c376240172af218d7a1ecfe65b4f75100638983c14de4974755dade8018c9b8f4543fb095961513e67c61dbc59c607f9b51f8d09bdcad28bcfb9e5d2744ea8848b2623ac07f8ef61a81a35910b8a1baf39a919a7b60bc604d63185f759221d847cc54a22765a4c33475b5791e9af3271fc8d93506
-  outCiphertext: 67090d8184ec50522d804f23c4fb44ffa481bc92ae408d1b9f2b131904f9705c59e2f4bde7a3b2c085d93fd2abc5e14d163001a12f51938d021afa92239b873dc6c357eaa8af4ee6d00540657fe32914
-  zkproof:       103b5d98f68bd3e2b5359f08ccd88d0c811e4c31fbb49f3a90bbd05dce62f344e7077593159ae35050b04c9e6b86bc432dc8b048c73c0018ca5b69411297732a4e1aa99a928c71e7a24fd277856aa42501e51b012aea9446a2104e93f815a0b3a29b458314f3d8be2b9823d342f46213e942a7e19a46e970b5c506708430317b1bb3b35df68ae33a4926a03e6bfeb5510416fcbb0524c9ca5074156cc5a5d6fe1c995edc60a2f550411aa41e3da3bdcf64bcf04a0510571b936d47e55cec0330
-
-vJoinSplit:      00
-bindingSig:      8dfe73563404f047d7f3a8a3d7743bc554955210f1eb0d08599ea77d5f974d87176d37d98b9c0ad440407209ed6a9f08464d565593e1a63b938536b49244e97d
-

Transaction digest with nIn = 0 and nHashType = 2 (SIGHASH_NONE):

-
hashPrevouts:
-  BLAKE2b-256('ZcashPrevoutHash', 0bbe32a598c22adfb48cef72ba5d4287c0cefbacfd8ce195b4963c34a94bba7a175dae4b090f47a068e227433f9e49d3aa09e356d8d66d0c0121e91a3c4aa3f27fa1b63396e2b41d)
-= cacf0f5210cce5fa65a59f314292b3111d299e7d9d582753cf61e1e408552ae4
-
-hashShieldedOutputs:
-  BLAKE2b-256(b'ZcashSOutputHash', 53e3b8a71face1c9f37745ed36883529304bfd5a390b37bc5a3445241f03f64a818820dfeddd75375159fbd21eca9872104f8d7b3c8c869703a1e7848a5c941e45a9c7943446d0dc9627cb31f80e7aa596d4821dc99a7d777cd57e194842a023471f0f6288a150647b2afe9df7cccf01f5cde5f04680bbfed87f6cf429fb27ad6babe791766611cf5bc20e48bef119259b9b8a0e39c3df28cb9582ea338601cdc481b32fb82adeebb3dade25d1a3df20c37e712506b5d996c49a9f0f30ddcb91fe9004e1e83294a6c9203d94e8dc2cbb449de4155032604e47997016b304fd437d8235045e255a19b743a0a9f2e336b44cae307bb3987bd3e4e777fbb34c0ab8cc3d67466c0a88dd4ccad18a07a8d1068df5b629e5718d0f6df5c957cf71bb00a5178f175caca944e635c5159f738e2402a2d21aa081e10e456afb00b9f62416c8b9c0f7228f510729e0be3f305313d77f7379dc2af24869c6c74ee4471498861d192f0ff0f508285dab6b6a36ccf7d12256cc76b95503720ac672d08268d2cf7773b6ba2a5f664847bf707f2fc10c98f2f006ec22ccb5a8c8b7c40c7c2d49a6639b9f2ce33c25c04bc461e744dfa536b00d94baddf4f4d14044c695a33881477df124f0fcf206a9fb2e65e304cdbf0c4d2390170c130ab849c2f22b5cdd3921640c8cf1976ae1010b0dfd9cb2543e45f99749cc4d61f2e8aabfe98bd905fa39951b33ea769c45ab9531c57209862ad12fd76ba4807e65417b6cd12fa8ec916f013ebb8706a96effeda06c4be24b04846392e9d1e6930eae01fa21fbd700583fb598b92c8f4eb8a61aa6235db60f2841cf3a1c6ab54c67066844711d091eb931a1bd6281aedf2a0e8fab18817202a9be06402ed9cc720c16bfe881e4df4255e87afb7fc62f38116bbe03cd8a3cb11a27d568414782f47b1a44c97c680467694bc9709d32916c97e8006cbb07ba0e4180a3738038c374c4cce8f32959afb25f303f5815c4533124acf9d18940e77522ac5dc4b9570aae8f47b7f57fd8767bea1a24ae7bed65b4afdc8f1278c30e2db98fd172730ac6bbed4f1127cd32b04a95b205526cfcb4c4e1cc955175b3e8de1f5d81b18669692350aaa1a1d797617582e54d7a5b57a683b32fb1098062dad7b0c2eb518f6862e83db25e3dbaf7aed504de932acb99d735992ce62bae9ef893ff6acc0ffcf8e3483e146b9d49dd8c7835f43a37dca0787e3ec9f6605223d5ba7ae0ab9025b73bc03f7fac36c009a56d4d95d1e81d3b3ebca7e54cc1a12d127b57c8138976e791013b015f06a624f521b6ee04ec980893c7e5e01a336203594094f82833d74427880084d35863c8e7ebb5c9eed98e72572ec40c79b26623b58022f489b0893d88be63f3f8c0d23249ebcde13db9312941c36c1d1cbcabac0c78cb3b1912db0dcbfe1893d9b51be4af1d000bac1ad0a3ae2ce1e73225fb114d05af4cefc06e875f074ffeae0cba7da3a516c173be1c513323e119f635e8209a074b216b7023fadc2d25949c90037e71e3e550726d210a2c688342e52440635e9cc14afe10102621a9c9accb782e9e4a5fa87f0a956f5b85509960285c22627c59483a5a4c28cce4b156e551406a7ee8355656a21e43e38ce129fdadb759eddfa08f00fc8e567cef93c6792d01df05e6d580f4d5d48df042451a33590d3e8cf49b2627218f0c292fa66ada945fa55bb23548e33a83a562957a3149a993cc472362298736a8b778d97ce423013d64b32cd172efa551bf7f368f04bdaec6091a3004a757598b801dcf675cb83e43a53ae8b254d333bcda20d4817d3477abfba25bb83df5949c126f149b1d99341e4e6f9120f4d41e629185002c72c012c414d2382a6d47c7b3deaba770c400ca96b2814f6b26c3ef17429f1a98c85d83db20efad48be8996fb1bff591efff360fe1199056c56e5feec61a7b8b9f699d6012c2849232f329fef95c7af370098ffe4918e0ca1df47f275867b739e0a514d3209325e217045927b479c1ce2e5d54f25488cad1513e3f44a21266cfd841633327dee6cf810fbf7393e317d9e53d1be1d5ae7839b66b943b9ed18f2c530e975422332c3439cce49a29f2a336a4851263c5e9bd13d731109e844b7f8c392a5c1dcaa2ae5f50ff63fab9765e016702c35a67cd7364d3fab552fb349e35c15c50250453fd18f7b855992632e2c76c0fbf1ef963ea80e3223de3277bc559251725829ec03f213ba8955cab2822ff21a9b0a4904d668fcd77224bde3dd01f6ffc4828f6b64230b35c6a049873494276ea1d7ed5e92cb4f90ba83a9e49601b194042f2900d99d312d7b70508cf176066d154dbe96ef9d4367e4c840e4a17b5e5122e8ebe2158a3c5f4cbae21ea3fa1ae6c25a9462ebcbb0fd5f14554bc97747c33e34da90c816d8d0d50bfe37618c5812891484fa259322c15092d4155d8696d6f12f24fd364496b3be0871ca3dd9625348a614b59bde45885649bae36de34def8fcec85343475d976ae1e9b27829ce2ac5efd0b399a8b448be6504294ee6b3c1c6a5342d7c01ae9d8ad3070c2b1a91573af5e0c5e4cbbf4acdc6b54c9272200d9970250c17c1036f06085c41858ed3a0c48150bc697e4a695fef335f7ad07e1a46dc767ff822db70e6669080b9816b2232c81a4c66cc586abfe1eaa8ca6cf41fc30eb8dc57c37a3c39c59c94232df9d388dbfa35c2cd5c75f328e9fea78f65568f2bb934c82c4142da69d12ca7de9a7df706400ec79878d868e17e8f71ea31495a8bae7bdc2e48b5118771c2fca078cca1fce0d7ef0af3478cf36f69e85a41dd29b4294a65d3e055ff718dd9dc8c75e7e5b2efe442637371b7c48f6ee99e3ea38a4b0f2f67fc2b908cda657eae754e037e262e9a9f9bd7ec4267ed8e96930e1084783c37d6f9dd15fd29f4cc477e66f130d630430dcc0104899b4f9f46eb090ef7fc90b479abf61f93955ee00e6a1848f1ab14ad334f2b68035808cdf1bb9e9d9a816baf728a955b960b7701fa626687dc3c9cba646337b53e29816e9482ddf5578a8768aae477fce410ac2d5de6095861c111d7feb3e6bb4fbb5a54955495972798350a253f05f66c2ecfcbc0ed43f5ec2e6d8dba15a51254d97b1821107c07dd9a16ef8406f943e282b95d4b362530c913d6ba421df6027de5af1e4745d5868106954be6c1962780a2941072e95131b1679df0637625042c37d48ffb152e5ebc185c8a2b7d4385f1c95af937df78dfd8757fab434968b0b57c66574468f160b447ac8221e5060676a842a1c6b7172dd3340f764070ab1fe091c5c74c95a5dc043390723a4c127da14cdde1dc2675a62340b3e6afd0522a31de26e7d1ec3a9c8a091ffdc75b7ecfdc7c12995a5e37ce3488bd29f8629d68f696492448dd526697476dc061346ebe3f677217ff9c60efce943af28dfd3f9e59692598a6047c23c4c01400f1ab5730eac0ae8d5843d5051c376240172af218d7a1ecfe65b4f75100638983c14de4974755dade8018c9b8f4543fb095961513e67c61dbc59c607f9b51f8d09bdcad28bcfb9e5d2744ea8848b2623ac07f8ef61a81a35910b8a1baf39a919a7b60bc604d63185f759221d847cc54a22765a4c33475b5791e9af3271fc8d9350667090d8184ec50522d804f23c4fb44ffa481bc92ae408d1b9f2b131904f9705c59e2f4bde7a3b2c085d93fd2abc5e14d163001a12f51938d021afa92239b873dc6c357eaa8af4ee6d00540657fe32914103b5d98f68bd3e2b5359f08ccd88d0c811e4c31fbb49f3a90bbd05dce62f344e7077593159ae35050b04c9e6b86bc432dc8b048c73c0018ca5b69411297732a4e1aa99a928c71e7a24fd277856aa42501e51b012aea9446a2104e93f815a0b3a29b458314f3d8be2b9823d342f46213e942a7e19a46e970b5c506708430317b1bb3b35df68ae33a4926a03e6bfeb5510416fcbb0524c9ca5074156cc5a5d6fe1c995edc60a2f550411aa41e3da3bdcf64bcf04a0510571b936d47e55cec0330)
-= b79530fcec83211d21e3c355db538c138d625784c27370e9d1039a8515a23f87
-
-Preimage:
-0400008085202f89cacf0f5210cce5fa65a59f314292b3111d299e7d9d582753cf61e1e408552ae40000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000b79530fcec83211d21e3c355db538c138d625784c27370e9d1039a8515a23f87d7034302011b9a076620edc067ff020002000000090f47a068e227433f9e49d3aa09e356d8d66d0c0121e91a3c4aa3f27fa1b63396e2b41d00adedf029965102004e970568
-
-  header:              04000080
-  nVersionGroupId:     85202f89
-  hashPrevouts:        cacf0f5210cce5fa65a59f314292b3111d299e7d9d582753cf61e1e408552ae4
-  hashSequence:        0000000000000000000000000000000000000000000000000000000000000000
-  hashOutputs:         0000000000000000000000000000000000000000000000000000000000000000
-  hashJoinSplits:      0000000000000000000000000000000000000000000000000000000000000000
-  hashShieldedSpends:  0000000000000000000000000000000000000000000000000000000000000000
-  hashShieldedOutputs: b79530fcec83211d21e3c355db538c138d625784c27370e9d1039a8515a23f87
-  nLockTime:           d7034302
-  nExpiryHeight:       011b9a07
-  valueBalance:        6620edc067ff0200
-  nHashType:           02000000
-
-  Input:
-    prevout:    090f47a068e227433f9e49d3aa09e356d8d66d0c0121e91a3c4aa3f27fa1b633 96e2b41d
-    scriptCode: 00
-    amount:     adedf02996510200
-    nSequence:  4e970568
-
-sighash: bbe6d84f57c56b29b914c694baaccb891297e961de3eb46c68e3c89c47b1a1db
-
-

Test vector 3

-

Testnet transaction with txid 97d8814886d07fc12bbac90c089a10f90906cbb53402ee26e576ef99276c492d sends only transparent funds.

-

Raw transaction:

-
0400008085202f8901a8c685478265f4c14dada651969c45a65e1aeb8cd6791f2f5bb6a1d9952104d9010000006b483045022100a61e5d557568c2ddc1d9b03a7173c6ce7c996c4daecab007ac8f34bee01e6b9702204d38fdc0bcf2728a69fde78462a10fb45a9baa27873e6a5fc45fb5c76764202a01210365ffea3efa3908918a8b8627724af852fc9b86d7375b103ab0543cf418bcaa7ffeffffff02005a6202000000001976a9148132712c3ff19f3a151234616777420a6d7ef22688ac8b959800000000001976a9145453e4698f02a38abdaa521cd1ff2dee6fac187188ac29b0040048b004000000000000000000000000
-
-header:          04000080
-nVersionGroupId: 85202f89
-vin:             01 a8c685478265f4c14dada651969c45a65e1aeb8cd6791f2f5bb6a1d9952104d9 01000000 6b483045022100a61e5d557568c2ddc1d9b03a7173c6ce7c996c4daecab007ac8f34bee01e6b9702204d38fdc0bcf2728a69fde78462a10fb45a9baa27873e6a5fc45fb5c76764202a01210365ffea3efa3908918a8b8627724af852fc9b86d7375b103ab0543cf418bcaa7f feffffff
-vout:            02 005a620200000000 1976a9148132712c3ff19f3a151234616777420a6d7ef22688ac
-                    8b95980000000000 1976a9145453e4698f02a38abdaa521cd1ff2dee6fac187188ac
-nLockTime:       29b00400
-nExpiryHeight:   48b00400
-valueBalance:    0000000000000000
-vShieldedSpend:  00
-vShieldedOutput: 00
-vJoinSplit:      00
-

Transaction digest with nIn = 0 and nHashType = 1 (SIGHASH_ALL):

-
Preimage:
-0400008085202f89fae31b8dec7b0b77e2c8d6b6eb0e7e4e55abc6574c26dd44464d9408a8e33f116c80d37f12d89b6f17ff198723e7db1247c4811d1a695d74d930f99e98418790d2b04118469b7810a0d1cc59568320aad25a84f407ecac40b4f605a4e686845400000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000029b0040048b00400000000000000000001000000a8c685478265f4c14dada651969c45a65e1aeb8cd6791f2f5bb6a1d9952104d9010000001976a914507173527b4c3318a2aecd793bf1cfed705950cf88ac80f0fa0200000000feffffff
-
-  header:              04000080
-  nVersionGroupId:     85202f89
-  hashPrevouts:        fae31b8dec7b0b77e2c8d6b6eb0e7e4e55abc6574c26dd44464d9408a8e33f11
-  hashSequence:        6c80d37f12d89b6f17ff198723e7db1247c4811d1a695d74d930f99e98418790
-  hashOutputs:         d2b04118469b7810a0d1cc59568320aad25a84f407ecac40b4f605a4e6868454
-  hashJoinSplits:      0000000000000000000000000000000000000000000000000000000000000000
-  hashShieldedSpends:  0000000000000000000000000000000000000000000000000000000000000000
-  hashShieldedOutputs: 0000000000000000000000000000000000000000000000000000000000000000
-  nLockTime:           29b00400
-  nExpiryHeight:       48b00400
-  valueBalance:        0000000000000000
-  nHashType:           01000000
-
-  Input:
-    prevout:    a8c685478265f4c14dada651969c45a65e1aeb8cd6791f2f5bb6a1d9952104d9 01000000
-    scriptCode: 1976a914507173527b4c3318a2aecd793bf1cfed705950cf88ac
-    amount:     80f0fa0200000000
-    nSequence:  feffffff
-
-  sighash: f3148f80dfab5e573d5edfe7a850f5fd39234f80b5429d3a57edcc11e34c585b
-
-
-

Deployment

-

This proposal is deployed with the Sapling network upgrade. 6

-
-

Backward compatibility

-

This proposal is backwards-compatible with old UTXOs. It is not backwards-compatible with older software. Given that v3 transaction formats will be invalid from the Sapling upgrade, all transactions will be required to use this transaction digest algorithm for signatures, and so transactions created by older software will be rejected by the network.

-
-

Reference Implementation

-

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

-
-

References

- - - - - - - -
1Information 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"
- - - - - - - -
2Zcash Protocol Specification, version 2021.2.16 or later
- - - - - - - -
3"BLAKE2: simpler, smaller, fast as MD5", Section 2.8
- - - - - - - -
4ZIP 143: Transaction Signature Validation for Overwinter
- - - - - - - -
5ZIP 200: Network Upgrade Mechanism
- - - - - - - -
6ZIP 205: Deployment of the Sapling Network Upgrade
- - - - - - - -
7ZIP 243 Test Vectors
- - - - - - - -
8SignatureHash Test Vectors
-
-
- - \ No newline at end of file diff --git a/rendered/zip-0244.html b/rendered/zip-0244.html deleted file mode 100644 index 8f73e4511..000000000 --- a/rendered/zip-0244.html +++ /dev/null @@ -1,554 +0,0 @@ - - - - ZIP 244: Transaction Identifier Non-Malleability - - - - -
-
ZIP: 244
-Title: Transaction Identifier Non-Malleability
-Owners: Kris Nuttycombe <kris@electriccoin.co>
-        Daira-Emma Hopwood <daira-emma@electriccoin.co>
-        Jack Grigg <str4d@electriccoin.co>
-Status: Final
-Category: Consensus
-Created: 2021-01-06
-License: MIT
-Discussions-To: <https://github.com/zcash/zips/issues/411>
-

Terminology

-

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

-

The terms "consensus branch", "epoch", and "network upgrade" in this document are to be interpreted as described in ZIP 200. 3

-

The term "field encoding" refers to the binary serialized form of a Zcash transaction field, as specified in section 7.1 of the Zcash protocol specification 2.

-
-

Abstract

-

This proposal defines a new transaction digest algorithm for the NU5 network upgrade onward, in order to introduce non-malleable transaction identifiers that commit to all transaction data except for attestations to transaction validity.

-

This proposal also defines a new transaction digest algorithm for signature validation, which shares all available structure produced during the construction of transaction identifiers, in order to minimize redundant data hashing in validation.

-

This proposal also defines a new name and semantics for the hashLightClientRoot field of the block header, to enable additional commitments to be represented in this hash and to provide a mechanism for future extensibility of the set of commitments represented.

-
-

Motivation

-

In all cases, but particularly in order to support the use of transactions in higher-level protocols, any modification of the transaction that has not been explicitly permitted (such as via anyone-can-spend inputs) should invalidate attestations to spend authority or to the included outputs. Following the activation of this proposed change, transaction identifiers will be stable irrespective of any possible malleation of "witness data" such as proofs and transaction signatures.

-

In addition, by specifying a transaction identifier and signature algorithm that is decoupled from the serialized format of the transaction as a whole, this change makes it so that the wire format of transactions is no longer consensus-critical.

-
-

Requirements

-
    -
  • Continue to support existing functionality of the protocol (multisig, signing modes for transparent inputs).
  • -
  • Allow the use of transaction ids, and pairs of the form (transaction id, output index) as stable identifiers.
  • -
  • A sender must be able to recognize their own transaction, even given allowed forms of malleability such as recomputation of transaction signatures.
  • -
  • In the case of transparent inputs, it should be possible to create a transaction (B) that spends the outputs from a previous transaction (A) even before (A) has been mined. This should also be possible in the case that the creator of (B) does not wait for confirmations of (A). That is, (B) should remain valid so long as any variant of (A) is eventually mined.
  • -
  • It should not be possible for an attacker to malleate a transaction in a fashion that would result in the transaction being interpreted as a double-spend.
  • -
  • It should be possible in the future to upgrade the protocol in such a fashion that only non-malleable transactions are accepted.
  • -
  • It should be possible to use the transaction id unmodified as the value that is used to produce a signature hash in the case that the transaction contains no transparent inputs.
  • -
-
-

Non-requirements

-

In order to support backwards-compatibility with parts of the ecosystem that have not yet upgraded to the non-malleable transaction format, it is not an initial requirement that all transactions be non-malleable.

-

It is not required that legacy (Sapling V4 and earlier) transaction formats support construction of non-malleable transaction identifiers, even though they may continue to be accepted by the network after the NU5 upgrade.

-
-

Specification

-

Digests

-

All digests are personalized BLAKE2b-256 hashes. In cases where no elements are available for hashing (for example, if there are no transparent transaction inputs or no Orchard actions), a personalized hash of the empty byte array will be used. The personalization string therefore provides domain separation for the hashes of even empty data fields.

-

The notation BLAKE2b-256(personalization_string, []) is used to refer to hashes constructed in this manner.

-

TxId Digest

-

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

-
txid_digest
-├── header_digest
-├── transparent_digest
-│   ├── prevouts_digest
-│   ├── sequence_digest
-│   └── outputs_digest
-├── sapling_digest
-│   ├── sapling_spends_digest
-│   │   ├── sapling_spends_compact_digest
-│   │   └── sapling_spends_noncompact_digest
-│   ├── sapling_outputs_digest
-│   │   ├── sapling_outputs_compact_digest
-│   │   ├── sapling_outputs_memos_digest
-│   │   └── sapling_outputs_noncompact_digest
-│   └── valueBalance
-└── orchard_digest
-    ├── orchard_actions_compact_digest
-    ├── orchard_actions_memos_digest
-    ├── orchard_actions_noncompact_digest
-    ├── flagsOrchard
-    ├── valueBalanceOrchard
-    └── anchorOrchard
-

Each node written as snake_case in this tree is a BLAKE2b-256 hash of its children, initialized with a personalization string specific to that branch of the tree. Nodes that are not themselves digests are written in camelCase. In the specification below, nodes of the tree are presented in depth-first order.

-
txid_digest
-

A BLAKE2b-256 hash of the following values

-
T.1: header_digest       (32-byte hash output)
-T.2: transparent_digest  (32-byte hash output)
-T.3: sapling_digest      (32-byte hash output)
-T.4: orchard_digest      (32-byte hash output)
-

The personalization field of this hash is set to:

-
"ZcashTxHash_" || CONSENSUS_BRANCH_ID
-

ZcashTxHash_ has 1 underscore character.

-

As in ZIP 143 6, CONSENSUS_BRANCH_ID is the 4-byte little-endian encoding of the consensus branch ID for the epoch of the block containing the transaction. Domain separation of the transaction id hash across parallel consensus branches provides replay protection: transactions targeted for one consensus branch will not have the same transaction identifier on other consensus branches.

-

This signature hash personalization prefix has been changed to reflect the new role of this hash (relative to ZcashSigHash as specified in ZIP 143) as a transaction identifier rather than a commitment that is exclusively used for signature purposes. The previous computation of the transaction identifier was a SHA256d hash of the serialized transaction contents, and was not personalized.

-
T.1: header_digest
-

A BLAKE2b-256 hash of the following values

-
T.1a: version             (4-byte little-endian version identifier including overwinter 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)
-

The personalization field of this hash is set to:

-
"ZTxIdHeadersHash"
-
-
T.2: transparent_digest
-

In the case that transparent inputs or outputs are present, the transparent digest consists of a BLAKE2b-256 hash of the following values

-
T.2a: prevouts_digest (32-byte hash)
-T.2b: sequence_digest (32-byte hash)
-T.2c: outputs_digest  (32-byte hash)
-

The personalization field of this hash is set to:

-
"ZTxIdTranspaHash"
-

In the case that the transaction has no transparent components, transparent_digest is

-
BLAKE2b-256("ZTxIdTranspaHash", [])
-
T.2a: prevouts_digest -

A BLAKE2b-256 hash of the field encoding of all outpoint field values of transparent inputs to the transaction.

-

The personalization field of this hash is set to:

-
"ZTxIdPrevoutHash"
-

In the case that the transaction has transparent outputs but no transparent inputs, prevouts_digest is

-
BLAKE2b-256("ZTxIdPrevoutHash", [])
-
-
T.2b: sequence_digest -

A BLAKE2b-256 hash of the 32-bit little-endian representation of all nSequence field values of transparent inputs to the transaction.

-

The personalization field of this hash is set to:

-
"ZTxIdSequencHash"
-

In the case that the transaction has transparent outputs but no transparent inputs, sequence_digest is

-
BLAKE2b-256("ZTxIdSequencHash", [])
-
-
T.2c: outputs_digest -

A BLAKE2b-256 hash of the concatenated field encodings of all transparent output values of the transaction. The field encoding of such an output consists of the encoded output amount (8-byte little endian) followed by the scriptPubKey byte array (serialized as Bitcoin script).

-

The personalization field of this hash is set to:

-
"ZTxIdOutputsHash"
-

In the case that the transaction has transparent inputs but no transparent outputs, outputs_digest is

-
BLAKE2b-256("ZTxIdOutputsHash", [])
-
-
-
T.3: sapling_digest
-

In the case that Sapling spends or outputs are present, the digest of Sapling components is composed of two subtrees which are organized to permit easy interoperability with the CompactBlock representation of Sapling data specified by the ZIP 307 Light Client Protocol 8.

-

This digest is a BLAKE2b-256 hash of the following values

-
T.3a: sapling_spends_digest  (32-byte hash)
-T.3b: sapling_outputs_digest (32-byte hash)
-T.3c: valueBalance           (64-bit signed little-endian)
-

The personalization field of this hash is set to:

-
"ZTxIdSaplingHash"
-

In the case that the transaction has no Sapling spends or outputs, sapling_digest is

-
BLAKE2b-256("ZTxIdSaplingHash", [])
-
T.3a: sapling_spends_digest -

In the case that Sapling spends are present, this digest is a BLAKE2b-256 hash of the following values

-
T.3a.i:  sapling_spends_compact_digest    (32-byte hash)
-T.3a.ii: sapling_spends_noncompact_digest (32-byte hash)
-

The personalization field of this hash is set to:

-
"ZTxIdSSpendsHash"
-

In the case that the transaction has Sapling outputs but no Sapling spends, sapling_spends_digest is

-
BLAKE2b-256("ZTxIdSSpendsHash", [])
-
T.3a.i: sapling_spends_compact_digest -

A BLAKE2b-256 hash of the field encoding of all nullifier field values of Sapling shielded spends belonging to the transaction.

-

The personalization field of this hash is set to:

-
"ZTxIdSSpendCHash"
-
-
T.3a.ii: sapling_spends_noncompact_digest -

A BLAKE2b-256 hash of the non-nullifier information for all Sapling shielded spends belonging to the transaction, excluding both zkproof data and spend authorization signature(s). For each spend, the following elements are included in the hash:

-
T.3a.ii.1: cv     (field encoding bytes)
-T.3a.ii.2: anchor (field encoding bytes)
-T.3a.ii.3: rk     (field encoding bytes)
-

In Transaction version 5, Sapling Spends have a shared anchor, which is hashed into the sapling_spends_noncompact_digest for each Spend.

-

The personalization field of this hash is set to:

-
"ZTxIdSSpendNHash"
-
-
-
T.3b: sapling_outputs_digest -

In the case that Sapling outputs are present, this digest is a BLAKE2b-256 hash of the following values

-
T.3b.i:   sapling_outputs_compact_digest    (32-byte hash)
-T.3b.ii:  sapling_outputs_memos_digest      (32-byte hash)
-T.3b.iii: sapling_outputs_noncompact_digest (32-byte hash)
-

The personalization field of this hash is set to:

-
"ZTxIdSOutputHash"
-

In the case that the transaction has Sapling spends but no Sapling outputs, sapling_outputs_digest is

-
BLAKE2b-256("ZTxIdSOutputHash", [])
-
T.3b.i: sapling_outputs_compact_digest -

A BLAKE2b-256 hash of the subset of Sapling output information included in the ZIP-307 8 CompactBlock format for all Sapling shielded outputs belonging to the transaction. For each output, the following elements are included in the hash:

-
T.3b.i.1: cmu                  (field encoding bytes)
-T.3b.i.2: ephemeral_key        (field encoding bytes)
-T.3b.i.3: enc_ciphertext[..52] (First 52 bytes of field encoding)
-

The personalization field of this hash is set to:

-
"ZTxIdSOutC__Hash" (2 underscore characters)
-
-
T.3b.ii: sapling_outputs_memos_digest -

A BLAKE2b-256 hash of the subset of Sapling shielded memo field data for all Sapling shielded outputs belonging to the transaction. For each output, the following elements are included in the hash:

-
T.3b.ii.1: enc_ciphertext[52..564] (contents of the encrypted memo field)
-

The personalization field of this hash is set to:

-
"ZTxIdSOutM__Hash" (2 underscore characters)
-
-
T.3b.iii: sapling_outputs_noncompact_digest -

A BLAKE2b-256 hash of the remaining subset of Sapling output information not included in the ZIP 307 8 CompactBlock format, excluding zkproof data, for all Sapling shielded outputs belonging to the transaction. For each output, the following elements are included in the hash:

-
T.3b.iii.1: cv                    (field encoding bytes)
-T.3b.iii.2: enc_ciphertext[564..] (post-memo Poly1305 AEAD tag of field encoding)
-T.3b.iii.3: out_ciphertext        (field encoding bytes)
-

The personalization field of this hash is set to:

-
"ZTxIdSOutN__Hash" (2 underscore characters)
-
-
-
-
T.4: orchard_digest
-

In the case that Orchard actions are present in the transaction, this digest is a BLAKE2b-256 hash of the following values

-
T.4a: orchard_actions_compact_digest      (32-byte hash output)
-T.4b: orchard_actions_memos_digest        (32-byte hash output)
-T.4c: orchard_actions_noncompact_digest   (32-byte hash output)
-T.4d: flagsOrchard                        (1 byte)
-T.4e: valueBalanceOrchard                 (64-bit signed little-endian)
-T.4f: anchorOrchard                       (32 bytes)
-

The personalization field of this hash is set to:

-
"ZTxIdOrchardHash"
-

In the case that the transaction has no Orchard actions, orchard_digest is

-
BLAKE2b-256("ZTxIdOrchardHash", [])
-
T.4a: orchard_actions_compact_digest -

A BLAKE2b-256 hash of the subset of Orchard Action information intended to be included in an updated version of the ZIP-307 8 CompactBlock format for all Orchard Actions belonging to the transaction. For each Action, the following elements are included in the hash:

-
T.4a.i  : nullifier            (field encoding bytes)
-T.4a.ii : cmx                  (field encoding bytes)
-T.4a.iii: ephemeralKey         (field encoding bytes)
-T.4a.iv : encCiphertext[..52]  (First 52 bytes of field encoding)
-

The personalization field of this hash is set to:

-
"ZTxIdOrcActCHash"
-
-
T.4b: orchard_actions_memos_digest -

A BLAKE2b-256 hash of the subset of Orchard shielded memo field data for all Orchard Actions belonging to the transaction. For each Action, the following elements are included in the hash:

-
T.4b.i: encCiphertext[52..564] (contents of the encrypted memo field)
-

The personalization field of this hash is set to:

-
"ZTxIdOrcActMHash"
-
-
T.4c: orchard_actions_noncompact_digest -

A BLAKE2b-256 hash of the remaining subset of Orchard Action information not intended for inclusion in an updated version of the the ZIP 307 8 CompactBlock format, for all Orchard Actions belonging to the transaction. For each Action, the following elements are included in the hash:

-
T.4c.i  : cv                    (field encoding bytes)
-T.4c.ii : rk                    (field encoding bytes)
-T.4c.iii: encCiphertext[564..]  (post-memo suffix of field encoding)
-T.4c.iv : outCiphertext         (field encoding bytes)
-

The personalization field of this hash is set to:

-
"ZTxIdOrcActNHash"
-
-
-
-
-

Signature Digest

-

A new per-input transaction digest algorithm is defined that constructs a hash that may be signed by a transaction creator to commit to the effects of the transaction. A signature digest is produced for each transparent input, each Sapling input, and each Orchard action. For transparent inputs, this follows closely the algorithms from ZIP 143 6 and ZIP 243 7. For shielded inputs, 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; each name referenced here will be described in detail below:

-
signature_digest
-├── header_digest
-├── transparent_sig_digest
-├── sapling_digest
-└── orchard_digest
-
signature_digest
-

A BLAKE2b-256 hash of the following values

-
S.1: header_digest          (32-byte hash output)
-S.2: transparent_sig_digest (32-byte hash output)
-S.3: sapling_digest         (32-byte hash output)
-S.4: orchard_digest         (32-byte hash output)
-

The personalization field of this hash is set to:

-
"ZcashTxHash_" || CONSENSUS_BRANCH_ID
-

ZcashTxHash_ has 1 underscore character.

-

This value has the same personalization as the top hash of the transaction identifier digest tree, so that what is being signed in the case that there are no transparent inputs is just the transaction id.

-
S.1: header_digest
-

Identical to that specified for the transaction identifier.

-
-
S.2: transparent_sig_digest
-

If we are producing a hash for either a coinbase transaction, or a non-coinbase transaction that has no transparent inputs, the value of transparent_sig_digest is identical to the value specified in section T.2.

-

If we are producing a hash for a non-coinbase transaction that has transparent inputs, the value of transparent_sig_digest depends upon the value of a hash_type flag, as follows.

-

The construction of each component below depends upon the values of the hash_type flag bits. Each component will be described separately.

-

This digest is a BLAKE2b-256 hash of the following values

-
S.2a: hash_type                (1 byte)
-S.2b: prevouts_sig_digest      (32-byte hash)
-S.2c: amounts_sig_digest       (32-byte hash)
-S.2d: scriptpubkeys_sig_digest (32-byte hash)
-S.2e: sequence_sig_digest      (32-byte hash)
-S.2f: outputs_sig_digest       (32-byte hash)
-S.2g: txin_sig_digest          (32-byte hash)
-

The personalization field of this hash is set to:

-
"ZTxIdTranspaHash"
-
S.2a: hash_type -

This is an 8-bit unsigned value. The SIGHASH encodings from the legacy script system are reused: one of SIGHASH_ALL (0x01), SIGHASH_NONE (0x02), and SIGHASH_SINGLE (0x03), with or without the SIGHASH_ANYONECANPAY flag (0x80). The following restrictions apply, which cause validation failure if violated:

-
    -
  • Using any undefined hash_type (not 0x01, 0x02, 0x03, 0x81, 0x82, or 0x83).
  • -
  • Using SIGHASH_SINGLE without a "corresponding output" (an output with the same index as the input being verified).
  • -
-

If we are producing a hash for the signature over a transparent input, the value of hash_type is obtained from the input's scriptSig as encoded in the transaction. If we are producing a hash for the signature over a Sapling Spend or an Orchard Action, hash_type is set to SIGHASH_ALL.

-
-
S.2b: prevouts_sig_digest -

This is a BLAKE2b-256 hash initialized with the personalization field value ZTxIdPrevoutHash.

-

If the SIGHASH_ANYONECANPAY flag is not set:

-
identical to the value of ``prevouts_digest`` as specified for the
-transaction identifier in section T.2a.
-

otherwise:

-
BLAKE2b-256(``ZTxIdPrevoutHash``, [])
-
-
S.2c: amounts_sig_digest -

If the SIGHASH_ANYONECANPAY flag is not set, the value of amounts_sig_digest is a BLAKE2b-256 hash of the concatenation of the 8-byte signed little-endian representations of all value fields 14 for the coins spent by the transparent inputs to the transaction.

-

The personalization field of this hash is set to:

-
"ZTxTrAmountsHash"
-

If the SIGHASH_ANYONECANPAY flag is set, amounts_sig_digest is:

-
BLAKE2b-256("ZTxTrAmountsHash", [])
-
-
S.2d: scriptpubkeys_sig_digest -

If the SIGHASH_ANYONECANPAY flag is not set, the value of scriptpubkeys_sig_digest is a BLAKE2b-256 hash of the concatenation of the field encodings (each including a leading CompactSize) of all pk_script fields 14 for the coins spent by the transparent inputs to the transaction.

-

The personalization field of this hash is set to:

-
"ZTxTrScriptsHash"
-

If the SIGHASH_ANYONECANPAY flag is set, scriptpubkeys_sig_digest is:

-
BLAKE2b-256("ZTxTrScriptsHash", [])
-
-
S.2e: sequence_sig_digest -

This is a BLAKE2b-256 hash initialized with the personalization field value ZTxIdSequencHash.

-

If the SIGHASH_ANYONECANPAY flag is not set:

-
identical to the value of ``sequence_digest`` as specified for the
-transaction identifier in section T.2b.
-

otherwise:

-
BLAKE2b-256(``ZTxIdSequencHash``, [])
-
-
S.2f: outputs_sig_digest -

This is a BLAKE2b-256 hash initialized with the personalization field value ZTxIdOutputsHash.

-

If the sighash type is neither SIGHASH_SINGLE nor SIGHASH_NONE:

-
identical to the value of ``outputs_digest`` as specified for the
-transaction identifier in section T.2c.
-

If the sighash type is SIGHASH_SINGLE and the signature hash is being computed for the transparent input at a particular index, and a transparent output appears in the transaction at that index:

-
the hash is over the transaction serialized form of the transparent output at that
-index
-

otherwise:

-
BLAKE2b-256(``ZTxIdOutputsHash``, [])
-
-
S.2g: txin_sig_digest -

If we are producing a hash for the signature over a transparent input, the value of txin_sig_digest is a BLAKE2b-256 hash of the following properties of the transparent input being signed, initialized with the personalization field value Zcash___TxInHash (3 underscores):

-
S.2g.i:   prevout      (field encoding)
-S.2g.ii:  value        (8-byte signed little-endian)
-S.2g.iii: scriptPubKey (field encoding)
-S.2g.iv:  nSequence    (4-byte unsigned little-endian)
-

Notes:

-
    -
  • value is defined in the consensus rules to be a nonnegative value <= MAX_MONEY, but all existing implementations parse this value as signed and enforce the nonnegative constraint as a consensus check. It is defined as signed here for consistency with those existing implementations.
  • -
  • scriptPubKey is the field encoding (including a leading CompactSize) of the pk_script field 14 for the coin spent by the transparent input. For P2SH coins, this differs from the redeemScript committed to in ZIP 243 7.
  • -
-

If we are producing a hash for the signature over a Sapling Spend or an Orchard Action, txin_sig_digest is:

-
BLAKE2b-256("Zcash___TxInHash", [])
-
-
-
S.3: sapling_digest
-

Identical to that specified for the transaction identifier.

-
-
S.4: orchard_digest
-

Identical to that specified for the transaction identifier.

-
-
-
-

Authorizing Data Commitment

-

A new transaction digest algorithm is defined that constructs a digest which commits to the authorizing data of a transaction from a tree of BLAKE2b-256 hashes. For v5 transactions, the overall structure of the hash is as follows:

-
auth_digest
-├── transparent_scripts_digest
-├── sapling_auth_digest
-└── orchard_auth_digest
-

Each node written as snake_case in this tree is a BLAKE2b-256 hash of authorizing data of the transaction.

-

For transaction versions before v5, a placeholder value consisting of 32 bytes of 0xFF is used in place of the authorizing data commitment. This is only used in the tree committed to by hashAuthDataRoot, as defined in Block Header Changes.

-

The pair (Transaction Identifier, Auth Commitment) constitutes a commitment to all the data of a serialized transaction that may be included in a block.

-
auth_digest
-

A BLAKE2b-256 hash of the following values

-
A.1: transparent_scripts_digest (32-byte hash output)
-A.2: sapling_auth_digest        (32-byte hash output)
-A.3: orchard_auth_digest        (32-byte hash output)
-

The personalization field of this hash is set to:

-
"ZTxAuthHash_" || CONSENSUS_BRANCH_ID
-

ZTxAuthHash_ has 1 underscore character.

-
A.1: transparent_scripts_digest
-

In the case that the transaction contains transparent inputs, this is a BLAKE2b-256 hash of the field encoding of the concatenated values of the Bitcoin script values associated with each transparent input belonging to the transaction.

-

The personalization field of this hash is set to:

-
"ZTxAuthTransHash"
-

In the case that the transaction has no transparent inputs, transparent_scripts_digest is

-
BLAKE2b-256("ZTxAuthTransHash", [])
-
-
A.2: sapling_auth_digest
-

In the case that Sapling Spends or Sapling Outputs are present, this is a BLAKE2b-256 hash of the field encoding of the Sapling zkproof value of each Sapling Spend Description, followed by the field encoding of the spend_auth_sig value of each Sapling Spend Description belonging to the transaction, followed by the field encoding of the zkproof field of each Sapling Output Description belonging to the transaction, followed by the field encoding of the binding signature:

-
A.2a: spend_zkproofs           (field encoding bytes)
-A.2b: spend_auth_sigs          (field encoding bytes)
-A.2c: output_zkproofs          (field encoding bytes)
-A.2d: binding_sig              (field encoding bytes)
-

The personalization field of this hash is set to:

-
"ZTxAuthSapliHash"
-

In the case that the transaction has no Sapling Spends or Sapling Outputs, sapling_auth_digest is

-
BLAKE2b-256("ZTxAuthSapliHash", [])
-
-
A.3: orchard_auth_digest
-

In the case that Orchard Actions are present, this is a BLAKE2b-256 hash of the field encoding of the zkProofsOrchard, spendAuthSigsOrchard, and bindingSigOrchard fields of the transaction:

-
A.3a: proofsOrchard            (field encoding bytes)
-A.3b: vSpendAuthSigsOrchard    (field encoding bytes)
-A.3c: bindingSigOrchard        (field encoding bytes)
-

The personalization field of this hash is set to:

-
"ZTxAuthOrchaHash"
-

In the case that the transaction has no Orchard Actions, orchard_auth_digest is

-
BLAKE2b-256("ZTxAuthOrchaHash", [])
-
-
-
-
-

Block Header Changes

-

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))}\) - , 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".

-

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:

-
hashLightClientRoot (as described in ZIP 221)
-hashAuthDataRoot    (as described below)
-terminator          [0u8;32]
-

This representation treats the hashBlockCommitments value as a linked list of hashes terminated by arbitrary data. In the case of protocol upgrades where additional commitments need to be included in the block header, it is possible to replace this terminator with the hash of a newly defined structure which ends in a similar terminator. Fully validating nodes MUST always use the entire structure defined by the latest activated protocol version that they support.

-

The linked structure of this hash is intended to provide extensibility for use by light clients which may be connected to a third-party server that supports a later protocol version. Such a third party SHOULD provide a value that can be used instead of the all-zeros terminator to permit the light client to perform validation of the parts of the structure it needs.

-

Unlike the hashLightClientRoot change, the change to hashBlockCommitments happens in the block that activates this ZIP.

-

The block header byte format and version are not altered by this ZIP.

-
-
-

Rationale

-

In S.2, we use the same personalization strings for fields that have matching fields in T.2, in order to facilitate reuse of their digests. In particular, the "no transparent inputs or outputs" case of S.2 is identical to the equivalent case in T.2; thus for fully shielded transactions, signature_digest is equal to txid_digest.

-

Several changes in this ZIP (relative to ZIP 243 7) were made to align with BIP 341 9:

-
    -
  • The hash_type field is now restricted via a new consensus rule to be one of a specific set of sighash type encodings. The rationale for this change is inherited from BIP 341 10. -
      -
    • Note however that we do not define SIGHASH_DEFAULT, as it is equivalent to SIGHASH_ALL, and we prefer the encodings to be canonical.
    • -
    -
  • -
  • Two new commitments (amounts_sig_digest and scriptpubkeys_sig_digest) were added, to address difficulties in the case of a hardware wallet signing transparent inputs. scriptpubkeys_sig_digest helps the hardware wallet to determine the subset of inputs belonging to it 11. amounts_sig_digest prevents the transaction creator from lying to the hardware wallet about the transaction fee 12. Without these commitments, the hardware wallet would need to be sent every transaction containing an outpoint referenced in the transaction being signed.
  • -
  • The semantics of sequence_sig_digest were changed, to commit to nSequence even if SIGHASH_SINGLE or SIGHASH_NONE is set. The rationale for this change is inherited from BIP 341 13.
  • -
  • The semantics of outputs_sig_digest were changed, via a new consensus rule that rejects transparent inputs for which SIGHASH_SINGLE is set without a corresponding transparent output at the same index. BIP 341 does not give a rationale for this change, but without it these inputs were effectively using SIGHASH_NONE, which is silently misleading.
  • -
  • The semantics of txin_sig_digest were changed, to always commit to the scriptPubKey field of the transparent coin being spent, instead of the script actually being executed at the time signature_digest is calculated. -
      -
    • This ensures that the signature commits to the entire committed script. In Taproot, this makes it possible to prove to a hardware wallet what (unused) execution paths exist 11. Alternate execution paths don't exist for P2PKH (where the executed script is scriptPubKey) or P2SH (where scriptPubKey is fully executed prior to redeemScript).
    • -
    • For P2SH, this means we commit to the Hash160 digest of redeemScript instead of the actual script. Note that the Bitcoin P2SH design depends entirely on Hash160 being preimage-resistant, because otherwise anyone would be able to spend someone else's P2SH UTXO using a preimage. We do need to ensure that there is no collision attack; this holds because even if an adversary could find a Hash160 collision, it would only enable them to alter the input's scriptSig field. Doing so doesn't alter the effecting data of the transaction, which by definition means the transaction has the same effect under consensus (spends the same inputs and produces the same outputs).
    • -
    -
  • -
-

Signatures over Sapling Spends or Orchard Actions, in transactions containing transparent inputs, commit to the same data that the transparent inputs do, including all of the transparent input values. Without this commitment, there would be a similar difficulty for a hardware wallet in the case where it is only signing shielded inputs, when the transaction also contains transparent inputs from a malicious other party, because that party could lie about their coins' values.

-

By contrast, binding signatures for shielded coinbase transactions continue to be over the transaction ID, as for non-coinbase transactions without transparent inputs. This is necessary because coinbase transactions have a single "dummy" transparent input element that has no corresponding previous output to commit to. It is also sufficient because the data in that transparent input either is already bound elsewhere (namely the block height, placed in expiry_height from NU5 activation), or does not need to be bound to the shielded outputs (e.g. miner-identifying information).

-
-

Reference implementation

- -
-

References

- - - - - - - -
1Information 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"
- - - - - - - -
2Zcash Protocol Specification, Version 2021.2.16 [NU5 proposal]. Section 7.1: Transaction Encoding and Consensus
- - - - - - - -
3ZIP 200: Network Upgrade Mechanism
- - - - - - - -
4ZIP 221: FlyClient - Consensus Layer Changes
- - - - - - - -
5ZIP 76: Transaction Signature Validation before Overwinter
- - - - - - - -
6ZIP 143: Transaction Signature Validation for Overwinter
- - - - - - - -
7ZIP 243: Transaction Signature Validation for Sapling
- - - - - - - -
8ZIP 307: Light Client Protocol for Payment Detection
- - - - - - - -
9BIP 341: Taproot: SegWit version 1 spending rules
- - - - - - - -
10Why reject unknown hash_type values?
- - - - - - - -
11Why does the signature message commit to the scriptPubKey?
- - - - - - - -
12Why does the signature message commit to the amounts of all transaction inputs?
- - - - - - - -
13Why does the signature message commit to all input nSequence if SIGHASH_SINGLE or SIGHASH_NONE are set?
- - - - - - - -
14Bitcoin Developer Reference. TxOut: A Transaction Output
-
-
- - \ No newline at end of file diff --git a/rendered/zip-0245.html b/rendered/zip-0245.html deleted file mode 100644 index 0a44da2f6..000000000 --- a/rendered/zip-0245.html +++ /dev/null @@ -1,161 +0,0 @@ - - - - ZIP 245: Transaction Identifier Digests & Signature Validation for Transparent Zcash Extensions - - - -
-
ZIP: 245
-Title: Transaction Identifier Digests & Signature Validation for Transparent Zcash Extensions
-Owners: Kris Nuttycombe <kris@electriccoin.co>
-        Daira-Emma Hopwood <daira-emma@electriccoin.co>
-Status: Draft
-Category: Consensus
-Created: 2021-01-13
-License: MIT
-Discussions-To: <https://github.com/zcash/zips/issues/384>
-

Terminology

-

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

-

The terms "consensus branch", "epoch", and "network upgrade" in this document are to be interpreted as described in ZIP 200. 2

-
-

Abstract

-

This proposal defines changes to ZIP 244 4 transaction id and signature digest algorithms to accommodate the inclusion of transparent Zcash extensions (TZEs) as defined in ZIP 222 3.

-
-

Specification

-

TxId Digest

-

The tree of hashes defined by ZIP 244 4 is re-structured to include a new branch for TZE hashes. The tze_digest branch is the only new addition to the tree; header_digest, transparent_digest, sprout_digest, and sapling_digest are as in ZIP 244:

-
txid_digest
-├── header_digest
-├── transparent_digest
-├── tze_digest
-│   ├── tzein_digest
-│   └── tzeout_digest
-├── sprout_digest
-└── sapling_digest
-

txid_digest

-

The top hash of the txid_digest tree is modified from the ZIP 244 structure to be a BLAKE2b-256 hash of the following values

-
T.1: header_digest      (32-byte hash output)
-T.2: transparent_digest (32-byte hash output)
-T.3: tze_digest         (32-byte hash output)
-T.4: sprout_digest      (32-byte hash output)
-T.5: sapling_digest     (32-byte hash output)
-

The personalization field of this hash is unmodified from ZIP 244.

-
2: tze_digest
-

A BLAKE2b-256 hash of the following values

-
T.2a: tzein_digest  (32-byte hash)
-T.2b: tzeout_digest (32-byte hash)
-

The personalization field of this hash is set to:

-
"ZTxIdTZE____Hash" (4 underscore characters)
-
2a: tzein_digest
-

A BLAKE2b-256 hash of all TZE inputs to the transaction, excluding witness data. For each TZE input, the following values are appended to this hash:

-
2a.i:  extension_id (CompactSize field encoding)
-2a.ii: mode         (CompactSize field encoding)
-

The personalization field of this hash is set to:

-
"ZTxIdTZEIns_Hash" (1 underscore character)
-
-
2a: tzeout_digest
-

A BLAKE2b-256 hash of the field encoding of all TZE outputs belonging to the transaction.

-

The personalization field of this hash is set to:

-
"ZTxIdTzeOutsHash"
-
-
-
-
-

Signature Digest

-

The signature digest creation algorithm defined by ZIP 244 4 is modified to include a new branch for TZE hashes. The tze_digest branch is the only new addition to the tree; header_digest, transparent_digest, sprout_digest, and sapling_digest are as in ZIP 244:

-
signature_digest
-├── header_digest
-├── transparent_digest
-├── tze_digest
-│   ├── tzein_digest
-│   └── tzeout_digest
-├── sprout_digest
-└── sapling_digest
-

signature_digest

-

A BLAKE2b-256 hash of the following values

-
S.1: header_digest      (32-byte hash output)
-S.2: transparent_digest (32-byte hash output)
-S.3: tze_digest         (32-byte hash output)
-S.4: sprout_digest      (32-byte hash output)
-S.5: sapling_digest     (32-byte hash output)
-

The personalization field of this hash is set to:

-
"ZcashTxHash_" || CONSENSUS_BRANCH_ID
-

ZcashTxHash_ has 1 underscore character.

-

This value must have the same personalization as the top hash of the transaction identifier digest tree, in order to make it possible to sign the transaction id in the case that there are no transparent inputs.

-
S.3: tze_digest
-

This digest is a BLAKE2b-256 hash of the following values of the TZE input being signed:

-
S.3a: prevout_digest (field encoding bytes)
-S.3b: extension_id   (CompactSize field encoding)
-S.3c: mode           (CompactSize field encoding)
-S.3d: payload        (arbitrary bytes)
-S.3e: value          (8-byte little endian value of the output spent by this input)
-

The personalization field of this hash is set to:

-
"Zcash__TzeInHash" (2 underscore characters)
-
-
-
-

Authorizing Data Commitment

-

The tree of hashes defined by ZIP 244 4 for authorizing data commitments is re-structured to include a new branch for TZE hashes. The tze_witnesses_digest branch is the only new addition to the tree; transparent_auth_digest, sprout_auth_digest, and sapling_auth_digest are as in ZIP 244:

-
auth_digest
-├── transparent_scripts_digest
-├── tze_witnesses_digest
-├── sprout_auth_digest
-└── sapling_auth_digest
-

auth_digest

-

The top hash of the auth_digest tree is modified from the ZIP 244 structure to be a BLAKE2b-256 hash of the following values

-
A.1: transparent_scripts_digest (32-byte hash output)
-A.2: tze_witnesses_digest       (32-byte hash output)
-A.3: sprout_auth_digest         (32-byte hash output)
-A.4: sapling_auth_digest        (32-byte hash output)
-

The personalization field of this hash is unmodified from ZIP 244.

-
-

2: tze_witnesses_digest

-

A BLAKE2b-256 hash of the field encoding of the witness payload data associated with each TZE input belonging to the transaction.

-

The personalization field of this hash is set to:

-
"ZTxAuthTZE__Hash" (2 underscore characters)
-
-
-
-

Reference implementation

- -
-

References

- - - - - - - -
1Information 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"
- - - - - - - -
2ZIP 200: Network Upgrade Mechanism
- - - - - - - -
3ZIP 222: Transparent Zcash Extensions
- - - - - - - -
4ZIP 244: Transaction Identifier Non-Malleability
-
-
- - \ No newline at end of file diff --git a/rendered/zip-0250.html b/rendered/zip-0250.html deleted file mode 100644 index 0c942d7e7..000000000 --- a/rendered/zip-0250.html +++ /dev/null @@ -1,136 +0,0 @@ - - - - ZIP 250: Deployment of the Heartwood Network Upgrade - - - -
-
ZIP: 250
-Title: Deployment of the Heartwood Network Upgrade
-Owners: Daira-Emma Hopwood <daira-emma@electriccoin.co>
-Status: Final
-Category: Consensus / Network
-Created: 2020-02-28
-License: MIT
-

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. 3

-

The terms below are to be interpreted as follows:

-
-
Heartwood
-
Code-name for the fourth Zcash network upgrade, also known as Network Upgrade 3.
-
Testnet
-
The Zcash test network, as defined in 2.
-
Mainnet
-
The Zcash production network, as defined in 2.
-
-
-

Abstract

-

This proposal defines the deployment of the Heartwood network upgrade.

-
-

Specification

-

Heartwood deployment

-

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

-
    -
  • The Zcash Protocol Specification 2
  • -
  • ZIP 200: Network Upgrade Mechanism 3
  • -
  • ZIP 213: Shielded Coinbase 5
  • -
  • ZIP 221: FlyClient - Consensus-Layer Changes 6.
  • -
-

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

-

The following network upgrade constants 3 are defined for the Heartwood upgrade:

-
-
CONSENSUS_BRANCH_ID
-
0xF5B9230B
-
ACTIVATION_HEIGHT (Heartwood)
-
-

Testnet: 903800

-

Mainnet: 903000

-
-
-

Nodes compatible with Heartwood activation on testnet MUST advertise protocol version 170010 or later. Nodes compatible with Heartwood activation on mainnet MUST advertise protocol version 170011 or later. The minimum peer protocol version that Heartwood-compatible nodes will connect to is 170002.

-

Pre-Heartwood testnet nodes are defined as nodes on testnet advertising a protocol version less than 170010. Pre-Heartwood mainnet nodes are defined as nodes on mainnet advertising a protocol version less than 170011.

-

For each network (testnet and mainnet), approximately 1.5 days (defined in terms of block height) before the corresponding Heartwood activation height, nodes compatible with Heartwood activation on that network will change the behaviour of their peer connection logic in order to prefer pre-Heartwood peers on that network for eviction from the set of peer connections:

-
/**
- * The period before a network upgrade activates, where connections to upgrading peers are preferred (in blocks).
- * This was three days for upgrades up to and including Blossom, and is 1.5 days from Heartwood onward.
- */
-static const int NETWORK_UPGRADE_PEER_PREFERENCE_BLOCK_PERIOD = 1728;
-

The implementation is similar to that for Overwinter which was described in 4.

-

Once Heartwood activates on testnet or mainnet, Heartwood nodes SHOULD take steps to:

-
    -
  • reject new connections from pre-Heartwood nodes on that network;
  • -
  • disconnect any existing connections to pre-Heartwood nodes on that network.
  • -
-
-
-

Backward compatibility

-

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

-

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

-

Unlike Overwinter and Sapling, and like Blossom, Heartwood does not define a new transaction version. Heartwood transactions are therefore in the same v4 format as Sapling transactions, use the same version group ID, i.e. 0x892F2085 as defined in 2 section 7.1, and the same transaction digest algorithm as defined in 7. This does not imply that transactions are valid across the Heartwood activation, since signatures MUST use the appropriate consensus branch ID. 7

-
-

Support in zcashd

-

Support for Heartwood on testnet will be implemented in zcashd version 2.1.2, which will advertise protocol version 170010. Support for Heartwood on mainnet will be implemented in zcashd version 3.0.0, which will advertise protocol version 170011.

-
-

References

- - - - - - - -
1Information 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"
- - - - - - - -
2Zcash Protocol Specification, Version 2021.2.16 or later
- - - - - - - -
3ZIP 200: Network Upgrade Mechanism
- - - - - - - -
4ZIP 201: Network Peer Management for Overwinter
- - - - - - - -
5ZIP 213: Shielded Coinbase
- - - - - - - -
6ZIP 221: FlyClient - Consensus-Layer Changes
- - - - - - - -
7ZIP 243: Transaction Signature Validation for Sapling
-
-
- - \ No newline at end of file diff --git a/rendered/zip-0251.html b/rendered/zip-0251.html deleted file mode 100644 index be3a7505b..000000000 --- a/rendered/zip-0251.html +++ /dev/null @@ -1,181 +0,0 @@ - - - - ZIP 251: Deployment of the Canopy Network Upgrade - - - -
-
ZIP: 251
-Title: Deployment of the Canopy Network Upgrade
-Owners: Daira-Emma Hopwood <daira-emma@electriccoin.co>
-Status: Final
-Category: Consensus / Network
-Created: 2020-02-28
-License: MIT
-

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. 5

-

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

-

"Canopy" is the code-name for the fifth Zcash network upgrade, also known as Network Upgrade 4.

-
-

Abstract

-

This proposal defines the deployment of the Canopy network upgrade.

-
-

Specification

-

Canopy deployment

-

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

-
    -
  • The Zcash Protocol Specification 2
  • -
  • ZIP 200: Network Upgrade Mechanism 5
  • -
  • ZIP 207: Funding Streams 7
  • -
  • ZIP 211: Disabling Addition of New Value to the Sprout Value Pool 8
  • -
  • ZIP 212: Allow Recipient to Derive Sapling Ephemeral Secret from Note Plaintext 9
  • -
  • ZIP 214: Consensus rules for a Zcash Development Fund 10
  • -
  • ZIP 215: Explicitly Defining and Modifying Ed25519 Validation Rules 11
  • -
  • ZIP 1014: Establishing a Dev Fund for ECC, ZF, and Major Grants 13.
  • -
-

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

-

The following network upgrade constants 5 are defined for the Canopy upgrade:

-
-
CONSENSUS_BRANCH_ID
-
0xE9FF75A6
-
ACTIVATION_HEIGHT (Canopy)
-
-

Testnet: 1028500

-

Mainnet: 1046400

-
-
-

Nodes compatible with Canopy activation on testnet MUST advertise protocol version 170012 or later. Nodes compatible with Canopy activation on mainnet MUST advertise protocol version 170013 or later. The minimum peer protocol version that Canopy-compatible nodes will connect to is 170002.

-

Pre-Canopy testnet nodes are defined as nodes on testnet advertising a protocol version less than 170012. Pre-Canopy mainnet nodes are defined as nodes on mainnet advertising a protocol version less than 170013.

-

For each network (testnet and mainnet), approximately 1.5 days (defined in terms of block height) before the corresponding Canopy activation height, nodes compatible with Canopy activation on that network will change the behaviour of their peer connection logic in order to prefer pre-Canopy peers on that network for eviction from the set of peer connections:

-
/**
- * The period before a network upgrade activates, where connections to upgrading peers are preferred (in blocks).
- * This was three days for upgrades up to and including Blossom, and is 1.5 days from Heartwood onward.
- */
-static const int NETWORK_UPGRADE_PEER_PREFERENCE_BLOCK_PERIOD = 1728;
-

The implementation is similar to that for Overwinter which was described in 6.

-

Once Canopy activates on testnet or mainnet, Canopy nodes SHOULD take steps to:

-
    -
  • reject new connections from pre-Canopy nodes on that network;
  • -
  • disconnect any existing connections to pre-Canopy nodes on that network.
  • -
-
-
-

Backward compatibility

-

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

-

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

-

Unlike Overwinter and Sapling, and like Blossom and Heartwood, Canopy does not define a new transaction version. Canopy transactions are therefore in the same v4 format as Sapling transactions; use the same version group ID, i.e. 0x892F2085 as defined in 4; and use the same transaction digest algorithm as defined in 12. This does not imply that transactions are valid across the Canopy activation, since signatures MUST use the appropriate consensus branch ID. 12

-
-

Support in zcashd

-

Support for Canopy on testnet will be implemented in zcashd version 3.1.0, which will advertise protocol version 170012. Support for Canopy on mainnet will be implemented in zcashd version 4.0.0, which will advertise protocol version 170013.

-
-

References

- - - - - - - -
1Information 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"
- - - - - - - -
2Zcash Protocol Specification, Version 2021.2.16 or later
- - - - - - - -
3Zcash Protocol Specification, Version 2021.2.16. Section 3.12: Mainnet and Testnet
- - - - - - - -
4Zcash Protocol Specification, Version 2021.2.16. Section 7.1: Transaction Encoding and Consensus
- - - - - - - -
5ZIP 200: Network Upgrade Mechanism
- - - - - - - -
6ZIP 201: Network Peer Management for Overwinter
- - - - - - - -
7ZIP 207: Funding Streams
- - - - - - - -
8ZIP 211: Disabling Addition of New Value to the Sprout Value Pool
- - - - - - - -
9ZIP 212: Allow Recipient to Derive Sapling Ephemeral Secret from Note Plaintext
- - - - - - - -
10ZIP 214: Consensus rules for a Zcash Development Fund
- - - - - - - -
11ZIP 215: Explicitly Defining and Modifying Ed25519 Validation Rules
- - - - - - - -
12ZIP 243: Transaction Signature Validation for Sapling
- - - - - - - -
13ZIP 1014: Establishing a Dev Fund for ECC, ZF, and Major Grants
-
-
- - \ No newline at end of file diff --git a/rendered/zip-0252.html b/rendered/zip-0252.html deleted file mode 100644 index 92f931d3a..000000000 --- a/rendered/zip-0252.html +++ /dev/null @@ -1,297 +0,0 @@ - - - - ZIP 252: Deployment of the NU5 Network Upgrade - - - -
-
ZIP: 252
-Title: Deployment of the NU5 Network Upgrade
-Owners: teor <teor@zfnd.org>
-        Daira-Emma Hopwood <daira-emma@electriccoin.co>
-Status: Final
-Category: Consensus / Network
-Created: 2021-02-23
-License: MIT
-Discussions-To: <https://github.com/zcash/zips/issues/440>
-Pull-Request: <https://github.com/zcash/zips/pull/446>
-

Terminology

-

The key words "MUST" and "SHOULD" 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. 6

-

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 NU5 network upgrade.

-
-

Specification

-

NU5 deployment

-

The primary sources of information about NU5 consensus and peer-to-peer protocol changes are:

-
    -
  • The Zcash Protocol Specification 2 4
  • -
  • ZIP 200: Network Upgrade Mechanism 6
  • -
  • ZIP 216: Require Canonical Point Encodings 12
  • -
  • ZIP 224: Orchard Shielded Protocol 14
  • -
  • ZIP 225: Version 5 Transaction Format 15
  • -
  • ZIP 239: Relay of Version 5 Transactions 16
  • -
  • ZIP 244: Transaction Identifier Non-Malleability 17
  • -
  • The Orchard Book 20
  • -
  • The halo2 Book 21
  • -
-

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

-

Unified addresses and viewing keys are described in ZIP 316 18.

-

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

-
    -
  • ZIP 32: Shielded Hierarchical Deterministic Wallets 5
  • -
  • ZIP 203: Transaction Expiry 8
  • -
  • ZIP 209: Prohibit Negative Shielded Chain Value Pool Balances 9
  • -
  • ZIP 212: Allow Recipient to Derive Ephemeral Secret from Note Plaintext 10
  • -
  • ZIP 213: Shielded Coinbase 11
  • -
  • ZIP 221: FlyClient - Consensus-Layer Changes 13
  • -
  • ZIP 401: Addressing Mempool Denial-of-Service 19
  • -
-

The following network upgrade constants 6 are defined for the NU5 upgrade:

-
-
CONSENSUS_BRANCH_ID
-
0xc2d6d0b4
-
ACTIVATION_HEIGHT (NU5)
-
-

Testnet (second activation): 1842420

-

Mainnet: 1687104

-
-
MIN_NETWORK_PROTOCOL_VERSION (NU5)
-
-

Testnet (second activation): 170050

-

Mainnet: 170100

-
-
-

Note: A first activation of NU5, with a previous version of the Orchard circuit and other NU5 consensus rules, occurred on Testnet at block height 1599200 with consensus branch ID 0x37519621 and peer protocol version 170015. With the release of zcashd v4.7.0, Testnet is being rolled back to another chain that forks from the block immediately preceding that activation, at height 1599199. This chain had been continuously mined by zcashd v4.0.0 nodes modified to disable End-of-Service halt.

-

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

-

For each network, pre-NU5 nodes are defined as nodes advertising a protocol version less than that network's MIN_NETWORK_PROTOCOL_VERSION (NU5).

-

Once NU5 activates on Testnet or Mainnet, NU5 nodes SHOULD take steps to:

-
    -
  • reject new connections from pre-NU5 nodes on that network;
  • -
  • disconnect any existing connections to pre-NU5 nodes on that network.
  • -
-

The change to the peer-to-peer protocol described in ZIP 239 took effect from peer protocol version 170014 onward, on both Testnet and Mainnet. 16

-
-
-

Backward compatibility

-

Prior to the network upgrade activating on each network, NU5 and pre-NU5 nodes are compatible and can connect to each other. (In the case of Testnet, there was a prolonged period of network fracturing due to a consensus bug, but this is expected to be resolved with the release of zcashd v4.7.0.)

-

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

-

Unlike Blossom, Heartwood, and Canopy, and like Overwinter and Sapling, NU5 defines a new transaction version. Therefore, NU5 transactions MAY be in the new v5 format specified by 15. Unlike previous transaction version updates, the existing v4 transaction format remains valid after NU5 activation. Both transaction formats MUST be accepted by NU5 nodes.

-

Backward compatibility of the new MSG_WTX inv type introduced for inv and getdata messages is discussed in 16.

-
-

Support in zcashd

-

Several versions of zcashd have implemented versions of the NU5 consensus rules on Testnet:

-
    -
  • zcashd v4.5.0 implemented a consensus revision that contained critical bugs in the Orchard Action circuit.
  • -
  • Before that revision could activate, zcashd v4.5.1 was released, with a later activation height of 1599200 as described in section NU5 deployment above. This revision also had a consensus bug that caused many nodes to stall at or near height 1779199, shortly after the first block containing an Orchard output.
  • -
  • zcashd v4.7.0 implements what is expected to be the final revision of the NU5 consensus rules, causing a long rollback to an alternate Testnet chain. It is necessary to use the -reindex and -rescan options to zcashd in order to follow this chain as intended.
  • -
-

Support for NU5 on Mainnet will be implemented in zcashd version 5.0.0, which will advertise protocol version 170100.

-

Backward compatibility in zcashd

-

The minimum peer protocol version that NU5-compatible zcashd nodes will connect to is 170002. On Testnet, they will immediately disconnect from nodes advertising a peer protocol version less than 170040.

-
-

NU5 deployment for zcashd

-

For each network, approximately 1.5 days (defined in terms of block height) before the corresponding NU5 activation height, nodes compatible with NU5 activation on that network will change the behaviour of their peer connection logic in order to prefer pre-NU5 peers on that network for eviction from the set of peer connections:

-
/**
- * The period before a network upgrade activates, where connections to upgrading peers are preferred (in blocks).
- * This was three days for upgrades up to and including Blossom, and is 1.5 days from Heartwood onward.
- */
-static const int NETWORK_UPGRADE_PEER_PREFERENCE_BLOCK_PERIOD = 1728;
-

The implementation is similar to that for Overwinter which was described in 7.

-

However, NU5 nodes will have a preference for connecting to other NU5 nodes, so pre-NU5 nodes will gradually be disconnected in the run up to activation.

-
-
-

Support in Zebra

-

Several versions of Zebra have implemented versions of the NU5 consensus rules on Testnet:

-
    -
  • zebrad v1.0.0-alpha.18 implemented partial support for NU5 on Testnet, validating a strict subset of the NU5 consensus rules. This version had an activation height of 1599200, as described in section NU5 deployment above.
  • -
  • zebrad v1.0.0-beta.8 will fully validate what is expected to be the final revision of the NU5 consensus rules. As part of these consensus rule changes, zebrad v1.0.0-beta.8 will automatically re-download the entire chain from genesis, then follow an alternate chain starting at height 1599200. It will advertise protocol version 170050.
  • -
-

Support for NU5 on Mainnet will be implemented in zebrad version v1.0.0-beta.10, which will advertise protocol version 170100.

-

Backward compatibility in Zebra

-

The minimum peer protocol version that NU5-compatible Zebra nodes will connect to is 170002. They will immediately disconnect from nodes advertising a peer protocol version less than:

-
    -
  • 170040 on Testnet, or
  • -
  • 170013 on Mainnet.
  • -
-
-

NU5 deployment for Zebra

-

For each network, at the corresponding NU5 activation height, nodes compatible with NU5 activation on that network will close existing connections with pre-NU5 peers, and reject new connections from pre-NU5 peers.

-
-
-

References

- - - - - - - -
1Information 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"
- - - - - - - -
2Zcash Protocol Specification, Version 2021.2.16 or later
- - - - - - - -
3Zcash Protocol Specification, Version 2021.2.16 [NU5 proposal]. Section 3.12: Mainnet and Testnet
- - - - - - - -
4Zcash Protocol Specification, Version 2021.2.16 [NU5 proposal]. Section 7.1: Transaction Encoding and Consensus
- - - - - - - -
5ZIP 32: Shielded Hierarchical Deterministic Wallets
- - - - - - - -
6ZIP 200: Network Upgrade Mechanism
- - - - - - - -
7ZIP 201: Network Peer Management for Overwinter
- - - - - - - -
8ZIP 203: Transaction Expiry
- - - - - - - -
9ZIP 209: Prohibit Negative Shielded Chain Value Pool Balances
- - - - - - - -
10ZIP 212: Allow Recipient to Derive Ephemeral Secret from Note Plaintext
- - - - - - - -
11ZIP 213: Shielded Coinbase
- - - - - - - -
12ZIP 216: Require Canonical Point Encodings
- - - - - - - -
13ZIP 221: FlyClient - Consensus-Layer Changes
- - - - - - - -
14ZIP 224: Orchard Shielded Protocol
- - - - - - - -
15ZIP 225: Version 5 Transaction Format
- - - - - - - -
16ZIP 239: Relay of Version 5 Transactions
- - - - - - - -
17ZIP 244: Transaction Identifier Non-Malleability
- - - - - - - -
18ZIP 316: Unified Addresses and Unified Viewing Keys
- - - - - - - -
19ZIP 401: Addressing Mempool Denial-of-Service
- - - - - - - -
20The Orchard Book
- - - - - - - -
21The halo2 Book
-
-
- - \ No newline at end of file diff --git a/rendered/zip-0253.html b/rendered/zip-0253.html deleted file mode 100644 index a667fd3b1..000000000 --- a/rendered/zip-0253.html +++ /dev/null @@ -1,152 +0,0 @@ - - - - ZIP 253: Deployment of the NU6 Network Upgrade - - - - - -
ZIP: 253
-Title: Deployment of the NU6 Network Upgrade
-Owners: Arya <arya@zfnd.org>
-Status: Proposed
-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

-

This proposal defines the deployment of the NU6 network upgrade.

-

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 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:

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

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

-
-
CONSENSUS_BRANCH_ID
-
-0xC8E71055 -
-
ACTIVATION_HEIGHT (NU6)
-
-Testnet: 2976000 -
-
-Mainnet: 2726400 -
-
MIN_NETWORK_PROTOCOL_VERSION (NU6)
-
-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

- - - diff --git a/rendered/zip-0300.html b/rendered/zip-0300.html deleted file mode 100644 index b8ec28883..000000000 --- a/rendered/zip-0300.html +++ /dev/null @@ -1,76 +0,0 @@ - - - - ZIP 300: Cross-chain Atomic Transactions - - - -
-
ZIP: 300
-Title: Cross-chain Atomic Transactions
-Owners: Daira-Emma Hopwood <daira-emma@electriccoin.co>
-Original-Authors: Jay Graber
-Status: Proposed
-Category: Informational
-Created: 2017-03-08
-License: MIT
-Pull-Request: <https://github.com/zcash/zips/pull/123>
-

Abstract

-

This is an Informational ZIP describing a proposed specification for a standardized protocol for performing cross-chain atomic transactions (XCAT) between Zcash and Bitcoin, or other Bitcoin-derived cryptocurrencies.

-
-

Status

-

This proposal only supports transparent cross-chain swaps and relies on the scripting system inherited from Bitcoin. At the time of writing (September 2020), it has not achieved widespread adoption.

-
-

Motivation

-

A well-defined standard for performing cross-chain transactions would improve the liquidity of cryptocurrencies and be useful for third-party services, such as decentralized exchanges.

-
-

Specification

-

The proposed protocol for XCAT is a set of hash time-locked contracts across both chains, created by two parties who wish to do a cross-chain exchange.

-

To perform an exchange, both parties need to have the public keys of the other, on both chains. The party that wishes to initiate the exchange (the "seller") constructs two hash time-locked contracts by generating pay-to-script-hash (P2SH) addresses using the XCAT protocol and the public key of their counterparty (the "buyer").

-

For the purposes of this example, the seller initiating the exchange will be named "Alice", and the buyer agreeing to complete the exchange will be named "Bob".

-

Alice wishes to initiate an XCAT exchange from Bitcoin to Zcash. She chooses a random number R, hashes it, and creates a P2SH address on the Zcash blockchain using her and Bob's public keys, that she will wait for Bob to fund with the amount he wants to trade. (Agreement on the amount to trade and exchange rate is outside the scope of this protocol, and could be determined out-of-band, or within the user interface of an application using XCAT under the hood)

-

The script in the P2SH address takes the following form:

-
OP_IF
-    [HASHOP] <hash digest of R> OP_EQUALVERIFY OP_DUP OP_HASH160 <Alice's pubkey hash>
-OP_ELSE
-    <time-out duration (24 hours)> CHECKLOCKTIMEVERIFY OP_DROP OP_DUP OP_HASH160 <Bob's pubkey hash>
-OP_ENDIF
-OP_EQUALVERIFY
-OP_CHECKSIG
-

There are two scenarios for spending funds from this P2SH address. The first is a successful atomic swap which gives Alice the money she asked for, and gives Bob access to the secret R which he can use to redeem his funds on the other blockchain. The second is a fail case which refunds Bob's money if Alice does not follow through.

-
    -
  1. Success case: Alice spends the funds sent to the address, revealing the random number R she hashed to create the script in the process.
  2. -
  3. Fail case: Alice does not spend the funds sent to the address within the timeout period, so Bob sends his funds back to himself, canceling the transaction.
  4. -
-

At the same time that Alice creates this P2SH address on the Zcash blockchain, she must also create a P2SH address on the Bitcoin blockchain, which she funds herself with the amount of BTC she wants to trade out of.

-

The script for this second transaction takes the following form:

-
OP_IF
-    [HASHOP] <hash digest of R> OP_EQUALVERIFY OP_DUP OP_HASH160 <Bob's pubkey hash>
-OP_ELSE
-    <time-out duration (48 hours)> CHECKLOCKTIMEVERIFY OP_DROP OP_DUP OP_HASH160 <Alice's pubkey hash>
-OP_ENDIF
-OP_EQUALVERIFY
-OP_CHECKSIG
-

The two scenarios for spending funds from this second P2SH address are as follows:

-
    -
  1. Success case: Bob uses R to spend the funds from this P2SH address, as Alice has already revealed R to Bob in the process of spending from the P2SH address he sent ZEC to on the Zcash blockchain. The cross-chain atomic transaction is now complete, and both parties have the funds they requested.
  2. -
  3. Fail case: Bob has not followed through on his part of the trade within the timeout period, so Alice sends her funds back to herself, canceling the transaction.
  4. -
-

Timeout Periods

-

Having timeout periods on both transactions allows the XCAT protocol to work by enabling refunds in case a counterparty misbehaves. The example above uses a timeout period of 24 hours for the first transaction and 48 hours for the second, but these are simply suggestions. Actual timeout periods should be considered to be variables that depend on the following factors for any given implementation of XCAT:

-

Duration

-

The time-lock period on the transaction in which the initiating party reveals R must be significantly shorter than the time-lock period on the second transaction in which the other party uses the revealed R, in order to give them enough time to make use of R to redeem their funds.

-

For example, once Alice reveals R by spending what Bob sent to her P2SH address, Bob must have enough time to use R to redeem his funds on the other blockchain before Alice can be allowed to refund herself. If there were an insufficient time delay between the first and second timeout periods, Alice could potentially spend Bob's funds at the last minute, then quickly refund herself on the other blockchain before Bob gets a chance to redeem his portion using the R she reveals.

-

Note that using long time-locks in the P2SH scripts does not necessarily mean that the transactions themselves will take a long time. If both parties are immediately responsive and execute their trades in a timely manner, providing the correct information, the full cross-chain atomic trade can happen quickly. The full duration of the timeout period for each transaction only elapses in the fail case, when either Alice or Bob defaults on their agreement to exchange.

-
-

Block times

-

The protection provided by the timeout period must take into account relative block times between the two blockchains.

-
-
-
-

Rationale

-

Users are free to come up with their own protocols for cross-chain atomic transactions, but having a well-defined protocol would aid adoption and support third-party services wishing to provide such functionality.

-
-
- - \ No newline at end of file diff --git a/rendered/zip-0301.html b/rendered/zip-0301.html deleted file mode 100644 index e84119136..000000000 --- a/rendered/zip-0301.html +++ /dev/null @@ -1,428 +0,0 @@ - - - - ZIP 301: Zcash Stratum Protocol - - - -
-
ZIP: 301
-Title: Zcash Stratum Protocol
-Owners: Jack Grigg <str4d@electriccoin.co>
-Credits: 5a1t
-         Daira-Emma Hopwood
-         Marek Palatinus (slush) and colleagues
-         Jelle Bourdeaud'hui (razakal)
-         ocminer
-Status: Final
-Category: Standards / Ecosystem
-Created: 2016-09-23
-License: MIT
-

Terminology

-

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

-
-

Abstract

-

This ZIP describes the Zcash variant of the Stratum protocol, used by miners to communicate with mining pool servers.

-
-

Motivation

-

Many existing cryptocurrency miners and pools use the original Stratum protocol 4 5 for communication, in situations where the miner does not require any control over what they mine (for example, a miner connected to a local 6 node). However, the protocol is very specific to Bitcoin, in that it makes assumptions about the block header format, and the available nonce space 7. Zcash has made changes that invalidate these assumptions.

-

Having a formal specification for a Zcash-compatible Stratum-style mining protocol means that existing pool operators and miner authors can quickly and easily migrate their frameworks to the Zcash network, with no ambiguity about interoperability.

-
-

Specification

-

The Stratum protocol is an instance of 9. The miner is a JSON-RPC client, and the Stratum server is a JSON-RPC server. The miner starts a session by opening a standard TCP connection to the server, which is then used for two-way line-based communication:

-
    -
  • The miner can send requests to the server.
  • -
  • The server can respond to requests.
  • -
  • The server can send notifications to the client.
  • -
-

All communication for a particular session happens through a single connection, which is kept open for the duration of the session. If the connection is broken or either party disconnects, the active session is ended. Servers MAY support session resuming; this is negotiated between the client and server during initial setup (see Session Resuming).

-

Each request or response is a JSON string, terminated by an ASCII LF character (denoted in the rest of this specification by \n). The LF character MUST NOT appear elsewhere in a request or response. Client and server implementations MAY assume that once they read a LF character, the current message has been completely received.

-

Per 9, there is no requirement for the id property in requests and responses to be unique; only that servers MUST set id in their responses equal to that in the request they are responding to (or null for notifications). However, it is RECOMMENDED that clients use unique ids for their requests, to simplify their response parsing.

-

In the protocol messages below, (content) indicates that content is optional. Variable names are indicated in EMPHASIS. All other characters are part of the protocol message.

-

Error Objects

-

The 9 specification allows for error objects in responses, but does not specify their format. The original Stratum protocol uses the following format for error responses 4:

-
-

{"id": ##, "result": null, "error": [ERROR_CODE, "ERROR_MESSAGE", TRACEBACK]} \n

-
-

For compatibility, this format is retained. We therefore define an error object as an array:

-
-

[ERROR_CODE, "ERROR_MESSAGE", TRACEBACK]

-
-
-
ERROR_CODE (int)
-
-

Indicates the type of error that occurred.

-

The error codes are to be interpreted as described in 10. The following application error codes are defined:

-
    -
  • 20 - Other/Unknown
  • -
  • 21 - Job not found (=stale)
  • -
  • 22 - Duplicate share
  • -
  • 23 - Low difficulty share
  • -
  • 24 - Unauthorized worker
  • -
  • 25 - Not subscribed
  • -
-
-
ERROR_MESSAGE (str)
-
A human-readable error message. The message SHOULD be limited to a concise single sentence.
-
TRACEBACK
-
-

Additional information for debugging errors. The format is server-specific.

-

Miners MAY attempt to parse the field for displaying to the user, and SHOULD fall back to rendering it as a JSON string.

-

Servers MUST set this to null if they have no additional information.

-
-
-

Miners SHOULD display a human-readable message to the user. This message can be derived from either ERROR_CODE or ERROR_MESSAGE, or both. An example of using ERROR_CODE over ERROR_MESSAGE might be that the miner UI offers localization.

-
-

Protocol Flow

-
    -
  • Client sends mining.subscribe to set up the session.
  • -
  • Server replies with the session information.
  • -
  • Client sends mining.authorize for their worker(s).
  • -
  • Server replies with the result of authorization.
  • -
  • Server sends mining.set_target.
  • -
  • Server sends mining.notify with a new job.
  • -
  • Client mines on that job.
  • -
  • Client sends mining.submit for each solution found.
  • -
  • Server replies with whether the solution was accepted.
  • -
  • Server sends mining.notify again when there is a new job.
  • -
-
-

Nonce Parts

-

In Bitcoin, blocks contain two nonces: the 4-byte block header nonce, and an extra nonce in the coinbase transaction 7. The original Stratum protocol splits this extra nonce into two parts: one set by the server (used for splitting the search space amongst connected miners), and the other iterated by the miner 4. The nonce in Zcash's block header is 32 bytes long 2, and thus can serve both purposes simultaneously.

-

We define two nonce parts:

-
-
NONCE_1
-
The server MUST pick such that len(NONCE_1) < 32 in bytes.
-
NONCE_2
-
-

The miner MUST pick such that len(NONCE_2) = 32 - len(NONCE_1) in bytes.

-

In hex, lenHex(NONCE_2) = 64 - lenHex(NONCE_1), and both lengths are even.

-
-
-

The nonce in the block header is the concatenation of NONCE_1 and NONCE_2 in hex. This means that a miner using bignum representations of nonce MUST increment by 1 << len(NONCE_1) to avoid altering NONCE_1 (because the encoding of the nonce in the block header is little endian, in line with the other 32-byte fields 7 2).

-
-

Session Resuming

-

Servers that support session resuming identify this by setting a SESSION_ID in their initial response. Servers MAY set SESSION_ID to null to indicate that they do not support session resuming. Servers that do not set SESSION_ID to null MUST cache the following information:

-
    -
  • The session ID.
  • -
  • NONCE_1
  • -
  • Any active job IDs.
  • -
-

Servers MAY drop entries from the cache on their own schedule.

-

When a miner connects using a previous SESSION_ID:

-
    -
  • If the cache contains the SESSION_ID, the server's initial response MUST be constructed from the cached information.
  • -
  • If the server does not recognise the session, the SESSION_ID in the server's initial response MUST NOT equal the SESSION_ID provided by the miner.
  • -
-

Miners MUST re-authorize all workers upon resuming a session.

-
-

Methods

-

mining.subscribe()

-

Request:

-
-

{"id": 1, "method": "mining.subscribe", "params": ["MINER_USER_AGENT", "SESSION_ID", "CONNECT_HOST", CONNECT_PORT]} \n

-
-
-
MINER_USER_AGENT (str)
-
-

A free-form string specifying the type and version of the mining software. Recommended syntax is the User Agent format used by Zcash nodes.

-

Example: MagicBean/1.0.0

-
-
SESSION_ID (str)
-
-

The id for a previous session that the miner wants to resume (e.g. after a temporary network disconnection) (see Session Resuming).

-

This MAY be null indicating that the miner wants to start a new session.

-
-
CONNECT_HOST (str)
-
-

The host that the miner is connecting to (from the server URL).

-

Example: pool.example.com

-
-
CONNECT_PORT (int)
-
-

The port that the miner is connecting to (from the server URL).

-

Example: 3337

-
-
-

Response:

-
-

{"id": 1, "result": ["SESSION_ID", "NONCE_1"], "error": null} \n

-
-
-
SESSION_ID (str)
-
The session id, for use when resuming (see Session Resuming).
-
NONCE_1 (hex)
-
The first part of the block header nonce (see Nonce Parts).
-
-
-

mining.authorize()

-

A miner MUST authorize a worker in order to submit solutions. A miner MAY authorize multiple workers in the same session; this could be for statistical purposes on the particular server being used. Details of such purposes are outside the scope of this specification.

-

Request:

-
-

{"id": 2, "method": "mining.authorize", "params": ["WORKER_NAME", "WORKER_PASSWORD"]} \n

-
-
-
WORKER_NAME (str)
-
The worker name.
-
WORKER_PASSWORD (str)
-
The worker password.
-
-

Response:

-
-

{"id": 2, "result": AUTHORIZED, "error": ERROR} \n

-
-
-
AUTHORIZED (bool)
-
This MUST be true if authorization succeeded. Per 9, it MUST be null if there was an error.
-
ERROR (obj)
-
-

An error object. This MUST be null if authorization succeeded.

-

If authorization failed, the server MUST provide an error object describing the reason. See Error Objects for the object format.

-
-
-
-

mining.set_target()

-

Server message:

-
-

{"id": null, "method": "mining.set_target", "params": ["TARGET"]} \n

-
-
-
TARGET (hex)
-
-

The server target for the next received job and all subsequent jobs (until the next time this message is sent). The miner compares proposed block hashes with this target as a 256-bit big-endian integer, and valid blocks MUST NOT have hashes larger than (above) the current target (in accordance with the Zcash network consensus rules 3).

-

Miners SHOULD NOT submit work above this target. Miners SHOULD validate their solutions before submission (to avoid both unnecessary network traffic and wasted miner time).

-

Servers MUST NOT accept submissions above this target for jobs sent after this message. Servers MAY accept submissions above this target for jobs sent before this message, but MUST check them against the previous target.

-
-
-

When displaying the current target in the UI to users, miners MAY convert the target to an integer difficulty as used in Bitcoin miners. When doing so, miners SHOULD use powLimit (as defined in src/chainparams.cpp) as the basis for conversion.

-
-

mining.notify()

-

Server message:

-
-

{"id": null, "method": "mining.notify", "params": ["JOB_ID", "VERSION", "PREVHASH", "MERKLEROOT", "RESERVED", "TIME", "BITS", CLEAN_JOBS]} \n

-
-
-
JOB_ID (str)
-
The id of this job.
-
VERSION (hex)
-
-

The block header version, encoded as in a block header (little-endian int32_t).

-

Used as a switch for subsequent parameters. At time of writing, the only defined block header version is 4. Miners SHOULD alert the user upon receiving jobs containing block header versions they do not know about or support, and MUST ignore such jobs.

-

Example: 04000000

-
-
-

The following parameters are only valid for VERSION == "04000000":

-
-
PREVHASH (hex)
-
The 32-byte hash of the previous block, encoded as in a block header.
-
MERKLEROOT (hex)
-
The 32-byte Merkle root of the transactions in this block, encoded as in a block header.
-
RESERVED (hex)
-
A 32-byte reserved field, encoded as in a block header. Zero by convention (in hex, 0000000000000000000000000000000000000000000000000000000000000000).
-
TIME (hex)
-
The block time suggested by the server, encoded as in a block header.
-
BITS (hex)
-
The current network difficulty target, represented in compact format, encoded as in a block header.
-
CLEAN_JOBS (bool)
-
If true, a new block has arrived. The miner SHOULD abandon all previous jobs.
-
-
-

mining.submit()

-

Request:

-
-

{"id": 4, "method": "mining.submit", "params": ["WORKER_NAME", "JOB_ID", "TIME", "NONCE_2", "EQUIHASH_SOLUTION"]} \n

-
-
-
WORKER_NAME (str)
-
-

A previously-authenticated worker name.

-

Servers MUST NOT accept submissions from unauthenticated workers.

-
-
JOB_ID (str)
-
-

The id of the job this submission is for.

-

Miners MAY make multiple submissions for a single job id.

-
-
TIME (hex)
-
-

The block time used in the submission, encoded as in a block header.

-

MAY be enforced by the server to be unchanged.

-
-
NONCE_2 (hex)
-
The second part of the block header nonce (see Nonce Parts).
-
EQUIHASH_SOLUTION (hex)
-
The Equihash solution, encoded as in a block header (including the compactSize at the beginning in canonical form 8).
-
-

Result:

-
-

{"id": 4, "result": ACCEPTED, "error": ERROR} \n

-
-
-
ACCEPTED (bool)
-
This MUST be true if the submission was accepted. Per 9, it MUST be null if there was an error.
-
ERROR (obj)
-
-

An error object. Per 9, this MUST be null if the submission was accepted without error.

-

If the submission was not accepted, the server MUST provide an error object describing the reason for not accepting the submission. See Error Objects for the object format.

-
-
-
-

client.reconnect()

-

Server message:

-
-

{"id": null, "method": "client.reconnect", "params": [("HOST", PORT, WAIT_TIME)]} \n

-
-
-
HOST (str)
-
-

The host to reconnect to.

-

Example: pool.example.com

-
-
PORT (int)
-
-

The port to reconnect to.

-

Example: 3337

-
-
WAIT_TIME (int)
-
Time in seconds that the miner should wait before reconnecting.
-
-

If client.reconnect is sent with an empty parameter array, the miner SHOULD reconnect to the same host and port it is currently connected to.

-
-

mining.suggest_target()

-

Request (optional):

-
-

{"id": 3, "method": "mining.suggest_target", "params": ["TARGET"]} \n

-
-
-
TARGET (hex)
-
The target suggested by the miner for the next received job and all subsequent jobs (until the next time this message is sent).
-
-

The server SHOULD reply with mining.set_target. The server MAY set the result id equal to the request id.

-
-
-
-

Rationale

-

Why does mining.subscribe include the host and port?

-
    -
  • It has the same use cases as the Host: header in HTTP. Specifically, it enables virtual hosting, where virtual pools or private URLs might be used for DDoS protection, but that are aggregated on Stratum server backends. As with HTTP, the server CANNOT trust the host string.
  • -
  • The port is included separately to parallel the client.reconnect method; both are extracted from the server URL that the miner is connecting to (e.g. stratum+tcp://pool.example.com:3337).
  • -
-

Why use the 256-bit target instead of a numerical difficulty?

-
    -
  • There is no protocol ambiguity when using a target. A server can pick a specific target (by whatever algorithm), and enforce it cleanly on submitted jobs. -
      -
    • A numerical difficulty must be converted into a target by miners, which adds unnecessary complexity, results in a loss of precision, and leaves ambiguity over the conversion and the validity of resulting submissions.
    • -
    -
  • -
  • The minimum numerical difficulty in Bitcoin's Stratum protocol is 1, which corresponds to powLimit. This makes it harder to test miners and servers. A target can represent difficulties lower than the minimum.
  • -
-

Does a 256-bit target waste bandwidth?

-
    -
  • The target is generally not set as often as solutions are submitted, so any effect is minimal.
  • -
  • Zcash's proof-of-work, Equihash, is much slower than Bitcoin's, so any latency caused by the size of the target is minimal compared to the overall solver time.
  • -
  • For the current Equihash parameters (200/9), the Equihash solution dominates bandwidth usage.
  • -
-

Why does mining.submit include WORKER_NAME?

-
    -
  • WORKER_NAME is only included here for statistical purposes (like monitoring performance and/or downtime). JOB_ID is used for pairing server-stored jobs with submissions.
  • -
-
-

Reference Implementation

- -
-

Acknowledgements

-

Thanks to:

-
    -
  • 5a1t for the initial brainstorming session.
  • -
  • Daira-Emma Hopwood for hir input on API selection and design.
  • -
  • Marek Palatinus (slush) and his colleagues for their refinements, suggestions, and robust discussion.
  • -
  • Jelle Bourdeaud'hui (razakal) and ocminer for their help with testing and finding implementation bugs in the specification.
  • -
-
-

References

- - - - - - - -
1Information 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"
- - - - - - - -
2Zcash Protocol Specification, Version 2020.1.15. Section 7.3: Block Headers
- - - - - - - -
3Zcash Protocol Specification, Version 2020.1.15. Section 7.6.2: Difficulty filter
- - - - - - - -
4Stratum Mining Protocol. Slush Pool
- - - - - - - -
5Stratum protocol documentation. Bitcoin Forum
- - - - - - - -
6P2Pool. Bitcoin Wiki
- - - - - - - -
7Block Headers - Bitcoin Developer Reference.
- - - - - - - -
8Variable length integer. Bitcoin Wiki
- - - - - - - -
9JSON-RPC 1.0 Specification (2005).
- - - - - - - -
10JSON-RPC 2.0 Specification. The JSON-RPC Working Group.
-
-
- - \ No newline at end of file diff --git a/rendered/zip-0302.html b/rendered/zip-0302.html deleted file mode 100644 index a404fc92b..000000000 --- a/rendered/zip-0302.html +++ /dev/null @@ -1,95 +0,0 @@ - - - - ZIP 302: Standardized Memo Field Format - - - -
-
ZIP: 302
-Title: Standardized Memo Field Format
-Owners: Jack Grigg <jack@electriccoin.co>
-Original-Authors: Jay Graber
-Status: Draft
-Category: Standards / RPC / Wallet
-Created: 2017-02-08
-Discussions-To: <https://github.com/zcash/zips/issues/366>
-Pull-Request: <https://github.com/zcash/zips/pull/105>
-

Abstract

-

This ZIP describes a proposed specification for a standardized format for clients who wish to transmit or receive content within the encrypted memo field of shielded transactions.

-
-

Motivation

-

A well-defined standard for formatting content within the encrypted memo field will help expand its use within the Zcash ecosystem by providing a commonly recognized format for memo values carrying different types of data. Users and third-party services benefit from standardized formatting rules that define the type and length of the data contained within.

-
-

Specification

-

Section 5.5 of the Zcash protocol specification 1 defines three cases for the encoding of a memo field:

-
    -
  • a UTF-8 human-readable string 2, padded by appending zero bytes; or
  • -
  • the byte 0xF6 followed by 511 0x00 bytes, indicating "no memo"; or
  • -
  • any other sequence of 512 bytes starting with a byte value 0xF5 or greater (which is therefore not a valid UTF-8 string), as specified in ZIP 302.
  • -
-

This ZIP refines the specification of the third case.

-

The following specification constrains a party, called the "reader", that interprets the contents of a memo. It does not define consensus requirements.

-
    -
  • If the first byte (byte 0) has a value of 0xF4 or smaller, then the reader MUST: -
      -
    • strip any trailing zero bytes
    • -
    • decode it as a UTF-8 string (if decoding fails then report an error).
    • -
    -
  • -
  • If the first byte has a value of 0xF6, and the remaining 511 bytes are 0x00, then the user supplied no memo, and the encrypted memo field is to be treated as empty.
  • -
  • If the memo matches any of these patterns, then this memo is from the future, because these ranges are reserved for future updates to this specification: -
      -
    • The first byte has a value of 0xF6, and the remaining 511 bytes are not all 0x00.
    • -
    • The first byte has a value between 0xF7 and 0xFE inclusive.
    • -
    -
  • -
  • If the first byte has a value of 0xFF then the reader should not make any other assumption about the memo. In order to put arbitrary data into a memo field (that might have some private non-standard structure), the value of the first byte SHOULD be set to 0xFF; the remaining 511 bytes are then unconstrained.
  • -
  • If the first byte has a value of 0xF5, then the reader should not make any other assumption about the memo. This value was used ambiguously in the past by private agreement; applications SHOULD prefer 0xFF which is unambiguously for this purpose.
  • -
-
-

Rationale

-

The new protocol specification is an improvement over the current memo field content specification that was in the protocol spec up to version 2020.1.0, which stated:

-
-

The usage of the memo field is by agreement between the sender and recipient of the note. The memo field SHOULD be encoded either as:

-
    -
  • a UTF-8 human-readable string [Unicode], padded by appending zero bytes; or
  • -
  • an arbitrary sequence of 512 bytes starting with a byte value of 0xF5 or greater, which is therefore not a valid UTF-8 string.
  • -
-

In the former case, wallet software is expected to strip any trailing zero bytes and then display the resulting UTF-8 string to the recipient user, where applicable. Incorrect UTF-8-encoded byte sequences should be displayed as replacement characters (U+FFFD).

-

In the latter case, the contents of the memo field SHOULD NOT be displayed. A start byte of 0xF5 is reserved for use by automated software by private agreement. A start byte of 0xF6 or greater is reserved for use in future Zcash protocol extensions.

-
-

See issue #1849 for further discussion.

-
-

Backwards Compatibility

-

Encrypted memo field contents sent without the standardized format proposed here will be interpreted according to the specification set out in older versions of the protocol spec.

-
-

References

- - - - - - - -
1Zcash Protocol Specification, Version 2021.1.19
- - - - - - - -
2UTF-8, a transformation format of ISO 10646
- - - - - - - -
3Variable length integer. Bitcoin Wiki
-
-
- - \ No newline at end of file diff --git a/rendered/zip-0303.html b/rendered/zip-0303.html deleted file mode 100644 index 56d842505..000000000 --- a/rendered/zip-0303.html +++ /dev/null @@ -1,18 +0,0 @@ - - - - ZIP 303: Sprout Payment Disclosure - - - -
-
ZIP: 303
-Title: Sprout Payment Disclosure
-Owners: Deirdre Connolly <deirdre@zfnd.org>
-Original-Authors: Simon Liu
-Status: Reserved
-Category: Standards / RPC / Wallet
-Pull-Request: <https://github.com/zcash/zips/pull/119>
-
- - \ No newline at end of file diff --git a/rendered/zip-0304.html b/rendered/zip-0304.html deleted file mode 100644 index 453038ad0..000000000 --- a/rendered/zip-0304.html +++ /dev/null @@ -1,436 +0,0 @@ - - - - ZIP 304: Sapling Address Signatures - - - - -
-
ZIP: 304
-Title: Sapling Address Signatures
-Owners: Jack Grigg <jack@electriccoin.co>
-Credits: Daira-Emma Hopwood <daira-emma@electriccoin.co>
-         Sean Bowe <sean@electriccoin.co>
-Status: Draft
-Category: Standards / RPC / Wallet
-Created: 2020-06-01
-License: MIT
-Discussions-To: <https://github.com/zcash/zips/issues/345>
-Pull-Request: <https://github.com/zcash/zips/pull/376>
-

Terminology

-

The key words "MUST" and "SHOULD" in this document is to be interpreted as described in BCP 14 1 when, and only when, they appear in all capitals.

-
-

Abstract

-

This proposal describes a mechanism for creating signatures with Sapling addresses, suitable for use by the signmessage and verifymessage RPC methods in zcashd.

-
-

Motivation

-

There are a variety of situations where it is useful for a user to be able to prove that they control a given payment address. For example, before a high-value transfer of funds, the sender may want to verify that the recipient will definitely be able to spend them, to ensure that the funds won't be stuck in an invalid or unusable address.

-

A payment address is analogous (in some cases, identical) to a public key in a signature scheme. A transaction that spends funds received by the address, is authorized by making (the equivalent of) a signature with the corresponding spending key. This authorization protocol can be repurposed to instead sign a message provided by a third party.

-

Bitcoin Core's bitcoind provides a signmessage RPC method that implements message signing for Bitcoin addresses, leveraging the fact that a Bitcoin private key is just a secp256k private key, and a Bitcoin transaction authorizes spends with a signature. zcashd inherited this RPC method, and it can be used to make signatures for transparent Zcash addresses.

-

However, support for signing messages with shielded addresses was not possible when Zcash launched, because of the design of the Sprout protocol (and the state of zero-knowledge proof R&D at the time). Shielded transactions, by design, do not expose the payment address of the sender when creating a transaction; in Sprout, this meant that the spending key was a private input to the zero-knowledge proof, and not a key that could be used to create a signature.

-

One of the R&D achievements behind the Sapling protocol was the ability to use elliptic curves inside a circuit. With this primitive available, Sapling keys and payment addresses could be designed such that transaction authorization involved a signature. While this was designed to enable hardware wallets (which lack the power to create zero-knowledge proofs, but can easily create signatures), it also enables the creation of a mechanism for signing arbitrary messages. That mechanism is the subject of this ZIP.

-
-

Conventions

-

The following constants and functions used in this ZIP are defined in the Zcash protocol specification: 3

-
    -
  • - \(\mathsf{MerkleDepth}^\mathsf{Sapling}\) - and - \(\mathsf{Uncommitted}^\mathsf{Sapling}\) - 6
  • -
  • - \(\mathsf{MerkleCRH}^\mathsf{Sapling}\) - 7
  • -
  • - \(\mathsf{DiversifyHash}(\mathsf{d})\) - 8
  • -
  • - \(\mathsf{MixingPedersenHash}(\mathsf{cm}, position)\) - 9
  • -
  • - \(\mathsf{PRF}^\mathsf{nfSapling}_\mathsf{nk}(ρ)\) - 10
  • -
  • - \(\mathsf{SpendAuthSig.RandomizePrivate}(α, \mathsf{sk})\) - , - \(\mathsf{SpendAuthSig.RandomizePublic}(α, \mathsf{vk})\) - , - \(\mathsf{SpendAuthSig.Sign}(\mathsf{sk}, m)\) - , and - \(\mathsf{SpendAuthSig.Verify}(\mathsf{vk}, m, σ)\) - 11
  • -
  • - \(\mathsf{NoteCommit}^\mathsf{Sapling}_\mathsf{rcm}(\mathsf{g_d}, \mathsf{pk_d}, value)\) - 12
  • -
  • - \(\mathsf{ValueCommit}_\mathsf{rcv}(value)\) - 13
  • -
-

We also reproduce some notation and functions here for convenience:

-
    -
  • - \(a\,||\,b\) - means the concatenation of sequences - \(a\) - then - \(b\) - .
  • -
  • - \(\mathsf{repr}_\mathbb{J}(P)\) - is the representation of the Jubjub elliptic curve point - \(P\) - as a bit sequence, defined in 14.
  • -
  • - \(\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\) - .
  • -
-
-

Requirements

-

Given a payment address, a message, and a valid signature, the following properties should hold:

-
    -
  • Authentication: the signature will not verify with any other payment address.
  • -
  • Binding: the signature will not verify with any modification, extension, or truncation of the message.
  • -
  • Non-malleability: it should not be possible to obtain a second valid signature (with a different encoding) for the same payment address and message without access to the spending key for that payment address.
  • -
-
-

Non-requirements

-

Multiple signatures by a single payment addresses are not required to be unlinkable.

-
-

Specification

-

A Sapling address signature is created by taking the process for creating a Sapling Spend description, and running it with fixed inputs:

-
    -
  • A fake Sapling note with a value of - \(1\) - zatoshi and - \(\mathsf{rcm} = 0\) - .
  • -
  • A Sapling commitment tree that is empty except for the commitment for the fake note.
  • -
-

Signature algorithm

-

The inputs to the signature algorithm are:

-
    -
  • The payment address - \((\mathsf{d}, \mathsf{pk_d})\) - ,
  • -
  • Its corresponding expanded spending key - \((\mathsf{ask}, \mathsf{nsk}, \mathsf{ovk})\) - ,
  • -
  • The SLIP-44 15 coin type, and
  • -
  • The message - \(msg\) - to be signed.
  • -
-

The signature is created as follows:

-
    -
  • Derive the full viewing key - \((\mathsf{ak}, \mathsf{nk}, \mathsf{ovk})\) - from the expanded spending key.
  • -
  • Let - \(\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)\) - .
  • -
  • 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 - \(path\) - be the Merkle path from position 0 to - \(\mathsf{rt}\) - . 4
  • -
  • Let - \(\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)))\) - .
  • -
  • Select a random - \(α\) - .
  • -
  • Let - \(\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})\) - . 5
  • -
  • Let - \(\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)\) - .
  • -
  • Let - \(spendAuthSig = \mathsf{SpendAuthSig.Sign}(\mathsf{rsk}, digest)\) - .
  • -
  • Return - \((\mathsf{nf}, \mathsf{rk}, zkproof, spendAuthSig)\) - .
  • -
-
-

Verification algorithm

-

The inputs to the verification algorithm are:

-
    -
  • The payment address - \((\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)\) - .
  • -
-

The signature MUST be verified as follows:

-
    -
  • 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)\) - .
  • -
  • If - \(\mathsf{SpendAuthSig.Verify}(\mathsf{rk}, digest, spendAuthSig) = 0\) - , return false.
  • -
  • 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 - \(\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 - \(path\) - be the Merkle path from position 0 to - \(\mathsf{rt}\) - . 4
  • -
  • Let - \(\mathsf{cv} = \mathsf{ValueCommit}_0(1)\) - . -
      -
    • This is a constant and may be pre-computed.
    • -
    -
  • -
  • Decode and verify - \(zkproof\) - as a Sapling spend proof with primary input - \((\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\) - , 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:"}\) - followed by the result of Base64-encoding 2 the raw form of the signature.

-
-
-

Rationale

-

We use a fake note within the signature scheme in order to reuse the Sapling Spend circuit and its parameters. It is possible to construct a signature scheme with a smaller encoded signature, but this would require a new circuit and another parameter-generation ceremony (if Groth16 were used).

-

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 - \(\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 - \(\mathsf{rcm}\) - and - \(\mathsf{rcv}\) - from the signature.

-
-

Security and Privacy Considerations

-

A normal (and desired) property of signature schemes is that all signatures for a specific public key are linkable if the public key is known. ZIP 304 signatures have the additional property that all signatures for a specific payment address are linkable without knowing 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 - \(α\) - is never re-used across signatures.

-

Most of the data within a ZIP 304 signature is inherently non-malleable:

-
    -
  • - \(\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 - \(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\) - , by including - \(zkproof\) - in the message digest.

-
-

Reference implementation

-

https://github.com/zcash/librustzcash/pull/210

-
-

References

- - - - - - - -
1Information 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"
- - - - - - - -
2RFC 4648: The Base16, Base32, and Base64 Data Encodings
- - - - - - - -
3Zcash Protocol Specification, Version 2020.1.15 or later
- - - - - - - -
4Zcash Protocol Specification, Version 2020.1.15. Section 4.8: Merkle path validity
- - - - - - - -
5Zcash Protocol Specification, Version 2020.1.15. Section 4.15.2: Spend Statement (Sapling)
- - - - - - - -
6Zcash Protocol Specification, Version 2020.1.15. Section 5.3: Constants
- - - - - - - -
7Zcash Protocol Specification, Version 2020.1.15. Section 5.4.1.3: Merkle Tree Hash Function
- - - - - - - -
8Zcash Protocol Specification, Version 2020.1.15. Section 5.4.1.6: DiversifyHash Hash Function
- - - - - - - -
9Zcash Protocol Specification, Version 2020.1.15. Section 5.4.1.8: Mixing Pedersen Hash Function
- - - - - - - -
10Zcash Protocol Specification, Version 2020.1.15. Section 5.4.2: Pseudo Random Functions
- - - - - - - -
11Zcash Protocol Specification, Version 2020.1.15. Section 5.4.6.1: Spend Authorization Signature
- - - - - - - -
12Zcash Protocol Specification, Version 2020.1.15. Section 5.4.7.2: Windowed Pedersen commitments
- - - - - - - -
13Zcash Protocol Specification, Version 2020.1.15. Section 5.4.7.3: Homomorphic Pedersen commitments
- - - - - - - -
14Zcash Protocol Specification, Version 2020.1.15. Section 5.4.8.3: Jubjub
- - - - - - - -
15SLIP-0044 : Registered coin types for BIP-0044
-
-
- - \ No newline at end of file diff --git a/rendered/zip-0305.html b/rendered/zip-0305.html deleted file mode 100644 index e430de062..000000000 --- a/rendered/zip-0305.html +++ /dev/null @@ -1,17 +0,0 @@ - - - - ZIP 305: Best Practices for Hardware Wallets supporting Sapling - - - -
-
ZIP: 305
-Title: Best Practices for Hardware Wallets supporting Sapling
-Owners: Daira-Emma Hopwood <daira-emma@electriccoin.co>
-Status: Reserved
-Category: Wallet
-Discussions-To: <https://github.com/zcash/zips/issues/346>
-
- - \ No newline at end of file diff --git a/rendered/zip-0306.html b/rendered/zip-0306.html deleted file mode 100644 index 6847e02c6..000000000 --- a/rendered/zip-0306.html +++ /dev/null @@ -1,17 +0,0 @@ - - - - ZIP 306: Security Considerations for Anchor Selection - - - -
-
ZIP: 306
-Title: Security Considerations for Anchor Selection
-Owners: Daira-Emma Hopwood <daira-emma@electriccoin.co>
-Status: Reserved
-Category: Informational
-Discussions-To: <https://github.com/zcash/zips/issues/351>
-
- - \ No newline at end of file diff --git a/rendered/zip-0307.html b/rendered/zip-0307.html deleted file mode 100644 index 07a72407c..000000000 --- a/rendered/zip-0307.html +++ /dev/null @@ -1,617 +0,0 @@ - - - - ZIP 307: Light Client Protocol for Payment Detection - - - - -
-
ZIP: 307
-Title: Light Client Protocol for Payment Detection
-Owners: Jack Grigg <jack@electriccoin.co>
-        Daira-Emma Hopwood <daira-emma@electriccoin.co>
-Original-Authors: George Tankersley
-Credits: Matthew Green
-Category: Standards / Ecosystem
-Status: Draft
-Created: 2018-09-17
-License: MIT
-

Terminology

-

The key words "MUST", "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 terms below are to be interpreted as follows:

-
-
Light client
-
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.
-
-
-

Abstract

-

This proposal defines a protocol for a Zcash light client supporting Sapling shielded transactions.

-
-

Motivation

-

Currently a client that wishes to send or receive shielded payments must be a full node participanting in the Zcash network. This requires an amount of available bandwidth, space, and processing power that may be unsuitable for some classes of user. This light client protocol addresses that need, and is appropriate for low-power, bandwidth-conscious, or otherwise limited machines (such as mobile phones).

-
-

High-Level Design

-

There are three logical components to a Zcash light client system:

-
    -
  • Zcash node that provides chain state and serves as a root of trust for the system.
  • -
  • Proxy server that extracts block chain data from zcashd to store and serve it in a lower-bandwidth format.
  • -
  • Light client that subscribes to the stream from a proxy server and uses that data to update its own view of the chain state. The light client MAY be attached to a wallet backend that will track particular Sapling notes.
  • -
-
- -
Outline of the light wallet architecture
-
-
-

Security Model

-

In this model, we propose payment detection privacy as our main security goal. That is, the proxy should not learn which transactions (received from the block chain) are addressed to a given light wallet. If we further assume network privacy (via Tor or similar), the proxy should not be able to link different connections or queries as deriving from the the same wallet.

-

In particular, the underlying Zcash node / proxy combination is assumed to be "honest but curious" and is trusted to provide a correct view of the current best chain state and to faithfully transmit queries and responses.

-

This ZIP does not address how to spend notes privately.

-
-

Compact Stream Format

-

A key observation in this protocol is that the current zcashd encrypted field is several hundred bytes long, due to the inclusion of a transaction “memo”. The need to download this entire field imposes a substantial bandwidth cost on each light wallets, which may be a limited mobile device on a restricted-bandwidth plan. While more efficient techniques can be developed in the future, for the moment we propose ignoring the memo field during payment detection. Futhermore, we can also ignore any information that is not directly relevant to a Sapling shielded transaction.

-

A compact block is a packaging of ONLY the data from a block needed to:

-
    -
  1. Detect a payment to your shielded Sapling address
  2. -
  3. Detect a spend of your shielded Sapling notes
  4. -
  5. Update your witnesses to generate new Sapling spend proofs.
  6. -
-

A compact block and its component compact transactions are encoded on the wire using the following Protocol Buffers 9 format:

-
message BlockID {
-     uint64 blockHeight = 1;
-     bytes blockHash = 2;
-}
-
-message CompactBlock {
-    BlockID id = 1;
-    repeated CompactTx vtx = 3;
-}
-
-message CompactTx {
-    uint64 txIndex = 1;
-    bytes txHash = 2;
-
-    repeated CompactSpend spends = 3;
-    repeated CompactOutput outputs = 4;
-}
-
-message CompactSpend {
-    bytes nf = 1;
-}
-
-message CompactOutput {
-    bytes cmu = 1;
-    bytes epk = 2;
-    bytes ciphertext = 3;
-}
-

Encoding Details

-

blockHash, txHash, nf, cmu, and epk are encoded as specified in the Zcash Protocol Spec.

-

The output and spend descriptions are handled differently, as described in the following sections.

-
-

Output Compression

-

In the normal Zcash protocol, the output ciphertext consists of the AEAD-encrypted form of a note plaintext 5:

- - - - - - - - - - -
8-bit 0x0188-bit d64-bit v256-bit rseedmemo (512 bytes) + tag (16 bytes)
-

A recipient detects their transactions by trial-decrypting this ciphertext. On a full node that has the entire block chain, the primary cost is computational. For light clients however, there is an additional bandwidth cost: every ciphertext on the block chain must be received from the server (or network node) the light client is connected to. This results in a total of 580 bytes per output that must be streamed to the client (in addition to the 32-byte ephemeral public key).

-

However, we don't need all of that just to detect payments. The first 52 bytes of the ciphertext contain the contents and opening of the note commitment, which is all of the data needed to spend the note and to verify that the note is spendable. If we ignore the memo and the authentication tag, we're left with a 32-byte ephemeral public key, the 32-byte note commitment, and only the first 52 bytes of the ciphertext for each output needed to decrypt, verify, and spend a note. This totals to 116 bytes per output, for an 80% reduction in bandwidth use.

-

However, skipping the full ciphertext means that we can no longer calculate the authentication tag for the entire ciphertext and will need to do something else to validate the integrity of the decrypted note plaintext.

-

Since the note commitment is sent outside the ciphertext and is authenticated by the binding signature over the entire transaction, it serves as an adequate check on the validity of the decrypted plaintext (assuming you trust the entity assembling transactions). We therefore recalculate the note commitment from the decrypted plaintext. If the recalculated commitment matches the one in the output, we accept the note as valid and spendable.

-
-

Spend Compression

-

Recall that a full Sapling Spend description is 384 bytes long 6:

- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
BytesNameType
32cvchar[32]
32anchorchar[32]
32nullifierchar[32]
32rkchar[32]
192zkproofchar[192]
64spendAuthSigchar[64]
-

The only part necessary for detection is the nullifier, which allows a light client to detect when one of its own notes has been spent. This means we only need to take 32 bytes of each Spend, for a 90% improvement in bandwidth use.

-
-
-

Proxy operation

-

The proxy's purpose is to provide a scalable and bandwidth-efficient interface between a Zcash node and any number of light clients. It accomplishes this by parsing a blockwise stream of transactions from the node and converting them into the compact format described above.

-

The details of the API described below may differ from the implementation.

-

The proxy offers the following API to clients:

-
service CompactTxStreamer {
-    rpc GetLatestBlock(ChainSpec) returns (BlockID) {}
-    rpc GetBlock(BlockID) returns (CompactBlock) {}
-    rpc GetBlockRange(RangeFilter) returns (stream CompactBlock) {}
-    rpc GetTransaction(TxFilter) returns (FullTransaction) {}
-}
-
-// Remember that proto3 fields are all optional.
-
-// Someday we may want to specify e.g. a particular chain fork.
-message ChainSpec {}
-
-
-// A BlockID message contains identifiers to select a block: either a
-// height or a hash.
-message BlockID {
-    uint64 blockHeight = 1;
-    bytes blockHash = 2;
-}
-
-
-message RangeFilter {
-    BlockID start = 1;
-    BlockID end = 2;
-}
-
-// A TxFilter contains the information needed to identify a particular
-// transaction: either a block and an index, or a direct transaction hash.
-message TxFilter {
-    BlockID blockID = 1;
-    uint64 txIndex = 2;
-    bytes txHash = 3;
-}
-
-

Client operation

-

Light clients obtain compact blocks from one or more proxy servers, which they then process locally to update their view of the block chain. We consider only a single proxy server here without loss of generality.

-

Local processing

-

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 - \((\mathtt{cmu}, \mathtt{ephemeralKey}, \mathsf{ciphertext})\) - with an incoming viewing key - \(\mathsf{ivk}\) - is a slight deviation from the standard decryption process 4 (all constants and algorithms are as defined there):

-
    -
  • 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

-

As CompactBlocks are received in height order, and the transactions within them have their order preserved, the cmu values in each CompactOutput can be sequentially appended to an incremental Merkle tree of depth 32 in order to maintain a local copy of the Sapling note commitment tree. 2 This can then be used to create incremental witnesses for each unspent note the light client is tracking. 10 An incremental witness updated to height X corresponds to a Merkle path from the note to the Sapling commitment tree anchor for block X. 3

-

Let tree be the Sapling note commitment tree at height X-1, and note_witnesses be the incremental witnesses for unspent notes detected up to height X-1. When the CompactBlock at height X is received:

-
    -
  • For each CompactTx in CompactBlock: -
      -
    • For each CompactOutput (cmu, epk, ciphertext) in CompactBlock: -
        -
      • Append cmu to tree.
      • -
      • For witness in note_witnesses: -
          -
        • Append cmu to witness.
        • -
        -
      • -
      • If ciphertext contains a relevant note, create an incremental witness from tree and append it to note_witnesses.
      • -
      -
    • -
    -
  • -
-

Incremental Merkle trees cannot be rewound, so the light client should cache both the Sapling note commitment tree and per-note incremental witnesses for recent block heights. Cache management is implementation-dependent, but a cache size of 100 is reasonable, as no full Zcash node will roll back the chain by more than 100 blocks.

-
-

Detecting spends

-

The CompactSpend entries can be checked against known local nullifiers, to for example ensure that a transaction has been received by the network and mined.

-
-

Block header validation

-

This section describes a proposed enhancement that has been only partially implemented: currently only prevHash is checked.

-

If the CompactBlock for height X contains a block header, the light client can validate it in a similar way to SPV clients 11 by performing the following checks:

-
    -
  • version >= MIN_BLOCK_VERSION
  • -
  • prevHash == prevBlock.id.blockHash where prevBlock is the previous CompactBlock received (at height X-1).
  • -
  • finalSaplingRoot is equal to the root of the Sapling note commitment tree after appending every cmu in the CompactBlock in-order.
  • -
  • The Equihash solution is valid.
  • -
  • targetFromBits(bits) != 0 && targetFromBits(bits) <= powLimit.
  • -
  • If the last 27 CompactBlocks all have block headers, bits is set correctly according to the difficulty adjustment algorithm.
  • -
  • toLittleEndian(blockHash) <= targetFromBits(bits).
  • -
-

A CompactBlock that fails any of these checks MUST be discarded. If it was received as part of a GetBlockRange call, the call MUST be aborted.

-

Block header validation provides light clients with some assurance that the CompactOutputs being sent to them are indeed from valid blocks that have been mined. The strongest-possible assurance is achieved when all block headers are synchronised; this comes at the cost of bandwidth and storage.

-

By default, CompactBlocks only contain CompactTxs for transactions that contain Sapling spends or outputs. Thus they do not contain sufficient information to validate that the received transaction IDs correspond to the transaction tree root in the block header. This does not have a significant effect on light client security: light clients only directly depend on CompactOutputs, which can be authenticated via block header validation. If a txid is used in a GetTransaction call, the returned transaction SHOULD be checked against the corresponding CompactOutputs, in addition to verifying the transaction signatures.

-
-

Potential extensions

-

A trivial extension (with corresponding bandwidth cost) would be to transmit empty CompactTxs corresponding to transactions that do not contain Sapling spends or outputs. A more complex extension would send the inner nodes within the transaction trees corresponding to non-Sapling-relevant subtrees; this would require strictly less bandwidth that the trivial extension. These extensions are not currently defined.

-
-
-

Client-server interaction

-

We can divide the typical client-server interaction into four distinct phases:

-
Phase   Client                Server
-=====   ============================
-  A     GetLatestBlock ------------>
-
-        <---------------- BlockID(X)
-
-        GetBlock(X) --------------->
-
-        <----------- CompactBlock(X)
-
-            ===
-
-  B     GetLatestBlock ------------>
-
-        <---------------- BlockID(Y)
-
-        GetBlockRange(X, Y) ------->
-
-        <--------- CompactBlock(X)
-        <--------- CompactBlock(X+1)
-        <--------- CompactBlock(X+2)
-                        ...
-        <--------- CompactBlock(Y-1)
-        <--------- CompactBlock(Y)
-
-            ===
-
-  C     GetTransaction(X+4, 7) ---->
-
-        <--- FullTransaction(X+4, 7)
-
-        GetTransaction(X+9, 2) ---->
-
-        <--- FullTransaction(X+9, 2)
-
-            ===
-
-  D     GetLatestBlock ------------>
-
-        <---------------- BlockID(Z)
-
-        GetBlockRange(Y, Z) ------->
-
-        <--------- CompactBlock(Y)
-        <--------- CompactBlock(Y+1)
-        <--------- CompactBlock(Y+2)
-                        ...
-        <--------- CompactBlock(Z-1)
-        <--------- CompactBlock(Z)
-

Phase A: The light client starts up for the first time.

-
    -
  • The light client queries the server to fetch the most recent block X.
  • -
  • The light client queries the commitment tree state for block X. -
      -
    • Or, it has to set X to the block height at which Sapling activated, so as to be sent the entire commitment tree. [TODO: Decide which to specify.]
    • -
    -
  • -
  • Shielded addresses created by the light client will not have any relevant transactions in this or any prior block.
  • -
-

Phase B: The light client updates its local chain view for the first time.

-
    -
  • The light client queries the server to fetch the most recent block Y.
  • -
  • It then executes a block range query to fetch every block between X (inclusive) and Y (inclusive).
  • -
  • The block at height X is checked to ensure the received blockHash matches the light client's cached copy, and then discards it without further processing. -
      -
    • An inconsistency would imply that block X was orphaned during a chain reorg.
    • -
    -
  • -
  • As each subsequent CompactBlock arrives, the light client: -
      -
    • Validates the block header if it is present.
    • -
    • Scans the CompactBlock to find any relevant transactions for addresses generated since X was fetched (likely the first transactions involving those addresses). If notes are detected, it: -
        -
      • Generates incremental witnesses for the notes, and updates them going forward.
      • -
      • Scans for their nullifiers from that block onwards.
      • -
      -
    • -
    -
  • -
-

Phase C: The light client has detected some notes and displayed them. User interaction has indicated that the corresponding full transactions should be fetched.

-
    -
  • The light client queries the server for each transaction it wishes to fetch.
  • -
-

Phase D: The user has spent some notes. The light client updates its local chain view some time later.

-
    -
  • The light client queries the server to fetch the most recent block Z.
  • -
  • It then executes a block range query to fetch every block between Y (inclusive) and Z (inclusive).
  • -
  • The block at height Y is checked to ensure the received blockHash matches the light client's cached copy, and then discards it without further processing. -
      -
    • An inconsistency would imply that block Y was orphaned during a chain reorg.
    • -
    -
  • -
  • As each subsequent CompactBlock arrives, the light client: -
      -
    • Validates the block header if it is present.
    • -
    • Updates the incremental witnesses for known notes.
    • -
    • Scans for any known nullifiers. The corresponding notes are marked as spent at that height, and excluded from further witness updates.
    • -
    • Scans for any relevant transactions for addresses generated since Y was fetched. These are handled as in phase B.
    • -
    -
  • -
-

Importing a pre-existing seed

-

Phase A of the interaction assumes that shielded addresses created by the light client will have never been used before. This is not a valid assumption if the light client is being initialised with a seed that it did not generate (e.g. a previously backed-up seed). In this case, phase A is modified as follows:

-

Phase A: The light client starts up for the first time.

-
    -
  • The light client sets X to the block height at which Sapling activated. -
      -
    • Shielded addresses created by any light client cannot have any relevant transactions prior to Sapling activation.
    • -
    -
  • -
-
-
-

Block privacy via bucketing

-

This section describes a proposed enhancement that has not been implemented.

-

The above interaction reveals to the server at the start of each synchronisation phase (B and D) the block height which the light client had previously synchronised to. This is an information leak under our security model (assuming network privacy). We can reduce the information leakage by "bucketing" the start point of each synchronisation. Doing so also enables us to handle most chain reorgs simultaneously.

-

Let ⌊X⌋ = X - (X % N) be the value of X rounded down to some multiple of the bucket size N. The synchronisation phases from the above interaction are modified as follows:

-
Phase   Client                Server
-=====   ============================
-  B     GetLatestBlock ------------>
-
-        <---------------- BlockID(Y)
-
-        GetBlockRange(⌊X⌋, Y) ----->
-
-        <-------- CompactBlock(⌊X⌋)
-        <-------- CompactBlock(⌊X⌋+1)
-        <-------- CompactBlock(⌊X⌋+2)
-                        ...
-        <-------- CompactBlock(Y-1)
-        <-------- CompactBlock(Y)
-
-            ===
-
-  D     GetLatestBlock ------------>
-
-        <---------------- BlockID(Z)
-
-        GetBlockRange(⌊Y⌋, Z) ----->
-
-        <-------- CompactBlock(⌊Y⌋)
-        <-------- CompactBlock(⌊Y⌋+1)
-                        ...
-        <-------- CompactBlock(Z-1)
-        <-------- CompactBlock(Z)
-

Phase B: The light client updates its local chain view for the first time.

-
    -
  • The light client queries the server to fetch the most recent block Y.
  • -
  • It then executes a block range query to fetch every block between ⌊X⌋ (inclusive) and Y (inclusive).
  • -
  • Blocks between ⌊X⌋ and X are checked to ensure that the received blockHash matches the light client's chain view for each height, and are then discarded without further processing. -
      -
    • If an inconsistency is detected at height Q, the light client sets X = Q-1, discards all local blocks with height >= Q, and rolls back the state of all local transactions to height Q-1 (un-mining them as necessary).
    • -
    -
  • -
  • Blocks between X+1 and Y are processed as before.
  • -
-

Phase D: The user has spent some notes. The light client updates its local chain view some time later.

-
    -
  • The light client queries the server to fetch the most recent block Z.
  • -
  • It then executes a block range query to fetch every block between ⌊Y⌋ (inclusive) and Z (inclusive).
  • -
  • Blocks between ⌊Y⌋ and Y are checked to ensure that the received blockHash matches the light client's chain view for each height, and are then discarded without further processing. -
      -
    • If an inconsistency is detected at height R, the light client sets Y = R-1, discards all local blocks with height >= R, and rolls back the following local state to height R-1: -
        -
      • All local transactions (un-mining them as necessary).
      • -
      • All tracked nullifiers (unspending or discarding as necessary).
      • -
      • All incremental witnesses (caching strategies are not covered in this ZIP).
      • -
      -
    • -
    -
  • -
  • Blocks between Y+1 and Z are processed as before.
  • -
-
-

Transaction privacy

-

The synchronisation phases give the light client sufficient information to determine accurate address balances, show when funds were received or spent, and spend any unspent notes. As synchronisation happens via a broadcast medium, it leaks no information about which transactions the light client is interested in.

-

If, however, the light client needs access to other components of a transaction (such as the memo fields for received notes, or the outgoing ciphertexts in order to recover spend information when importing a wallet seed), it will need to download the full transaction. The light client SHOULD obscure the exact transactions of interest by downloading numerous uninteresting transactions as well, and SHOULD download all transactions in any block from which a single full transaction is fetched (interesting or otherwise). It MUST convey to the user that fetching full transactions will reduce their privacy.

-
-
-

Reference Implementation

-

This proposal is supported by a set of libraries and reference code made available by the Electric Coin Company.

-
-

References

- - - - - - - -
1Information 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"
- - - - - - - -
2Zcash Protocol Specification, Version 2020.1.15. Section 3.7: Note Commitment Trees
- - - - - - - -
3Zcash Protocol Specification, Version 2020.1.15. Section 4.8: Merkle Path Validity
- - - - - - - -
4Zcash Protocol Specification, Version 2020.1.15. Section 4.17.2: Decryption using an Incoming Viewing Key (Sapling)
- - - - - - - -
5Zcash Protocol Specification, Version 2020.1.15. Section 5.5: Encodings of Note Plaintexts and Memo Fields
- - - - - - - -
6Zcash Protocol Specification, Version 2020.1.15. Section 7.3: Encoding of Spend Descriptions
- - - - - - - -
7Zcash Protocol Specification, Version 2020.1.15. Section 7.4: Encoding of Output Descriptions
- - - - - - - -
8ZIP 212: Allow Recipient to Derive Sapling Ephemeral Secret from Note Plaintext
- - - - - - - -
9Protocol Buffers documentation
- - - - - - - -
10zcash_primitives Rust crate — merkle_tree.rs
- - - - - - - -
11Bitcoin Wiki: Scalability — Simplified payment verification
-
-
- - \ No newline at end of file diff --git a/rendered/zip-0308.html b/rendered/zip-0308.html deleted file mode 100644 index 6afcc473a..000000000 --- a/rendered/zip-0308.html +++ /dev/null @@ -1,284 +0,0 @@ - - - - ZIP 308: Sprout to Sapling Migration - - - -
-
ZIP: 308
-Title: Sprout to Sapling Migration
-Owners: Daira-Emma Hopwood <daira-emma@electriccoin.co>
-Original-Authors: Daira-Emma Hopwood
-                  Eirik Ogilvie-Wigley
-Status: Final
-Category: Standards / RPC / Wallet
-Created: 2018-11-27
-License: MIT
-

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 terms below are to be interpreted as follows:

-
-
Sprout protocol
-
Code-name for the Zcash shielded protocol at launch.
-
Sapling protocol
-
Code-name for the Zcash shielded protocol added by the second Zcash network upgrade, also known as Network Upgrade 1.
-
-
-

Abstract

-

This proposal describes privacy-preserving procedures to migrate funds from Sprout to Sapling z-addresses; and supporting RPC operations to enable, disable, and monitor the migration process.

-
-

Motivation

-

Zcash Sapling 4 introduces significant efficiency improvements relative to the previous iteration of the Zcash shielded protocol, Sprout. These improvements will pave the way for broad mobile, exchange and vendor adoption of shielded addresses.

-

Therefore, we anticipate that users will want to migrate all their shielded funds from Sprout to Sapling.

-

The Zcash consensus rules prohibit direct transfers from Sprout to Sapling z-addresses, unless the amount is revealed by sending it through the "transparent value pool" 2. The primary motivation for this is to allow detection of any overall inflation of the Zcash monetary base, due to exploitation of possible vulnerabilities in the shielded protocols or their implementation, or a compromise of the Sprout multi-party computation. (It is not necessary for Sprout -> Sapling transfers to go via a t-address.)

-

Since the exposure of the migrated amount potentially compromises the privacy of users, we wish to define a way to perform the migration that mitigates this privacy leak as far as possible. This can be done by hiding individual migration transactions among those of all users that are doing the migration at around the same time.

-

The security analysis of migration strategies is quite subtle; the more obvious potential strategies can leak a lot of information.

-
-

Requirements

-

Migration is performed "in the background" by a zcashd (or equivalent) node. It does not significantly interfere with concurrent usage of the node, other than possibly increasing the latency of some other shielded operations.

-

It is possible to enable or disable migration at any time.

-

All shielded funds in Sprout z-addresses will eventually be transferred to Sapling z-addresses, provided the node is working.

-

It should take a "reasonable" length of time to complete the transfer; less than a month for amounts up to 1000 ZEC.

-

The design should mitigate information leakage via timing information and transaction data, including

-
    -
  • linkage of particular z-addresses or users, and the amounts held;
  • -
  • information about the distribution of amounts of individual notes.
  • -
-

The design and implementation is stateless, to the extent practical.

-

Visibility is provided for the wallet/node user into the progress of the migration.

-

There is sufficient information available to debug failed transactions that are part of the migration.

-

The design recovers from failed operations to the extent possible.

-

The total amount sent by each user is obscured, to the extent practical.

-
-

Non-requirements

-

There is no requirement or assumption of network layer anonymity. (Users may, but are not expected to, configure Tor.)

-

The migration procedure does not have to provably leak no information.

-

There is no need to preserve individual note values (i.e. notes can be consolidated).

-

Migration txns need only be hidden among themselves, rather than among all kinds of transaction.

-

A small amount (less than 0.01 ZEC) can be left unmigrated if this helps with privacy.

-

It is not required to support the case of single wallet being used by multiple users whose funds should be kept distinct.

-
-

Specification

-

There are two main aspects to a strategy for selecting migration transactions:

-
    -
  • how many transactions are sent, and when;
  • -
  • the amount sent in each transaction.
  • -
-

Transaction schedule

-

When migration is enabled, a node will send up to 5 transactions for inclusion in each block with height a multiple of 500 (that is, they are sent immediately after seeing a block with height 499, modulo 500). Up to the limit of 5, as many transactions are sent as are needed to migrate the remaining funds (possibly with a remainder less than 0.01 ZEC left unmigrated).

-

Nodes SHOULD NOT send migration transactions during initial block download, or if the timestamp of the triggering block (with height 499, modulo 500) is more than three hours in the past according to the node's adjusted local clock.

-

Note: the 500-block interval has not been altered as a result of the halving of target block spacing to 75 seconds with the Blossom upgrade. 5

-

The migration transactions to be sent in a particular batch can take significant time to generate, and this time depends on the speed of the user's computer. If they were generated only after a block is seen at the target height minus 1, then this could leak information. Therefore, for target height N, implementations SHOULD start generating the transactions at around height N-5 (provided that block's timestamp is not more than three hours in the past). Each migration transaction SHOULD specify an anchor at height N-10 for each Sprout JoinSplit description (and therefore only notes created before this anchor are eligible for migration).

-

Open questions:

-
    -
  • does this reliably give sufficient time to generate the transactions?
  • -
  • what happens to a batch if the anchor is invalidated -- should it be regenerated, or cancelled?
  • -
-

Rationale for transaction schedule

-
-Click to show/hide -

Privacy is increased when the times at which to send transactions are coordinated between nodes. We choose to send a batch of transactions at each coordinated time. Sending multiple transactions in each batch ensures that:

-
    -
  • less information about balances is leaked;
  • -
  • it is easier to finish in a reasonable length of time.
  • -
-

The choice of 500 blocks as the batch interval ensures that each batch occurs at a different time of day (both before and after the Blossom upgrade), which may help to mitigate problems with the availability of nodes being correlated with the local time-of-day.

-

Simulation shows that the migration process will typically complete reasonably quickly even if the amount to be migrated is large:

- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
AmountTime in days to complete migration
10th-percentilemedian90th-percentile
1 ZEC1.001.461.72
10 ZEC1.431.952.48
100 ZEC1.932.693.60
1000 ZEC5.666.958.47
10000 ZEC45.3149.1653.24
-

(The estimated times for larger amounts halved as a result of the target block spacing change in Blossom.)

-

The simulation also depends on the amounts sent as specified in the next section. It includes the time spent waiting for the first batch to be sent.

-

The code used for this simulation is at 6.

-
-
-

How much to send in each transaction

-

If the remaining amount to be migrated is less than 0.01 ZEC, end the migration.

-

Otherwise, the amount to send in each transaction is chosen according to the following distribution:

-
    -
  1. Choose an integer exponent uniformly in the range 6 to 8 inclusive.
  2. -
  3. Choose an integer mantissa uniformly in the range 1 to 99 inclusive.
  4. -
  5. Calculate amount := (mantissa * 10exponent) zatoshi.
  6. -
  7. If amount is greater than the amount remaining to send, repeat from step 1.
  8. -
-

Implementations MAY optimize this procedure by selecting the exponent and mantissa based on the amount remaining to avoid repetition, but the resulting distribution MUST be identical.

-

The amount chosen includes the 0.0001 ZEC fee for this transaction, i.e. the value of the Sapling output will be 0.0001 ZEC less.

-

Rationale for how much to send

-
-Click to show/hide -

Suppose that a user has an amount to migrate that is a round number of ZEC. Then, a potential attack would be to find some subset of all the migration transactions that sum to a round number of ZEC, and infer that all of those transactions are from the same user. If amounts sent were a random multiple of 1 zatoshi, then the resulting knapsack problem would be likely to have a unique solution and be practically solvable for the number of transactions involved. The chosen distribution of transaction amounts mitigates this potential vulnerability by ensuring that there will be many solutions for sets of transactions, including "incorrect" solutions (that is, solutions that mix transactions from different users, contrary to the supposed adversary's inference).

-

Making the chosen amount inclusive of the fee avoids leaving any unmigrated funds at the end, in the case where the original amount to migrate was a multiple of 0.01 ZEC.

-
-
-

Other design decisions

-

We assume use of the normal wallet note selection algorithm and change handling. Change is sent back to the default address, which is the z-address of the first selected Sprout note. The number of JoinSplits will therefore be the same as for a normal transaction sending the same amount with the same wallet state. Only the vpub_new of the last JoinSplit will be nonzero. There will always be exactly one Sapling Output.

-

The expiry delta for migration transactions MUST be 450 blocks. Since these transactions are sent when the block height is 499 modulo 500, their expiry height will be 451 blocks later, i.e. nExpiryHeight will be 450 modulo 500.

-

The fee for each migration transaction MUST be 0.0001 ZEC. This fee is taken from the funds to be migrated.

-

Some wallets by default add a "developer fee" to each transaction, directed to the developer(s) of the wallet. This is typically implemented by adding the developer address as an explicit output, so if migration transactions are generated internally by zcashd, they will not include the developer fee. We strongly recommend not patching the zcashd code to add the developer fee output to migration transactions, because doing so partitions the anonymity set between users of that wallet and other users.

-

There MUST NOT be any transparent inputs or outputs, or Sapling Spends, in a migration transaction.

-

The lock_time field MUST be set to 0 (unused).

-

When creating Sapling shielded Outputs, the outgoing viewing key ovk SHOULD be chosen in the same way as for a transfer sent from a t-address.

-

A node SHOULD treat migration transactions in the same way as transactions submitted over the RPC interface.

-
-

Open questions

-

The above strategy has several "magic number" parameters:

-
    -
  • the interval between batches (500 blocks)
  • -
  • the maximum number of transactions in a batch (5)
  • -
  • the distribution of exponents (uniform integer in 6..8)
  • -
  • the distribution of mantissae (uniform integer in 1..99).
  • -
-

These have been chosen by guesswork. Should we change any of them?

-

In particular, if the amount to migrate is large, then this strategy can result in fairly large amounts (up to 99 ZEC, worth USD ~6700 at time of writing) transferred in each transaction. This leaks the fact that the transaction was sent by a user who has at least that amount.

-

The strategy does not migrate any remaining fractional amount less than 0.01 ZEC (worth USD ~0.68 at time of writing). Is this reasonable?

-

In deciding the amount to send in each transaction, the strategy does not take account of the values of individual Sprout notes, only the total amount remaining to migrate. Can a strategy that is sensitive to individual note values improve privacy?

-

An adversary may attempt to interfere with the view of the block chain seen by a subset of nodes that are performing migrations, in order to cause those nodes to send migration batches at a different time, so that they may be distinguished. Is there anything further we can do to mitigate this vulnerability?

-
-

RPC calls

-

Nodes MUST maintain a boolean state variable during their execution, to determine whether migration is enabled. The default when a node starts, is set by a configuration option:

-
-migration=0/1
-

The destination z-address can optionally be set by another option:

-
-migrationdestaddress=<zaddr>
-

If this option is not present then the migration destination address is the address for Sapling account 0, with the default diversifier 3.

-

The state variable can also be set for a running node using the following RPC method:

-
z_setmigration true/false
-

It is intentional that the only option associated with the migration is the destination z-address. Other options could potentially distinguish users.

-

Nodes MUST also support the following RPC call to return the current status of the migration:

-
z_getmigrationstatus
-

Returns:

-
{
-  "enabled": true|false,
-  "destination_address": "zaddr",
-  "unmigrated_amount": nnn.n,
-  "unfinalized_migrated_amount": nnn.n,
-  "finalized_migrated_amount": nnn.n,
-  "finalized_migration_transactions": nnn,
-  "time_started": ttt, // Unix timestamp
-  "migration_txids": [txids]
-}
-

The destination_address field MAY be omitted if the -migrationaddress parameter is not set and no default address has yet been generated.

-

The values of unmigrated_amount and migrated_amount MUST take into account failed transactions, that were not mined within their expiration height.

-

The values of unfinalized_migrated_amount and finalized_migrated_amount are the total amounts sent to the Sapling destination address in migration transactions, excluding fees.

-

migration_txids is a list of strings representing transaction IDs of all known migration transactions involving this wallet, as lowercase hexadecimal in RPC byte order. A given transaction is defined as a migration transaction iff it has:

-
    -
  • one or more Sprout JoinSplits with nonzero vpub_new field; and
  • -
  • no Sapling Spends, and;
  • -
  • one or more Sapling Outputs.
  • -
-

Note: it is possible that manually created transactions involving this wallet will be recognized as migration transactions and included in migration_txids.

-

The value of time_started is the earliest Unix timestamp of any known migration transaction involving this wallet; if there is no such transaction, then the field is absent.

-

A transaction is finalized iff it has at least 10 confirmations. TODO: subject to change, if the recommended number of confirmations changes.

-
-
-

Support in zcashd

-

The following PRs implement this specification:

- -
-

References

- - - - - - - -
1Information 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"
- - - - - - - -
2Zcash Protocol Specification, Version 2020.1.15. Sections 3.4, 4.11 and 4.12
- - - - - - - -
3ZIP 32: Shielded Hierarchical Deterministic Wallets
- - - - - - - -
4ZIP 205: Deployment of the Sapling Network Upgrade
- - - - - - - -
5ZIP 208: Shorter Block Target Spacing
- - - - - - - -
6Sprout -> Sapling migration simulation
-
-
- - \ No newline at end of file diff --git a/rendered/zip-0309.html b/rendered/zip-0309.html deleted file mode 100644 index a35caf6ad..000000000 --- a/rendered/zip-0309.html +++ /dev/null @@ -1,22 +0,0 @@ - - - - ZIP 309: Blind Off-chain Lightweight Transactions (BOLT) - - - -
-
ZIP: 309
-Title: Blind Off-chain Lightweight Transactions (BOLT)
-Owners: J. Ayo Akinyele <ayo@boltlabs.io>
-        Colleen Swanson <swan@boltlabs.io>
-Credits: Ian Miers
-         Matthew Green
-Status: Reserved
-Category: Standards / Ecosystem
-Created: 2019-07-15
-Discussions-To: <https://github.com/zcash/zcash/issues/2353>
-Pull-Request: <https://github.com/zcash/zips/pull/216>
-
- - \ No newline at end of file diff --git a/rendered/zip-0310.html b/rendered/zip-0310.html deleted file mode 100644 index 0c9c2b30e..000000000 --- a/rendered/zip-0310.html +++ /dev/null @@ -1,185 +0,0 @@ - - - - ZIP 310: Security Properties of Sapling Viewing Keys - - - -
-
ZIP: 310
-Title: Security Properties of Sapling Viewing Keys
-Owners: Daira-Emma Hopwood <daira-emma@electriccoin.co>
-        Jack Grigg <jack@electriccoin.co>
-Status: Draft
-Category: Informational
-Created: 2020-03-09
-License: MIT
-

Terminology

-
-
Sapling FVK
-
A Sapling full viewing key as described in 1, or a Sapling extended full viewing key as described in 3.
-
GUARANTEED
-
Information that can be learned by the holder of a Sapling FVK, and ensured to be correct by the Sapling protocol, given the cryptographic assumptions underlying that protocol.
-
UNVERIFIED
-
Information that can be learned by the holder of a Sapling FVK, but that is not guaranteed to be correct.
-
UNDEFINED
-
The Sapling protocol does not define whether or not this information is accessible.
-
UNREVEALED
-
Information that is not revealed as a consequence of holding a Sapling FVK.
-
-
-

Abstract

-

This ZIP documents what information an entity learns when they are given one or more Sapling viewing keys, and what guarantees they have about this information.

-
-

Motivation

-

Shielded addresses allow for network participants to send and receive while revealing as little information on the public block chain as possible. However, there are circumstances in which it is desirable to explicitly reveal some of this information to a third party, such as during auditing or for splitting authority between multiple parties or devices.

-

It is important that a party that is relying on the information made visible by a viewing key, understands what that information conveys and what assumptions they can make when relying on it.

-
-

Security Properties

-

Alice has a spending key that she has been using for receiving and sending ZEC. She generates a Sapling FVK and gives it to Ian. What can Ian learn with the Sapling FVK, and what guarantees does he have about the things he learns? (Note for below: IVK and OVK are derived from FVK.)

-

If Ian is given some diversified payment address:

-
    -
  • [GUARANTEED] He can determine whether the IVK derived from FVK corresponds to the address.
  • -
  • [UNVERIFIED] He cannot reliably determine whether the OVK derived from FVK corresponds to the address. -
      -
    • That is, Ian could have been given an alleged FVK that is “correct” for a particular address, but with an arbitrary OVK that corresponds to some other address, or no address, or a well-known OVK (e.g. all-zeros which is used for funding streams / coinbase outputs).
    • -
    -
  • -
-

If Ian is given two diversified payment addresses:

-
    -
  • [GUARANTEED] He can determine whether or not both of these addresses are linked to the given FVK, and if so, that they are linked to each other.
  • -
-

What Ian learns about a single transaction

-

If Ian detects a new transaction (defined as a transaction that Ian had no prior knowledge about) solely by decrypting one of its Output descriptions with Alice’s IVK, then he learns:

-
    -
  • [GUARANTEED] Whether Alice is a recipient of the payment (by verifying the note commitment against the encrypted contents). -
      -
    • [GUARANTEED] If so, to which of Alice’s diversified payment addresses the payment was sent.
    • -
    • [UNDEFINED] Whether Alice is an explicit recipient, or just receiving change or making a movement between “accounts” (the protocol does not distinguish between Bob sending Alice funds, and Alice moving funds between different addresses).
    • -
    -
  • -
  • [GUARANTEED] A new, unspent note that Alice is able to spend.
  • -
  • [GUARANTEED] The nullifier with which to detect the new note being spent, once this transaction is mined in a block. -
      -
    • This is a way in which Sapling viewing keys differ from Sprout; you do not learn this information for Sprout viewing keys.
    • -
    -
  • -
  • [UNVERIFIED] The memo field contents, which might identify the sender. -
      -
    • If the memo contained explicit sender authentication / proof-of-spending-key, then Ian gains a guarantee; FVK does not require this.
    • -
    -
  • -
-

If Ian detects a new transaction by observing a nullifier for one of Alice’s unspent known notes, then he learns:

-
    -
  • [GUARANTEED] Alice is a sender.
  • -
  • [GUARANTEED] Whether Alice is the sole sender, or has collaborated to create the transaction (if there are other Spend descriptions with unknown nullifiers).
  • -
  • [UNREVEALED] The identities of the other senders (as in this context Ian only has Alice’s FVK).
  • -
  • [UNDEFINED] The recipient(s). -
      -
    • Nothing in the transaction enforces that outputs are encrypted to either the address of the note that is committed to, or any value known to the sender.
    • -
    -
  • -
  • [UNDEFINED] Whether Alice receives any funds in the transaction. -
      -
    • The protocol does not distinguish between Alice sending all funds to a third party, and moving funds to a different address that she controls.
    • -
    -
  • -
-

If Ian can decrypt an output in the same transaction with Alice’s IVK, then he additionally learns:

-
    -
  • [GUARANTEED] Alice receives change from the transaction (by the definition that “change” is funds that you receive in a transaction where you also spend funds).
  • -
-

If Ian can decrypt an output in the same transaction with Alice’s OVK (which he will be able to do if Alice follows standard protocol), then he additionally learns:

-
    -
  • [GUARANTEED] The recipient’s diversified payment address (by verifying the note commitment).
  • -
  • [GUARANTEED] The amount sent to the recipient.
  • -
  • [GUARANTEED] The memo that the recipient will receive by decrypting the output.
  • -
  • [UNREVEALED] The nullifier with which the recipient would spend the note (as Ian does not have the recipient’s FVK).
  • -
-

If Ian detects a new transaction solely by decrypting one of its Output descriptions with Alice’s OVK (and not via any of the nullifiers in its Spend descriptions), then he learns:

-
    -
  • [GUARANTEED] The sender had knowledge of Alice’s OVK (negligible probability of random chance, as OVK is 256 bits).
  • -
  • [UNVERIFIED] Alice might be the sender.
  • -
  • [UNVERIFIED] This is a non-standard transaction. There may be a bug in the wallet generating transactions, or the transaction might be generated as an out-of-band transaction. -
      -
    • The behaviour of the zcashd wallet is to use the OVK corresponding to the first address (i.e. first call to the transaction builder) being spent from.
    • -
    -
  • -
-
-

What Ian learns about balances

-

This section concerns what Ian learns contextually across multiple transactions.

-

We define a “tally” to be the abstraction of balance corresponding to an FVK. This corresponds to exactly one expanded spending key. (Balances cannot accurately be modelled as being associated with a diversified address, since there are multiple diversified addresses associated with an FVK.)

-

The balance of a tally after a particular block is defined as the sum of note values that are spendable, according to the Sapling protocol, using the extended spending key associated with the tally, in a block chain that extends from that block.

-

Ian can attempt to keep track of a given tally’s balance as of a given block. This would be done as follows:

-
    -
  • Scan the chain from Sapling activation up to and including the specified block, collecting all of the Sapling spends and Sapling outputs up to and including that block that are relevant to the FVK, as specified in section 4.19 of the Protocol Specification 2. This produces a ReceivedSet of notes that were received by that tally, and a SpentSet of notes that were spent from it.
  • -
  • Compute the balance as the sum of the values of all notes appearing in ReceivedSet but not in SpentSet.
  • -
-

The following inaccuracies may occur in balance accounting:

-
    -
  • An incoming payment to the tally may not be detected, if the sender transmitted it and the recipient accepted it “out of band”, without following the Sapling protocol.
  • -
  • If an incoming payment is not detected for the above reason, and the note is later spent, then that spend will also not be detected by the process in section 4.19.
  • -
-

The combination of the above inaccuracies can cause a tally’s computed balance to be lower than its actual balance. They cannot cause a tally’s computed balance to be higher than its actual balance. That is:

-
    -
  • [GUARANTEED] Ian learns a lower bound on the balance of the tally.
  • -
  • [UNVERIFIED] If Alice followed the Sapling protocol when receiving funds to addresses associated with the tally, then Ian learns the exact balance of the tally.
  • -
-

It should be noted that since “out-of-band” payments require cooperation between the sender and recipient in not following the Sapling protocol, the sender and recipient could instead have agreed to use a different tally.

-
-

What Ian learns about the ecosystem

-

Assume Ian now has access to a set S of FVKs. Without loss of generality we will treat these as belonging to independent entities.

-

Ian runs the transaction and balance scanning protocols described in previous sections, in parallel for all FVKs in S.

-

In addition to information learned from each individual FVK, Ian can infer:

-
    -
  • [GUARANTEED] When any member of the set sends funds to any other member of the set via any standard transaction. -
      -
    • [UNDEFINED] Ian may not learn about out-of-band transactions, but this has a similar effect to transactions between entities with FVKs not in the set.
    • -
    -
  • -
  • [GUARANTEED] Any common recipients (with payment addresses that are not controlled by any members of the set) that have received funds from two or more members of the set via standard transactions. -
      -
    • [UNVERIFIED] Any common recipients that have received funds from two or more members of the set via non-standard transactions where OVKs from the set members were used to encrypt recipient outputs.
    • -
    • [UNDEFINED] Ian might not see the full set of common recipients, if members of the set cooperate with recipients to create out-of-band transactions.
    • -
    -
  • -
  • [GUARANTEED] Any subsets of set members that cooperatively spend funds (for which Ian has knowledge of the individual spends) within the same transaction. -
      -
    • [UNDEFINED] Ian may learn about cooperative spends involving members of the set by detecting the use of multiple OVKs from set members within a single transaction, even if the transactions are not made according to the Sapling protocol.
    • -
    -
  • -
-
-
-

References

- - - - - - - -
1Zcash Protocol Specification, Version 2020.1.15 or later
- - - - - - - -
2Zcash Protocol Specification, Version 2020.1.15. Section 4.19: Block Chain Scanning (Sapling)
- - - - - - - -
3ZIP 32: Shielded Hierarchical Deterministic Wallets
-
-
- - \ No newline at end of file diff --git a/rendered/zip-0311.html b/rendered/zip-0311.html deleted file mode 100644 index cfec0a94b..000000000 --- a/rendered/zip-0311.html +++ /dev/null @@ -1,637 +0,0 @@ - - - - ZIP 311: Zcash Payment Disclosures - - - - -
-
ZIP: 311
-Title: Zcash Payment Disclosures
-Owners: Jack Grigg <jack@electriccoin.co>
-Status: Draft
-Category: Standards / RPC / Wallet
-Discussions-To: <https://github.com/zcash/zips/issues/387>
-

Abstract

-

This ZIP describes a mechanism and format for disclosing information about shielded spends and outputs within a transaction. In the typical case, this means enabling a sender to present a proof that they transferred funds to a recipient's shielded address.

-
-

Motivation

-

There are various situations where a proof-of-payment may be desired. For example:

-
    -
  • A sender may need to prove that their payment was sent to a recipient, and available to be received (following the Zcash protocol in-band).
  • -
  • A third party may need to verify that a payment between a given sender and recipient was executed successfully.
  • -
-

When a transaction involves only transparent addresses, proof-of-payment is simple: The sender provides the transaction ID, and the recipient examines the blockchain to confirm that the transaction was mined. A third party can also perform this verification if they know the transparent addresses of the involved parties.

-

However, if the transaction involves shielded addresses, the blockchain by itself does not contain enough information to allow a record of the payment to be reconstructed and verified:

- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
SourceDestinationSenderRecipientAmountPayment dislosure?
TransparentTransparent🔍🔍🔍Not required
TransparentShielded🔍🔐🔐*Required
ShieldedTransparent🔒🔍🔍Required
ShieldedShielded🔒🔐🔐Required
-
    -
  • 🔍 = Visible on the block chain.
  • -
  • 🔐 = Cannot be confirmed without information that is not visible on the block chain.
  • -
  • 🔐* = Information is revealed, but not enough to confirm the amount paid (due to change).
  • -
  • 🔒 = Requires either an interactive payment disclosure, or a non-interactive payment disclosure that reveals the sender's address.
  • -
-

Enabling proof-of-payment for all of these transaction variants (where it is possible to do so) is the subject of this ZIP.

-
-

Use cases

-

Managing contributions for an event

-

Alice runs an event on behalf of Bob and Carol, who both agree to split the cost equally. Alice receives a single payment for half the amount, and wants proof of who it came from (so she knows which person to follow up with for the remaining amount). Carol can provide a payment disclosure that reveals to Alice:

-
    -
  • The correct amount was sent to the Alice's recipient address in the given transaction.
  • -
  • Carol was the sender of that transaction (more precisely, Carol controls the spend authority used in that transaction).
  • -
-

and does not reveal:

-
    -
  • Carol's payment address.
  • -
  • Any of Carol's other diversified payment addresses.
  • -
  • Any of Carol's other transactions.
  • -
-

For this use case, it is not necessary (and not necessarily intended) that the payment disclosure be publically verifiable.

-
-

Donation drive

-

Diana is a well-known individual with a public shielded payment address (for receiving donations). She runs a matching donation drive to the non-profit Totally Legit Bunnies, and wants to prove to her followers that she correctly matched their donations. Diana can create a payment disclosure, and post it to her social media account, that reveals:

-
    -
  • The correct amount was sent to the Totally Legit Bunnies' recipient address in the given transaction.
  • -
  • The sender of the transaction is the payment address that is associated with Diana.
  • -
-

and does not reveal:

-
    -
  • Any of Diana's other diversified payment addresses.
  • -
  • Any of Diana's other transactions.
  • -
-
-

Merchant dispute

-

Edward goes to CarsRFast to buy a Lamborghini, and sends funds from his shielded address to CarsRFast's transparent address. They can see a payment has been made, but claim that they have not received a payment from Edward. He can create a payment disclosure that reveals:

-
    -
  • Edward was the sender of the given transaction.
  • -
-

and does not reveal:

-
    -
  • Edward's payment address.
  • -
  • Any of Edward's other diversified payment addresses.
  • -
  • Any of Edward's other transactions.
  • -
-
-

Shielded withdrawals from an exchange

-

CorpBux is an exchange with a transparent hot wallet, and enables customers to withdraw their funds to shielded addresses. They can create a payment disclosure, that they can give to their customers, that reveals:

-
    -
  • The correct amount was sent to the customer's shielded recipient address in the given transaction.
  • -
  • CorpBux was the sender of the given transaction.
  • -
-
-
-

Requirements

-
    -
  • The payment disclosure may disclose the contents of zero or more shielded outputs within a single transaction. (Zero outputs is useful for z2t transactions.)
  • -
  • Payment disclosures can only be created by a sender of the transaction, and are non-malleable (that is, no-one else can take one or more payment disclosures and construct a new one that they would not have been able to make independently).
  • -
  • A payment disclosure may be tied to a challenge, creating an interactive proof.
  • -
  • Senders with a shielded address may choose to provably reveal that address as part of the payment disclosure.
  • -
  • Senders are not required to remember any ephemeral data from the creation of a transaction in order to produce a payment disclosure for that transaction. (Performance may be improved if they do cache witness data for spent notes.)
  • -
  • The payment disclosure can be created without requiring another trusted setup.
  • -
-
-

Conventions

-

The following functions used in this ZIP are defined in the Zcash protocol specification: 3

-
    -
  • - \(\mathsf{DiversifyHash}(\mathsf{d})\) - 7
  • -
  • - \(\mathsf{SpendAuthSig.RandomizePrivate}(α, \mathsf{sk})\) - , - \(\mathsf{SpendAuthSig.Sign}(\mathsf{sk}, m)\) - , and - \(\mathsf{SpendAuthSig.Verify}(\mathsf{vk}, m, σ)\) - 8
  • -
-

We reproduce some notation and functions from 3 here for convenience:

-
    -
  • - \([k] P\) - means scalar multiplication of the elliptic curve point - \(P\) - by the scalar - \(k\) - .
  • -
  • - \(\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\) - .
  • -
-

We also define the following notation here:

-
    -
  • - \([a..b]\) - means the sequence of values inclusive of - \(a\) - and exclusive of - \(b\) - .
  • -
  • - \(\mathsf{length}(a)\) - means the length of the sequence - \(a\) - .
  • -
-
-

Specification

-

Payment disclosure data structure

-

A payment disclosure has the following fields:

-
    -
  • txid: Transaction id for the transaction tx being disclosed.
  • -
  • msg: A message field, which could contain a challenge value from the party to whom the payment disclosure is directed.
  • -
  • - \(\mathsf{transparentInputs}\) - : A sequence of the transparent inputs for which we are proving spend authority - \([0..\mathsf{length}(\mathsf{tx.vin})]\) -
      -
    • - \(\mathsf{index}\) - : An index into - \(\mathsf{tx.vin}\) - .
    • -
    • - \(\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.
      • -
      • TODO: BIP 322 specifies consensus rule checks as part of the signature verification 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).
      • -
      -
    • -
    -
  • -
  • - \(\mathsf{saplingSpends}\) - : A sequence of the Sapling Spends for which we are proving spend authority - \([0..\mathsf{length}(\mathsf{tx.shieldedSpends})]\) -
      -
    • - \(\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 - \((\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. 11
      • -
      • - \(\mathsf{zkproof_{addr}}\) - : A Sapling spend proof.
      • -
      -
    • -
    • - \(\mathsf{spendAuthSig}\) -
    • -
    -
  • -
  • - \(\mathsf{saplingOutputs}\) - : A sequence of the Sapling Outputs that we are disclosing - \([0..\mathsf{length}(\mathsf{tx.shieldedOutputs})]\) -
      -
    • - \(\mathsf{index}\) - : An index into - \(\mathsf{tx.shieldedOutputs}\) - .
    • -
    • - \(\mathsf{ock}\) - : The outgoing cipher key that allows this output to be recovered. 5
    • -
    -
  • -
-

TODO: Add support for Orchard.

-

TODO: Decide on payment disclosure versioning.

-

TODO: Define encodings for unsigned and signed payment disclosures.

-
-

Creating a payment disclosure

-

The inputs to a payment disclosure are:

-
    -
  • The transaction.
  • -
  • The SLIP-44 10 coin type.
  • -
  • 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 - \((\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: -
      -
    • - \(\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 or a transparent input tuple).

-

The payment disclosure is created as follows:

-
    -
  • For each Sapling spend index: -
      -
    • Create a Sapling spend proof for the note that was spent in - \(\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, 11 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: -
      -
    • TODO: Prepare BIP 322 signature inputs using msg as the message_data.
    • -
    -
  • -
  • 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\) - .
  • -
  • For each Sapling spend index: -
      -
    • Let - \(\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)\) - .
    • -
    • Let - \(spendAuthSig = \mathsf{SpendAuthSig.Sign}(\mathsf{rsk}, digest)\) - .
    • -
    -
  • -
  • For each transparent input index: -
      -
    • TODO: Create a BIP 322 signature using msg as the message_data.
    • -
    -
  • -
  • Return the payment disclosure as the combination of the unsigned payment disclosure and the set of spendAuthSig and transparent signature values.
  • -
-
-

Verifying a payment disclosure

-

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: -
      -
    • - \(\mathsf{pd.txid} = \mathsf{tx.txid}()\) -
    • -
    • Sequence length correctness: -
        -
      • - \(\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 - \(\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 - \(\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})\) -
      • -
      -
    • -
    • - \(\mathsf{length}(\mathsf{pd.saplingSpends}) + \mathsf{length}(\mathsf{pd.transparentInputs}) > 0\) -
    • -
    -
  • -
  • Let - \(unsignedPaymentDisclosure\) - be the encoding of the payment disclosure without signatures.
  • -
  • 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{"ZIP311Signed"}\,||\,coinType, unsignedPaymentDisclosure)\) - .
  • -
  • For every - \(\mathsf{spend}\) - in - \(\mathsf{pd.saplingSpends}\) - : -
      -
    • If - \(\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}\) - , 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})\) - 11. If verification fails, return false.
    • -
    • Decode and verify - \(\mathsf{zkproof_{spend}}\) - as a Sapling spend proof 4 with primary input: -
        -
      • - \(\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 - \(\mathsf{input}\) - in - \(\mathsf{pd.transparentInputs}\) - : -
      -
    • TODO: BIP 322 verification.
    • -
    -
  • -
  • For every - \(\mathsf{output}\) - in - \(\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})\) - . If recovery returns - \(\bot\) - , return false.
    • -
    -
  • -
  • Return true.
  • -
-
-

Payment disclosure validity in UIs

-

TODO: Set some standards for how UIs should display payment disclosures, and how they should convey the various kinds of validity information:

-
    -
  • One, but not all, of the spenders proved spend authority.
  • -
  • All spenders of a specific type proved spend authority.
  • -
  • All spenders proved spend authority.
  • -
  • These, but also including optional payment address proofs.
  • -
-
-
-

Rationale

-

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 - \(\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.

-
-

Security and Privacy Considerations

-

When spending Sapling notes normally in transactions, wallets select a recent anchor to make the anonymity set of the spent note as large as possible. By contrast, Sapling spend authority in a payment disclosure is proven using the same anchor that was used in the transaction itself, instead of a recent anchor. We do this for efficency reasons:

-
    -
  • The anchor is already encoded in the transaction, so can be omitted from the payment disclosure encoding.
  • -
  • It is necessary to have a witness for each spent note that is being included in the payment disclosure. Using the same anchor means that the same witness can be used for the transaction spend and the payment disclosure, which in turn means that wallets that support payment disclosures only need to remember that witness, and do not need to continually update witnesses for spent notes in the off-chance that they might be used in a payment disclosure.
  • -
-

There is no privacy benefit to selecting a more recent anchor; the anonymity set of the note was "fixed" by the original spend (which revealed that the note existed as of that anchor's height).

-

We require all payment disclosures to prove spend authority for at least one input, in order to simplify the verification UX. In particular, if payment disclosures without spends were considered valid, an invalid payment disclosure with invalid signatures (that would be shown as invalid by UIs) could be mutated into a payment disclosure that would be shown as valid by UIs, by stripping off the signatures. We do not believe that this prevents any useful use cases; meanwhile if someone is intent on obtaining Sapling output disclosures regardless of the validity of their source, they will do so without a common standard.

-
-

Reference implementation

-

TBD

-
-

References

- - - - - - - -
1RFC 2119: Key words for use in RFCs to Indicate Requirement Levels
- - - - - - - -
2RFC 4648: The Base16, Base32, and Base64 Data Encodings
- - - - - - - -
3Zcash Protocol Specification, Version 2020.1.15 or later
- - - - - - - -
4Zcash Protocol Specification, Version 2020.1.15. Section 4.15.2: Spend Statement (Sapling)
- - - - - - - -
5Zcash Protocol Specification, Version 2020.1.15. 4.17.1: Encryption (Sapling)
- - - - - - - -
6Zcash Protocol Specification, Version 2020.1.15. 4.17.3: Decryption using a Full Viewing Key (Sapling)
- - - - - - - -
7Zcash Protocol Specification, Version 2020.1.15. Section 5.4.1.6: DiversifyHash Hash Function
- - - - - - - -
8Zcash Protocol Specification, Version 2020.1.15. Section 5.4.6.1: Spend Authorization Signature
- - - - - - - -
9BIP 322: Generic Signed Message Format
- - - - - - - -
10SLIP-0044 : Registered coin types for BIP-0044
- - - - - - - -
11ZIP 304: Sapling Address Signatures
-
-
- - \ No newline at end of file diff --git a/rendered/zip-0312.html b/rendered/zip-0312.html deleted file mode 100644 index f69ad06eb..000000000 --- a/rendered/zip-0312.html +++ /dev/null @@ -1,425 +0,0 @@ - - - - ZIP 312: FROST for Spend Authorization Multisignatures - - - - -
-
ZIP: 312
-Title: FROST for Spend Authorization Multisignatures
-Owners: Conrado Gouvea <conrado@zfnd.org>
-        Chelsea Komlo <ckomlo@uwaterloo.ca>
-        Deirdre Connolly <deirdre@zfnd.org>
-Status: Draft
-Category: Wallet
-Created: 2022-08-dd
-License: MIT
-Discussions-To: <https://github.com/zcash/zips/issues/382>
-Pull-Request: <https://github.com/zcash/zips/pull/662>
-

Terminology

-

{Edit this to reflect the key words that are actually used.} The key words "MUST", "MUST NOT", "SHOULD", and "MAY" in this document are to be interpreted as described in RFC 2119. 2

-

The terms below are to be interpreted as follows:

-
-
Unlinkability
-
The property of statistical independence of signatures from the signers' long-term keys, ensuring that (for perfectly uniform generation of Randomizers and no leakage of metadata) it is impossible to determine whether two transactions were generated by the same party.
-
-
-

Abstract

-

This proposal adapts FROST 3, a threshold signature scheme, to make it unlinkable, which is a requirement for its use in the Zcash protocol. The adapted scheme generates signatures compatible with spend authorization signatures in the Sapling and Orchard shielded protocols as deployed in Zcash.

-
-

Motivation

-

In the Zcash protocol, Spend Authorization Signatures are employed to authorize a transaction. The ability to generate these signatures with the user's private key is what effectively allows the user to spend funds.

-

This is a security-critical step, since anyone who obtains access to the private key will be able to spend the user's funds. For this reason, one interesting possibility is to require multiple parties to allow the transaction to go through. This can be accomplished with threshold signatures, where the private key is split between parties (or generated already split using a distributed protocol) in a way that a threshold (e.g. 2 out of 3) of them must sign the transaction in order to create the final signature. This enables scenarios such as users and third-party services sharing custody of a wallet, or a group of people managing shared funds, for example.

-

FROST is one of such threshold signature protocols. However, it can't be used as-is since the Zcash protocol also requires re-randomizing public and private keys to ensure unlinkability between transactions. This ZIP specifies a variant of FROST with re-randomization support. This variant is named "Re-Randomized FROST" and has been described in 4.

-
-

Requirements

-
    -
  • All signatures generated by following this ZIP must be verified successfully as Sapling or Orchard spend authorization signatures using the appropriate validating key.
  • -
  • The signatures generated by following this ZIP should meet the security criteria for Signature with Re-Randomizable Keys as specified in the Zcash protocol 12.
  • -
  • The threat model described below must be taken into account.
  • -
-

Threat Model

-

In normal usage, a Zcash user follows multiple steps in order to generate a shielded transaction:

-
    -
  • The transaction is created.
  • -
  • The transaction is signed with a re-randomized version of the user's spend authorization private key.
  • -
  • The zero-knowledge proof for the transaction is created with the randomizer 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 - \(\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 they are responsible for creating the proof.

-

This fits well into the "Coordinator" role from the FROST specification 5. The Coordinator is responsible for sending the message to be signed to all participants, and to aggregate the signature shares.

-

With those considerations in mind, the threat model considered in this ZIP is:

-
    -
  • The Coordinator is trusted with the privacy of the transaction (which includes the unlinkability property). A rogue Coordinator will be able to break unlinkability and privacy, but should not be able to create signed transactions without the approval of MIN_PARTICIPANTS participants, as specified in FROST.
  • -
  • All key share holders are also trusted with the privacy of the transaction, thus a rogue key share holder will be able to break its privacy and unlinkability.
  • -
-
-
-

Non-requirements

-
    -
  • This ZIP does not support removing the Coordinator role, as described in 6.
  • -
  • This ZIP does not prevent key share holders from linking the signing operation to a transaction in the blockchain.
  • -
  • Like the FROST specification 3, this ZIP does not specify a key generation procedure; but refer to that specification for guidelines.
  • -
  • Network privacy is not in scope for this ZIP, and must be obtained with other tools if desired.
  • -
-
-

Specification

-

Algorithms in this section are specified using Python pseudo-code, in the same fashion as the FROST specification 3.

-

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\) - .

-

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

-

While key generation is out of scope for this ZIP and the FROST spec 3, it needs to be consistent with FROST, see 9 for guidance. The spend authorization private key - \(\mathsf{ask}\) - 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}\) - , 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 - \(\mathsf{sk}\) - prevents using seed phrases to recover the original secret (which may be something desirable in the context of FROST).

-
-

Re-randomizable FROST

-

To add re-randomization to FROST, follow the specification 3 with the following modifications.

-

Randomizer Generation

-

A new helper function is defined, which generates a randomizer. The encode_signing_package is defined as the byte serialization of the msg, commitment_list values as described in 11. Implementations MAY choose another encoding as long as all values (the message, and the identifier, binding nonce and hiding nonce for each participant) are unambiguously encoded.

-

The function random_bytes(n) is defined in 3 and it returns a buffer with n bytes sampled uniformly at random. The constant Ns is also specified in 3 and is the size of a serialized scalar.

-
randomizer_generate():
-
-Inputs:
-- msg, the message being signed in the current FROST signing run
-- commitment_list = [(i, hiding_nonce_commitment_i,
-  binding_nonce_commitment_i), ...], a list of commitments issued by
-  each participant, where each element in the list indicates a
-  NonZeroScalar identifier i and two commitment Element values
-  (hiding_nonce_commitment_i, binding_nonce_commitment_i). This list
-  MUST be sorted in ascending order by identifier.
-
-Outputs: randomizer, a Scalar
-
-def randomizer_generate(msg, commitment_list):
-  # Generate a random byte buffer with the size of a serialized scalar
-  rng_randomizer = random_bytes(Ns)
-  signing_package_enc = encode_signing_package(commitment_list, msg)
-  randomizer_input = rng_randomizer || signing_package_enc
-  return HR(randomizer_input)
-
-

Round One - Commitment

-

Roune One is exactly the same as specified 3. But for context, it involves these steps:

-
    -
  • Each signer generates nonces and their corresponding public commitments. A nonce is a pair of Scalar values, and a commitment is a pair of Element values.
  • -
  • The nonces are stored locally by the signer and kept private for use in the second round.
  • -
  • The commitments are sent to the Coordinator.
  • -
-
-

Round Two - Signature Share Generation

-

In Round Two, the Coordinator generates a random scalar randomizer by calling randomizer_generate and sends it to each signer, over a confidential and authenticated channel, along with the message and the set of signing commitments. (Note that this differs from regular FROST which just requires an authenticated channel.)

-

In Zcash, the message that needs to be signed is actually the SIGHASH transaction hash, which does not convey enough information for the signers to decide if they want to authorize the transaction or not. Therefore, in practice, more data is needed to be sent (over the same encrypted, authenticated channel) from the Coordinator to the signers, possibly the transaction itself, openings of value commitments, decryption of note ciphertexts, etc.; and the signers MUST check that the given SIGHASH matches the data sent from the Coordinator, or compute the SIGHASH themselves from that data. However, the specific mechanism for that process is outside the scope of this ZIP.

-

The randomized sign function is defined as the regular FROST sign function, but with its inputs modified relative to the randomizer as following:

-
    -
  • sk_i = sk_i + randomizer
  • -
  • group_public_key = group_public_key + G.ScalarBaseMult(randomizer)
  • -
-
-

Signature Share Verification and Aggregation

-

The randomized aggregate function is defined as the regular FROST aggregate function, but with its inputs modified relative to the randomizer as following:

-
    -
  • group_public_key = group_public_key + G.ScalarBaseMult(randomizer)
  • -
-

The randomized verify_signature_share function is defined as the regular FROST verify_signature_share function, but with its inputs modified relative to the randomizer as following:

-
    -
  • PK_i = PK_i + G.ScalarBaseMult(randomizer)
  • -
  • group_public_key = group_public_key + G.ScalarBaseMult(randomizer)
  • -
-
-
-

Ciphersuites

-

FROST(Jubjub, BLAKE2b-512)

-

This ciphersuite uses Jubjub for the Group and BLAKE2b-512 for the Hash function H meant to produce signatures indistinguishable from RedJubjub Sapling Spend Authorization Signatures as specified in 13.

-
    -
  • Group: Jubjub 15 with base point - \(\mathcal{G}^{\mathsf{Sapling}}\) - as defined in 13. -
      -
    • Order: - \(r_\mathbb{J}\) - as defined in 15.
    • -
    • Identity: as defined in 15.
    • -
    • 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 - \(\mathsf{repr}_\mathbb{J}(P)\) - as defined in 15
    • -
    • DeserializeElement(P): Implemented as - \(\mathsf{abst}_\mathbb{J}(P)\) - as defined in 15, 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 of the Scalar value.
    • -
    • DeserializeScalar: Implemented by attempting to deserialize a Scalar from a little-endian 32-byte string. This function can fail if the input does not represent a Scalar in the range [0, G.Order() - 1].
    • -
    -
  • -
  • Hash (H): BLAKE2b-512 1 (BLAKE2b with 512-bit output and 16-byte personalization string), and Nh = 64. -
      -
    • 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)\) - , as defined by the - \(\mathsf{RedJubjub}\) - scheme instantiated in 12.)
    • -
    • 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().
    • -
    • H4(m): Implemented by computing BLAKE2b-512("FROST_RedJubjubM", m).
    • -
    • H5(m): Implemented by computing BLAKE2b-512("FROST_RedJubjubC", m).
    • -
    • HR(m): Implemented by computing BLAKE2b-512("FROST_RedJubjubA", m), interpreting the 64 bytes as a little-endian integer, and reducing the resulting integer modulo G.Order().
    • -
    -
  • -
-

Signature verification is as specified in 13 for RedJubjub.

-
-

FROST(Pallas, BLAKE2b-512)

-

This ciphersuite uses Pallas for the Group and BLAKE2b-512 for the Hash function H meant to produce signatures indistinguishable from RedPallas Orchard Spend Authorization Signatures as specified in 13.

-
    -
  • Group: Pallas 16 with base point - \(\mathcal{G}^{\mathsf{Orchard}}\) - as defined in 13. -
      -
    • Order: - \(r_\mathbb{P}\) - as defined in 16.
    • -
    • Identity: as defined in 16.
    • -
    • 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 - \(\mathsf{repr}_\mathbb{P}(P)\) - as defined in 16.
    • -
    • DeserializeElement(P): Implemented as - \(\mathsf{abst}_\mathbb{P}(P)\) - as defined in 16, 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.
    • -
    • DeserializeScalar: Implemented by attempting to deserialize a Scalar from a little-endian 32-byte string. This function can fail if the input does not represent a Scalar in the range [0, G.Order() - 1].
    • -
    -
  • -
  • Hash (H): BLAKE2b-512 1 (BLAKE2b with 512-bit output and 16-byte personalization string), and Nh = 64. -
      -
    • 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)\) - , as defined by the - \(\mathsf{RedPallas}\) - scheme instantiated in 12.)
    • -
    • 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().
    • -
    • H4(m): Implemented by computing BLAKE2b-512("FROST_RedPallasM", m).
    • -
    • H5(m): Implemented by computing BLAKE2b-512("FROST_RedPallasC", m).
    • -
    • HR(m): Implemented by computing BLAKE2b-512("FROST_RedPallasA", m), interpreting the 64 bytes as a little-endian integer, and reducing the resulting integer modulo G.Order().
    • -
    -
  • -
-

Signature verification is as specified in 13 for RedPallas.

-
-
-
-

Rationale

-

FROST is a threshold Schnorr signature scheme, and Zcash Spend Authorization are also Schnorr signatures, which allows the usage of FROST with Zcash. However, 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 - \(\mathsf{RedDSA.Validate}\) - function specified in 12:

-
    -
  • The FROST signature, when split into R and S in the first step of - \(\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}\) - . 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 - \(\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. This is not an issue however, since with Schnorr signatures it does not matter for the verifier how the r value was chosen, it just needs to be generated uniformly at random, which is true for FROST.
  • -
  • The above will ensure that the verification equation in - \(\mathsf{RedDSA.Validate}\) - will pass, since FROST ensures the exact same equation will be valid as described in 8.
  • -
-

The second step is adding the re-randomization functionality so that each FROST signing generates a re-randomized signature:

-
    -
  • Anywhere the public key is used, the randomized public key must be used instead. This is exactly what is done in the functions defined above.
  • -
  • 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}\) - , 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 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}\) - ; 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 4.

-
-

Reference implementation

-

The reddsa crate 17 contains a re-randomized FROST implementation of both ciphersuites.

-
-

References

- - - - - - - -
1BLAKE2: simpler, smaller, fast as MD5
- - - - - - - -
2RFC 2119: Key words for use in RFCs to Indicate Requirement Levels
- - - - - - - -
3RFC 9591: The Flexible Round-Optimized Schnorr Threshold (FROST) Protocol for Two-Round Schnorr Signatures
- - - - - - - -
4Re-Randomized FROST
- - - - - - - -
5RFC 9591: The Flexible Round-Optimized Schnorr Threshold (FROST) Protocol for Two-Round Schnorr Signatures. Section 5: Two-Round FROST Signing Protocol
- - - - - - - -
6RFC 9591: The Flexible Round-Optimized Schnorr Threshold (FROST) Protocol for Two-Round Schnorr Signatures. Section 7.3: Removing the Coordinator Role
- - - - - - - -
7RFC 9591: The Flexible Round-Optimized Schnorr Threshold (FROST) Protocol for Two-Round Schnorr Signatures. Section 3.1: Prime-Order Group
- - - - - - - -
8RFC 9591: The Flexible Round-Optimized Schnorr Threshold (FROST) Protocol for Two-Round Schnorr Signatures. Appendix B: Schnorr Signature Generation and Verification for Prime-Order Groups
- - - - - - - -
9RFC 9591: The Flexible Round-Optimized Schnorr Threshold (FROST) Protocol for Two-Round Schnorr Signatures. Appendix B: Trusted Dealer Key Generation
- - - - - - - -
10RFC 9591: The Flexible Round-Optimized Schnorr Threshold (FROST) Protocol for Two-Round Schnorr Signatures. Appendix C: Random Scalar Generation
- - - - - - - -
11The ZF FROST Book, Serialization Format
- - - - - - - -
12Zcash Protocol Specification, Version 2022.3.4 [NU5]. Section 5.4.7: RedDSA, RedJubjub, and RedPallas
- - - - - - - -
13Zcash Protocol Specification, Version 2022.3.4 [NU5]. Section 5.4.7.1: Spend Authorization Signature (Sapling and Orchard)
- - - - - - - -
14Zcash Protocol Specification, Version 2022.3.4 [NU5]. Section 4.15: Spend Authorization Signature (Sapling and Orchard)
- - - - - - - -
15Zcash Protocol Specification, Version 2022.3.4 [NU5]. Section 5.4.9.3: Jubjub
- - - - - - - -
16Zcash Protocol Specification, Version 2022.3.4 [NU5]. Section 5.4.9.6: Pallas and Vesta
- - - - - - - -
17reddsa
- - - - - - - -
18Prove that the sum of the Lagrange (interpolation) coefficients is equal to 1
-
-
- - \ No newline at end of file diff --git a/rendered/zip-0313.html b/rendered/zip-0313.html deleted file mode 100644 index d5aead657..000000000 --- a/rendered/zip-0313.html +++ /dev/null @@ -1,170 +0,0 @@ - - - - ZIP 313: Reduce Conventional Transaction Fee to 1000 zatoshis - - - -
-
ZIP: 313
-Title: Reduce Conventional Transaction Fee to 1000 zatoshis
-Owners: Aditya Bharadwaj <nighthawkwallet@protonmail.com>
-Credits: Daira-Emma Hopwood
-         Deirdre Connolly
-         Nathan Wilcox
-Status: Obsolete
-Obsoleted-By: 317
-Category: Wallet
-Created: 2020-10-11
-License: MIT
-Discussions-To: <https://forum.zcashcommunity.com/t/zip-reduce-default-shielded-transaction-fee-to-1000-zats/37566>
-Pull-Request: <https://github.com/zcash/zips/pull/408>
-

Terminology

-

The key words "SHOULD" and "RECOMMENDED" in this document are to be interpreted as described in BCP 14 1 when, and only when, they appear in all capitals.

-

The term "conventional transaction fee" in this document is in reference to the value of a transaction fee that is conventionally used by wallets, and that a user can reasonably expect miners on the Zcash network to accept for including a transaction in a block.

-
-

Abstract

-

The goal of this ZIP is to gather wallet developers, miners & Zcash users for social consensus on reducing the conventional transaction fees and to get the Zcash conventional transaction fee reduced from 10,000 zatoshis to 1,000 zatoshis.

-

In addition, this specification harmonizes transaction fees between different kinds of transaction (involving shielded addresses, transparent addresses, or both), as proposed in 7.

- -
-

Motivation

-

The conventional transaction fee presently is 0.0001 ZEC or 10,000 zatoshis. At a ZEC market price of USD 100, for example, a user can send 10,000 transactions for 1 ZEC. This works out to 1 U.S. cent per transaction and it rises with any increase in the price of ZEC.

-

With increase in light wallet adoptions on mobile clients, many users will be new to the Zcash eco-system. And the fact that the transaction fees are paid by the sender (not the receiver) is new information to users who might use Zcash for e-commerce and app interactions that might result in several transactions each day.

-

Privacy must not cost a premium. The cost of 10 shielded transactions buys 1GB of mobile data in India today.

-

Zcash users must be able to do more with their ZEC balance than worry about paying the premium for shielded transactions.

-

With reduced fees, it will be cheaper to transact on the Zcash network, while also inviting novel use cases for privacy-preserving applications that would benefit from the privacy, security, and programmable money aspects of the Zcash chain.

-

The harmonization of fees between different kinds of transaction can be expected to improve usability, consistency, and predictability.

-

Requirements for adoption

-

The change to the conventional transaction fees should be undertaken soon as it gets difficult to gain consensus with the growth in the network of wallets, exchanges, miners and third parties involved.

-

The following parties need to be part of the consensus:

-
    -
  • Support from mining groups is required to include the lowered conventional fee transactions in the next block.
  • -
  • Wallet developers need to provide commitment to update the software to use the new fee.
  • -
  • Zcash documentation and community outreach must be undertaken to make the change known.
  • -
-
-

Security and privacy considerations

-

Unique transaction fees may reveal specific users or wallets or wallet versions, which would reduce privacy for those specific users and the rest of the network. Hence this change should be accepted by a majority of shielded transaction software providers before deploying the change.

-

Varying/unique fees are bad for privacy. For the short term before blocks get full, it is fine for everyone to use a constant fee, as long as it is enough to compensate miners for including the transaction. 2

-

Long term, the issue of fees needs to be re-visited in separate future proposals as the blocks start getting consistently full. New ZIPs with flexible fees, such as 3, along with scaling solutions, will need to be evaluated and applied.

-

Denial of Service Vulnerability

-

A transaction-rate-based denial of service attack occurs when an attacker generates enough transactions over a window of time to prevent legitimate transactions from being mined, or to hinder syncing blocks for full nodes or miners.

-

There are two primary protections to this kind of attack in Zcash: the block size limit, and transaction fees. The block size limit ensures that full nodes and miners can keep up with the block chain even if blocks are completely full. However, users sending legitimate transactions may not have their transactions confirmed in a timely manner.

-

Variable fees could mitigate this kind of denial of service: if there are more transactions available than can fit into a single block, then a miner will typically choose the transactions that pay the highest fees. If legitimate wallets were to increase their fees during this condition, the attacker would also increase the fees of their transactions. It is sometimes argued that this would impose a cost to the attacker that would limit the time window for which they can continue the attack. However, there is little evidence that the actual costs involved would be a sufficient disincentive.

-

This proposal does not alter how fees are paid from transactions to miners. However, it does establish a fixed flat fee that wallets are expected to use. Therefore during a transaction rate denial-of-service attack, legitimate fees from those wallets will not rise, so an attacker can extend an attack for a longer window for the same cost.

-

This ZIP does not address this concern. A future ZIP should address this issue. Wallet developers and operators should monitor the Zcash network for rapid growth in transaction rates.

-
-
-
-

Specification

-

Wallets implementing this specification will use a default fee of 0.00001 ZEC (1000 zatoshis) from block 1,080,000, for all transactions.

-

Transaction relaying

-

zcashd, and potentially other node implementations, implements fee-based restrictions on relaying of mempool transactions. Nodes that normally relay transactions are expected to do so for transactions that pay at least the conventional fee, unless there are other reasons not to do so for robustness or denial-of-service mitigation.

-

In zcashd 4.2.0, this change is implemented by 8.

-
-

Mempool size limiting

-

zcashd limits the size of the mempool as described in 10. This specifies a low_fee_penalty that is added to the "eviction weight" if the transaction pays a fee less than (in the original ZIP) 10,000 zatoshis. This threshold is modified to match the new conventional fee in zcashd 4.2.0.

-
-
-

Support

-

The developers of the following wallets intend to implement the reduced fees:

-
    -
  • Zbay;
  • -
  • Zecwallet Suite (Zecwallet Lite for Desktop/iOS/Android & Zecwallet FullNode);
  • -
  • Nighthawk Wallet for Android & iOS;
  • -
  • zcashd built-in wallet 6.
  • -
-

In zcashd this fee change is implemented in version 4.2.0 (not dependent on block height), and in that version is limited to transactions created using z_* RPC APIs. It is planned to extend this to all transactions in a future version 7.

-
-

Acknowledgements

-

Thanks to Nathan Wilcox for suggesting improvements to the denial of service section. Thanks to Daira-Emma Hopwood and Deirdre Connolly for reviewing and fixing the wording in this ZIP.

-
-

References

- - - - - - - -
1Information 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"
- - - - - - - -
2Conventional Shielded Fees
- - - - - - - -
3Ian Miers. Mechanism for fee suggester/oracle
- - - - - - - -
4Zooko Wilcox. Tweet on reducing tx fees
- - - - - - - -
5Zooko Wilcox. Tweet on sharing tx fee with wallet developer
- - - - - - - -
6Reduce default fee to 1000 zatoshis
- - - - - - - -
7Ecosystem-wide standard transaction fee
- - - - - - - -
8zcashd commit e6a44ff: Always allow transactions paying at least DEFAULT_FEE to be relayed
- - - - - - - -
9ZIP 317: Proportional Transfer Fee Mechanism
- - - - - - - -
10ZIP 401: Addressing Mempool Denial-of-Service
-
-
- - \ No newline at end of file diff --git a/rendered/zip-0314.html b/rendered/zip-0314.html deleted file mode 100644 index fa245dceb..000000000 --- a/rendered/zip-0314.html +++ /dev/null @@ -1,17 +0,0 @@ - - - - ZIP 314: Privacy upgrades to the Zcash light client protocol - - - -
-
ZIP: 314
-Title: Privacy upgrades to the Zcash light client protocol
-Owners: Taylor Hornby <taylor@electriccoin.co>
-Status: Reserved
-Category: Standards / Wallet
-Discussions-To: <https://github.com/zcash/zips/issues/434>
-
- - \ No newline at end of file diff --git a/rendered/zip-0315.html b/rendered/zip-0315.html deleted file mode 100644 index 9ae30b3d9..000000000 --- a/rendered/zip-0315.html +++ /dev/null @@ -1,396 +0,0 @@ - - - - ZIP 315: Best Practices for Wallet Implementations - - - -
-
ZIP: 315
-Title: Best Practices for Wallet Implementations
-Owners: Daira-Emma Hopwood <daira-emma@electriccoin.co>
-        Jack Grigg <jack@electriccoin.co>
-        Kris Nuttycombe <kris@electriccoin.co>
-Credits: Francisco Gindre
-Status: Draft
-Category: Wallet
-Discussions-To: <https://github.com/zcash/zips/issues/447>
-Pull-Request: <https://github.com/zcash/zips/pull/607>
-

Terminology

-

The key words "MUST", "SHOULD", "SHOULD NOT", "RECOMMENDED", "NOT RECOMMENDED", 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 terms below are to be interpreted as follows:

-
-
Auto-shielding
-
The process of automatically transferring transparent funds to the most recent shielded pool on receipt.
-
Auto-migration
-
The process of automatically transferring shielded funds from older pools to the most preferred (usually the most recent) pool on receipt.
-
Opportunistic migration
-
The process of transferring previously received shielded funds from older pools to the most preferred (usually the most recent) pool as part of a user-initiated transaction.
-
Transaction output (TXO)
-
An output (transparent coin or shielded note) of a transaction on the consensus block chain or in the mempool visible to a wallet.
-
-

TODO: Add informal definitions of: * known-spendable and confirmed-spendable TXOs; * trusted and untrusted TXOs.

-

These should forward-reference the specification section with the formal definitions.

-
-

Motivation

-

Zcash wallets have to serve two purposes as a user agent:

-
    -
  • to manage the economic actions dictated by the user;
  • -
  • to manage the privacy implications of these actions.
  • -
-

The goal of this ZIP is to document security and privacy best practices when handling funds and transactions as the user's agent. These best practices are intended to provide as much privacy as is feasible by default, while still enabling the user's desired transactions to occur, and exposing any privacy implications to the user so that they have enough information to assess the consequences of their economic actions.

-

This ZIP covers best practices for:

-
    -
  • what information to display to the user about transactions and balances;
  • -
  • how to handle interactions between the ZIP 32 2 key tree and Unified Addresses 4;
  • -
  • when to use external or internal keys/addresses;
  • -
  • sharing addresses and viewing keys;
  • -
  • sending and receiving funds (including fee selection);
  • -
  • migrating funds between pools.
  • -
-
-

Requirements

- -

Prompt accessibility of funds

-

Wallets need to take account of two main concerns with respect to accessibility of funds:

-
    -
  • enabling funds to be spent as quickly as possible to reduce latency;
  • -
  • ensuring that the confirmed-spendable balance is not overestimated, and so can be trusted by the user.
  • -
-

These concerns affect the way that balances should be computed, which notes are selected for spending, and how the wallet should ensure that sufficient notes are available to cover multiple spends within a short period.

-

To support this we define two kinds of TXOs:

-
    -
  • A trusted TXO is a TXO received from a party where the wallet trusts that it will remain mined in its original transaction, such as TXOs created by the wallet's internal TXO handling.
  • -
  • An untrusted TXO is a TXO received by the wallet that is not trusted.
  • -
-

Wallets can then require that untrusted TXOs need more confirmations before they become confirmed-spendable than trusted TXOs. This provides an improved trade-off between latency on the one hand, and reliability and safety on the other.

-
-
-

Specification

-

Long-term storage of funds

-

It is RECOMMENDED that wallets only hold funds as shielded in the long term; that is, if a wallet supports receiving transparent funds (or supports importing a seed from another wallet that might have done so), then it SHOULD auto-shield such funds by default.

-

A shielding transaction is always linked to the transparent addresses it spends from. This can cause undesirable information leaks:

-
    -
  1. if there are multiple transparent addresses, they will be linked to each other;
  2. -
  3. a link between the input transparent address(es) and the payment will be visible to the recipient(s), or to any other holder of an Incoming Viewing Key for the destination address(es).
  4. -
-

Despite the fact that it is not possible to achieve strong privacy guarantees from any use of transparent addresses, it is undesirable to reveal this additional information. In particular, issue b) motivates ruling out the use of "opportunistic shielding", i.e. shielding previously received transparent funds as part of a user-initiated transaction.

-

Wallets SHOULD NOT auto-shield from multiple transparent addresses in the same transaction, and SHOULD NOT use opportunistic shielding.

-

Following all of the recommendations in this section improves both collective privacy and the user's individual privacy, by maximizing the size of the note anonymity set over time and minimizing the potential linkage of shielding transactions to other transactions.

-

The remainder of this specification assumes a wallet that follows all of these recommendations, except where explicitly noted.

-

A wallet MAY allow users to disable auto-shielding, auto-migration, and/or opportunistic migration. If it does so, this need not be via three independent settings.

-

Automatic shielding and automatic/opportunistic migration SHOULD NOT be applied to inputs where the cost of shielding or migrating them will exceed their economic value. If these transactions are paying the ZIP 317 conventional fee 5, that will be the case if the amount of the UTXO to be shielded/migrated exceeds the marginal fee, and cannot be accommodated by an input that would be present in any case due to padding of the number of inputs from a given shielded pool.

-
-

Trusted and untrusted TXOs

-

A wallet SHOULD treat received TXOs that are outputs of transactions created by the same wallet, as trusted TXOs. Wallets MAY enable users to mark specific external transactions as trusted, allowing their received TXOs also to be classified as trusted TXOs.

-

A wallet SHOULD have a policy that is clearly communicated to the user for the number of confirmations needed to spend untrusted and trusted TXOs respectively. The following confirmation policy is RECOMMENDED:

-
    -
  • 10 confirmations, for untrusted TXOs;
  • -
  • 3 confirmations, for trusted TXOs.
  • -
-

Rationale for the given numbers of confirmations

-

The rationale for choosing three confirmations for trusted TXOs is that anecdotally, reorgs are usually less than three blocks.

-

The consequences of attempting to spend a trusted TXO may be less severe in the case of a rollback than the consequences of attempting to spend an untrusted TXO. The value received from a trusted TXO should always be recoverable, whereas recovering value received from an untrusted TXO may require the user to request that funds are re-sent.

-
-
-

Categories of TXOs according to spendability

-

A TXO is known-spendable, relative to a given block chain and wallet state, if and only if all of the following are true in that state:

-
    -
  • the TXO is unspent at the wallet's view of the chain tip, and that view is reasonably up-to-date; -

    TODO: consider undoing the up-to-date part, as when combined with the definition of balance below, it causes wallet balance to drop to zero in the short window between opening and updating the wallet's chain tip view.

    -
  • -
  • the TXO is not committed to be spent in another transaction created by this wallet; and
  • -
  • the wallet has the TXO's spending key (for whatever protocol the TXO uses).
  • -
-

A TXO is confirmed-spendable, relative to a given block chain and wallet state, if and only if all of the following are true in that state:

-
    -
  • the wallet is synchronized; and
  • -
  • the TXO is known-spendable; and
  • -
  • either auto-shielding is not active or the TXO is shielded; and
  • -
  • auto-migration from whatever protocol the TXO uses is not active; and
  • -
  • the TXO is trusted and has at least the required confirmations for trusted TXOs, or it is untrusted and has at least the required confirmations for untrusted TXOs.
  • -
-

A TXO is unconfirmed-spendable, relative to a given block chain and wallet state, if and only if the TXO is known-spendable but is not confirmed-spendable in that state.

-

A TXO is watch-only if and only if the wallet has its full viewing key (or address in the case of a transparent TXO) but not its spending key.

-

A wallet MUST NOT attempt to spend a TXO in a user-initiated transaction that is not confirmed-spendable.

-

Open question: what should be specified about which TXOs can be spent in non-user-initiated transactions?

-

Note: the definition of a TXO includes outputs in mempool transactions that are unconflicted from the perspective of the wallet.

-
-

Reporting of balances

-

Wallets SHOULD report:

-
    -
  • Confirmed-spendable balance.
  • -
  • Pending balance, or total balance.
  • -
-

These are calculated as follows:

-
    -
  • The confirmed-spendable balance is the sum of values of confirmed-spendable TXOs.
  • -
  • The pending balance is the sum of values of unconfirmed-spendable TXOs.
  • -
  • The total balance is the confirmed-spendable balance plus the pending balance.
  • -
-

Note: the definition of "confirmed-spendable" above ensures that:

-
    -
  • if auto-shielding is enabled, transparent funds will be reported in the pending or total balance, but not in the confirmed-spendable balance;
  • -
  • if the wallet has not synchronized at least the nullifier set to the chain tip, the confirmed-spendable balance will be zero.
  • -
-

If auto-shielding is disabled, the wallet MAY report shielded and transparent balances separately. If it does so, it MUST make clear whether each reported balance corresponds to a confirmed-spendable, pending, or total subset of funds.

-

Rationale for reporting of balances

-

If auto-shielding is disabled, then separate shielded and transparent balances can constitute useful information. If auto-shielding is enabled then the wallet can and will automatically spend transparent TXOs in order to shield them, and so transparent TXOs need to be presented as pending, not as part of the balance spendable by the user.

-

Potentially, for expert users, separate shielded balances per pool could also be useful.

-

Open question: Does the specification of balance reporting give the user sufficient visibility into the operation of auto-shielding and pool migration/usage?

-
-
-

Reporting of transactions

-

If a transaction includes watch-only received TXOs, its watch-only incoming balance MUST be reported separately to any potentially known-spendable balance.

-

Incoming transactions

-

A transaction is incoming if it contains unconfirmed-spendable TXOs. Incoming transactions SHOULD be reported with their number of confirmations and their balances as described in Reporting of balances.

-
-

Sent transactions

-

A transaction is sent if it was either:

-
    -
  • created by the wallet, or
  • -
  • detected by using the wallet's outgoing viewing keys to decrypt Sapling or Orchard outputs, or
  • -
  • detected as spending a note that was at some time held by the wallet by recognizing that note's nullifier, or
  • -
  • detected as spending a transparent TXO associated with one of the wallet's addresses (including watch-only addresses).
  • -
-

Sent transactions SHOULD be reported with their number of confirmations, an estimate of how long until they expire (if they are unmined and have an expiry height), and their balances as described in Reporting of balances.

-
-
-

Transaction creation

- -

Linkability of transactions or addresses

-
Motivation for choices reducing linkability
-

We want to support creating unlinkable addresses, in order that a user can give different addresses to different counterparties, in such a way that the counterparties (even if they collude) cannot tell that the addresses were provided by the same or distinct users.

-

If multiple UTXOs are received at the same transparent address, it is safe to shield them all in the same transaction, because that is not leaking additional information.

-

UTXOs received on different transparent receivers SHOULD NOT be shielded in the same transaction. Ideally, when they are shielded in separate transactions, this should be done in such a way that the timing of those transactions is not linkable.

-

TODO: move this. Daira-Emma thinks that if we only document leakage rather than explicitly say in the specification of how to construct transactions how to mitigate it, then implementors will ignore it.

-

When spending transparent UTXOs, they SHOULD only be sent to an internal shielded receiver belonging to the wallet, except when they are generated and spent ephemerally as part of a ZIP 320 transfer 6.

-

A wallet MUST NOT send funds to a transparent address unless all of the source funds come from shielded pools, and this SHOULD be a single shielded pool.

-

We want to minimize pool crossing.

-
-
-

Anchor selection

-

A wallet SHOULD choose an anchor a number of blocks back from the head of the chain equal to the trusted confirmation depth. That is, if the current block is at height H, the anchor SHOULD reflect the final treestate of the block at height H-3.

-

TODO: Define a parameter for this depth, and then RECOMMEND a value of 3.

-
-

Rationale for anchor selection

-
    -
  • If the chain rolls back past the block at which the anchor is chosen, then the anchor and the transaction will be invalidated. This is undesirable both for reliability, and because the nullifiers of spent shielded notes will have been revealed, linking this transaction to any future transactions that spend those notes. -

    TODO: Reword this given the proposed note management mitigation below.

    -
  • -
  • On the other hand, it is undesirable to choose an anchor too many blocks back, because that prevents more recently received shielded notes from being spent.
  • -
  • Using a fixed anchor depth (as opposed to a different depth depending on whether or not we are spending trusted shielded notes) avoids leaking information about whether or not the shielded notes we spent were trusted.
  • -
-
-

Note selection

-

TODO: recommend that when nullifiers are revealed in a transaction that is then invalidated (or revealed in some other detectable way), they SHOULD be used in a note management tx to avoid linking the invalidated tx with some arbitrary future tx. Provided that there are no transparent outputs leaving this wallet's control, the same arities and transparent outputs SHOULD be preserved, which also avoids revealing whether the user changed their mind about whether to send the original semantic transaction.

-
-

Expiration height

-

A wallet SHOULD create transactions using the default expiration height of 40 blocks from the current height, as specified in 3.

-
-

Open question

-

How should wallet developers time transactions to avoid linkability?

-
    -
  • when we roll addresses with transparent components, we have to consider how that could allow linking of shielded components
  • -
-

TODO: dusting attack mitigation

-
-
-

Network-layer privacy

-
-

Viewing keys

-

What they are supposed to reveal; see ZIP 310 for Sapling (needs updating for Orchard). https://github.com/zcash/zips/issues/606

-
-

Allowed transfers

-
    -
  • Sprout -> transparent or Sapling
  • -
  • Sapling -> transparent or Sapling or Orchard
  • -
  • Orchard -> transparent or Sapling or Orchard
  • -
  • if auto-shielding is off: * transparent -> transparent or Sapling or Orchard
  • -
  • if auto-shielding is on: * transparent -> internal Orchard or Sapling
  • -
-

Note: wallets MAY further restrict the set of transfers they perform.

-
-

Auto-shielding

-

Wallets SHOULD NOT spend funds from a transparent address to an external address, unless the user gives explicit consent for this on a per-transaction basis.

-

TODO: Reword this to define the source transparent address as any transparent address (external, internal, or ephemeral), except in the case of ephemeral as allowed for implementing ZIP 320.

-

In order to support this policy, wallets SHOULD implement a system of auto-shielding with the following characteristics:

-

If auto-shielding functionality is available in a wallet, then users MUST be able to explicitly consent to one of the following possibilities:

-
    -
  • auto-shielding is always on;
  • -
  • auto-shielding is always off;
  • -
  • the user specifies a policy...
  • -
-

Auto-shielding MUST be one of:

-
    -
  • "must opt in or out" (zcashd will do this -- i.e. refuse to start unless the option is configured), or
  • -
  • always on.
  • -
-
-

Auto-migration

-
-

Information leakage for transfers between pools

-

If no auto-migration, if you can satisfy a transfer request to Sapling from your Sapling funds, do so.

-

The user's consent is needed to reveal amounts publically (as opposed to revealing them to the holder of a viewing key authorized to see that amount). Therefore, there should be per-transaction opt-in for any transfer that publically reveals amounts on chain.

-
    -
  • there may be a compatibility issue for amount-revealing cross-pool txns that were previously allowed without opt-in
  • -
-

Wallets MUST NOT automatically combine funds across pools to satisfy a transfer (since that could reveal the total funds the user holds in some pool).

-

In order to maintain the integrity of IVK guarantees, wallets should not generate unified addresses that contain internal receivers, nor expose internal receivers (such as those used for auto-shielding and change outputs) in any way.

-

Open questions:

-
    -
  • should there be an auto-migration option from Sapling to Orchard?
  • -
-

str4d notes

-

If we want to have both automatic and opportunistic shielding, and keep the two indistinguishable, then we can't auto-shield when the transparent balance reaches some threshold (otherwise opportunistic would either never be used, or would be identifiable when it uses the balance below the threshold).

-

Instead, a proposition: we define a distribution of "time since last payment to the address" from which we sample the time at which the auto-shielding transaction will be created. This distribution is weighted by the balance in the address, so as more funds accrue, the auto-shielding transaction is more likely to be created.

-
    -
  • It ensures that all funds will eventually be auto-shielded, while preventing fee-dusting attacks (where dust is sent in order to repeatedly consume fees from the wallet), as the auto-shielding transaction is not directly triggered by payment receipt.
  • -
  • If the user makes a shielding transaction in the meantime, we opportunistically shield, without it being clearly not an auto-shielding transaction.
  • -
  • If a wallet is offline for a long time, then it would likely auto-shield as soon as it finishes syncing. This maybe isn't enough to reveal that the wallet came online, except that it _might_ result in auto-shielding transactions for multiple transparent addresses being created at the same time. So we might want to special-case this?
  • -
-

Properties we want from auto-shielding:

-
    -
  • Auto-shielding transactions MUST NOT shield from multiple transparent receivers in the same transaction. - Doing so would trivially link diversified UAs containing transparent receivers.
  • -
-

Properties we want from auto-migration:

-
    -
  • Receipt of a shielded payment MUST NOT trigger any on-chain behaviour (as that reveals transaction linkability).
  • -
-

Both auto-shielding and auto-migration are time-triggered actions, not receipt-triggered actions. An auto-shielding or auto-migration transaction MUST NOT be created as a direct result of a payment being received.

-

Both of these are opportunistic: if the user's wallet is making a transaction in which one of these actions would occur anyway, then the wallet takes the opportunity to migrate as much as it would do if it were generating an autoshielding transaction. This both saves on a transaction, and removes the need for any kind of transparent change address within UAs.

-

TODO: what pool should change go to?

-
    -
  • Proposal: the most recent pool already involved in the transaction.
  • -
-
-
-

Wallet Recovery

-

In the case where we are recovering a wallet from a backed-up mnemonic phrase, and not from a wallet.dat, we don't have enough information to figure out what receiver types the user originally used when deriving each UA under an account. We have a similar issue if someone exports a UFVK, derives an address from it, and has a payment sent to the address: zcashd will detect the payment, but has no way to figure out what address it should display in the UI. A wallet could store this information in the memo field of change outputs, but that adds a bunch of coordination to the problem, and assumes ongoing on-chain state storage.

-
    -
  • If the receiver matches an address that the wallet knows was derived via z_getaddressforaccount, show that UA as expected (matching the receiver types the user selected).
  • -
  • If the receiver matches a UFVK in the wallet, and we are looking it up because we detected a received note in some block, show the UA with the default receiver types that zcashd was using as of that block height (ideally the earliest block height we detect), and cache this for future usage.
  • -
  • For zcashd's current policy of "best and second-best shielded pools, plus transparent pool", that would mean Orchard, Sapling, and transparent for current block heights.
  • -
  • For each release of a wallet, the wallet should specify a set of receiver types and an associated range of block heights during which the wallet will, by default, generate unified addresses using that set of receiver types.
  • -
  • For zcashd we know how the policy evolves because each zcashd release has an approximate release height and End-of-Service height that defines the window.
  • -
  • Subsequent releases of a wallet SHOULD NOT retroactively change their policies for previously defined block height ranges.
  • -
  • If the receiver type for a note received at a given time is not a member of the set of receiver types expected for the range of block heights, the policy corresponding to the nearest block height range that includes that receiver type SHOULD be used.
  • -
  • If the receiver matches a UFVK in the wallet, and we have no information about when this receiver may have been first used, show the UA corresponding to the most recent receiver types policy that includes the receiver's type.
  • -
  • As part of this, we're also going to change the "Sapling receiver to UfvkId" logic to trial-decrypt after trying internal map, so that we will detect all receivers linked to UFVKs in the wallet, not just receivers in addresses generated via z_getaddressforaccount. The internal map lookup is then just an optimisation (and a future refactor to have Orchard do the same is possible, but for now we will only trial-decrypt so we don't need to refactor to access the Rust wallet). TODO: express this in a less zcashd-specific way.
  • -
-

TODO: Mention recommendations (not requirements) of receiver types based on settled ('accepted') network upgrades, as defined in §3.3 of the Zcash Protocol Specification, at the time of the release of the wallet.

-

TODO: Rationale subsection explaining why earliest block height at detection and the rules/recommendations in place at that block height are preferred over showing different UAs at different heights

-
-
-

References

- - - - - - - -
1Information 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"
- - - - - - - -
2ZIP 32: Shielded Hierarchical Deterministic Wallets
- - - - - - - -
3ZIP 203: Transaction Expiry
- - - - - - - -
4ZIP 316: Unified Addresses and Unified Viewing Keys
- - - - - - - -
5ZIP 317: Proportional Transfer Fee Mechanism
- - - - - - - -
6ZIP 320: Defining an Address Type to which funds can only be sent from Transparent Addresses
-
-
- - \ No newline at end of file diff --git a/rendered/zip-0316.html b/rendered/zip-0316.html deleted file mode 100644 index 7dae95159..000000000 --- a/rendered/zip-0316.html +++ /dev/null @@ -1,1161 +0,0 @@ - - - - ZIP 316: Unified Addresses and Unified Viewing Keys - - - - -
-
ZIP: 316
-Title: Unified Addresses and Unified Viewing Keys
-Owners: Daira-Emma Hopwood <daira-emma@electriccoin.co>
-        Nathan Wilcox <nathan@electriccoin.co>
-        Jack Grigg <jack@electriccoin.co>
-        Sean Bowe <sean@electriccoin.co>
-        Kris Nuttycombe <kris@electriccoin.co>
-Original-Authors: Greg Pfeil
-                  Ying Tong Lai
-Credits: Taylor Hornby
-         Stephen Smith
-Status: Revision 0: Final, Revision 1: Proposed
-Category: Standards / RPC / Wallet
-Created: 2021-04-07
-License: MIT
-Discussions-To: <https://github.com/zcash/zips/issues/482>
-

Terminology

-

The key words "MUST", "MUST NOT", "SHOULD", "RECOMMENDED", 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 terms below are to be interpreted as follows:

-
-
Recipient
-
A wallet or other software that can receive transfers of assets (such as ZEC) or in the future potentially other transaction-based state changes.
-
Producer
-
A wallet or other software that can create an Address (in which case it is normally also a Recipient) or a Viewing Key.
-
Consumer
-
A wallet or other software that can make use of an Address or Viewing Key that it is given.
-
Sender
-
A wallet or other software that can send transfers of assets, or other side effects to consensus state that may be defined in future. Senders are a subset of Consumers.
-
Receiver
-
The necessary information to transfer an asset to a Recipient that generated that Receiver using a specific Transfer Protocol. Each Receiver is associated unambiguously with a specific Receiver Type, identified by an integer Typecode.
-
Receiver Encoding
-
An encoding of a Receiver as a byte sequence.
-
Viewing Key
-
The necessary information to view information about payments to an Address, or (in the case of a Full Viewing Key) from an Address. An Incoming Viewing Key can be derived from a Full Viewing Key, and an Address can be derived from an Incoming Viewing Key.
-
Viewing Key Encoding
-
An encoding of a Viewing Key as a byte sequence.
-
Metadata Encoding
-
An encoding of metadata that is not a Receiver or Viewing Key, but may affect the interpretation of the overall Unified Address/Viewing Key.
-
Item
-
An Receiver Encoding, Viewing Key Encoding, or Metadata Encoding.
-
Legacy Address
-
A Transparent, Sprout, or Sapling Address.
-
Unified Address (or UA)
-
A Unified Address combines multiple Receiver (and optionally Metadata) Items.
-
Unified Full Viewing Key (or UFVK)
-
A Unified Full Viewing Key combines multiple Full Viewing Key (and optionally Metadata) Items.
-
Unified Incoming Viewing Key (or UIVK)
-
A Unified Incoming Viewing Key combines multiple Incoming Viewing Key (and optionally Metadata) Items.
-
Unified Viewing Key (or UVK)
-
Either a Unified Full Viewing Key or a Unified Incoming Viewing Key.
-
Address
-
Either a Legacy Address or a Unified Address.
-
Transfer Protocol
-
A specification of how a Sender can transfer assets to a Recipient. For example, the Transfer Protocol for a Sapling Receiver is the subset of the Zcash protocol required to successfully transfer ZEC using Sapling Spend/Output Transfers as specified in the Zcash Protocol Specification. (A single Zcash transaction can contain transfers of multiple Transfer Protocols. For example a t→z transaction that shields to the Sapling pool requires both Transparent and Sapling Transfer Protocols.)
-
Unified String Encoding
-
An encoding of a UA/UVK as a US-ASCII string, intended either for display and transfer by Zcash end-users, or internal use by Zcash-related software.
-
Unified QR Encoding
-
An encoding of a UA/UVK as a QR code, intended for display and transfer by Zcash end-users in situations where usability advantages of a 2D bar code may be relevant.
-
Address Encoding
-
The externally visible encoding of an Address (e.g. as a string of characters or a QR code).
-
Unix Epoch Time
-
An integer representing a UTC time in seconds relative to the Unix Epoch of 1970-01-01T00:00:00Z.
-
-

Notation for sequences, conversions, and arithmetic operations follows the Zcash protocol specification 3.

-
-

Abstract

-

This proposal defines Unified Addresses, which bundle together Zcash Addresses of different types in a way that can be presented as a single Address Encoding. It also defines Unified Viewing Keys, which perform a similar function for Zcash viewing keys.

-
-

Motivation

-

Up to and including the Canopy network upgrade, Zcash supported the following Payment Address types:

-
    -
  • Transparent Addresses (P2PKH and P2SH)
  • -
  • Sprout Addresses
  • -
  • Sapling Addresses
  • -
-

Each of these has its own Address Encodings, as a string and as a QR code. (Since the QR code is derivable from the string encoding as described in 9, for many purposes it suffices to consider the string encoding.)

-

The Orchard proposal 26 adds a new Address type, Orchard Addresses.

-

The difficulty with defining new Address Encodings for each Address type, is that end-users are forced to be aware of the various types, and in particular which types are supported by a given Consumer or Recipient. In order to make sure that transfers are completed successfully, users may be forced to explicitly generate Addresses of different types and re-distribute encodings of them, which adds significant friction and cognitive overhead to understanding and using Zcash.

-

The goals for a Unified Address standard are as follows:

-
    -
  • Simplify coordination between Recipients and Consumers by removing complexity from negotiating Address types.
  • -
  • Provide a “bridging mechanism” to allow shielded wallets to successfully interact with conformant Transparent-Only wallets.
  • -
  • Allow older conformant wallets to interact seamlessly with newer wallets.
  • -
  • Enable users of newer wallets to upgrade to newer transaction technologies and/or pools while maintaining seamless interactions with counterparties using older wallets.
  • -
  • Facilitate wallets to assume more sophisticated responsibilities for shielding and/or migrating user funds.
  • -
  • Allow wallets to potentially develop new transfer mechanisms without underlying protocol changes.
  • -
  • Support abstractions corresponding to a Unified Address that provide the functionality of Full Viewing Keys and Incoming Viewing Keys.
  • -
  • Provide forward compatibility that is standard for all wallets across a range of potential future features. Some examples might include Layer 2 features, cross-chain interoperability and bridging, and decentralized exchange.
  • -
  • Allow for Metadata Items to be included in Unified Addresses/Viewing Keys in order to provide future extensibility.
  • -
  • The standard should work well for Zcash today and upcoming potential upgrades, and also anticipate even broader use cases down the road such as cross-chain functionality.
  • -
-
-

Requirements

-

Overview

-

Unified Addresses specify multiple methods for payment to a Recipient's wallet. The Sender's wallet can then non-interactively select the method of payment.

-

Importantly, any wallet can support Unified Addresses, even when that wallet only supports a subset of payment methods for receiving and/or sending.

-

Despite having some similar characteristics, the Unified Address standard is orthogonal to Payment Request URIs 29 and similar schemes. Since Payment Requests encode addresses as alphanumeric strings, no change to ZIP 321 is required in order to use Unified Addresses in Payment Requests.

-
-

Concepts

-

Wallets follow a model Interaction Flow as follows:

-
    -
  1. A Producer generates an Address.
  2. -
  3. The Producer encodes the Address.
  4. -
  5. The Producer wallet or human user distributes this Address Encoding. This ZIP leaves distribution mechanisms out of scope.
  6. -
  7. A Consumer wallet or user imports the Address Encoding through any of a variety of mechanisms (QR code scanning, Payment URIs, cut-and-paste, or “in-band” protocols like Reply-To memos).
  8. -
  9. A Consumer wallet decodes the Address Encoding and performs validity checks.
  10. -
  11. (Perhaps later in time) if the Consumer wallet is a Sender, it can execute a transfer of ZEC (or other assets or protocol state changes) to the Address.
  12. -
-

Encodings of the same Address may be distributed zero or more times through different means. Zero or more Consumers may import Addresses. Zero or more of those (that are Senders) may execute a Transfer. A single Sender may execute multiple Transfers over time from a single import.

-

Steps 1 to 5 inclusive also apply to Interaction Flows for Unified Full Viewing Keys and Unified Incoming Viewing Keys.

-
-

Addresses

-

A Unified Address (or UA for short) combines one or more Receivers.

-

When new Transport Protocols are introduced to the Zcash protocol after Unified Addresses are standardized, those should introduce new Receiver Types but not different Address types outside of the UA standard. There needs to be a compelling reason to deviate from the standard, since the benefits of UA come precisely from their applicability across all new protocol upgrades.

-
-

Receivers

-

Every wallet must properly parse encodings of a Unified Address or Unified Viewing Key containing unrecognised Items.

-

A wallet may process unrecognised Items by indicating to the user their presence or similar information for usability or diagnostic purposes.

-
-

Transport Encoding

-

The Unified String Encoding is “opaque” to human readers: it does not allow visual identification of which Receivers or Receiver Types are present.

-

The Unified String Encoding is resilient against typos, transcription errors, cut-and-paste errors, truncation, or other likely UX hazards.

-

There is a well-defined Unified QR Encoding of a Unified Address (or UFVK or UIVK) as a QR code, which produces QR codes that are reasonably compact and robust.

-

There is a well-defined transformation between the Unified QR Encoding and Unified String Encoding of a given UA/UVK in either direction.

-

The Unified String Encoding fits into ZIP-321 Payment URIs 29 and general URIs without introducing parse ambiguities.

-

The encoding must support sufficiently many Recipient Types to allow for reasonable future expansion.

-

The encoding must allow all wallets to safely and correctly parse out unrecognised Receiver Types well enough to ignore them.

-
-

Transfers

-

When executing a Transfer the Sender selects a Receiver via a Selection process.

-

Given a valid UA, Selection must treat any unrecognised Item as though it were absent.

-
    -
  • This property is crucial for forward compatibility to ensure users who upgrade to newer protocols / UAs don't lose the ability to smoothly interact with older wallets.
  • -
  • This property is crucial for allowing Transparent-Only UA-Conformant wallets to interact with newer shielded wallets, removing a disincentive for adopting newer shielded wallets.
  • -
  • This property also allows Transparent-Only wallets to upgrade to shielded support without re-acquiring counterparty UAs. If they are re-acquired, the user flow and usability will be minimally disrupted.
  • -
-
-

Experimental Usage

-

Unified Addresses and Unified Viewing Keys must be able to include Receivers and Viewing Keys of experimental types, possibly alongside non-experimental ones. These experimental Receivers or Viewing Keys must be used only by wallets whose users have explicitly opted into the corresponding experiment.

-
-

Viewing Keys

-

A Unified Full Viewing Key (resp. Unified Incoming Viewing Key) can be used in a similar way to a Full Viewing Key (resp. Incoming Viewing Key) as described in the Zcash Protocol Specification 2.

-

For a Transparent P2PKH Address that is derived according to BIP 32 30 and BIP 44 33, the nearest equivalent to a Full Viewing Key or Incoming Viewing Key for a given BIP 44 account is an extended public key, as defined in the section “Extended keys” of BIP 32. Therefore, UFVKs and UIVKs should be able to include such extended public keys.

-

A wallet should support deriving a UIVK from a UFVK, and a Unified Address from a UIVK.

-
-

Open Issues and Known Concerns

-

Privacy impacts of transparent or cross-pool transactions, and the associated UX issues, will be addressed in ZIP 315 (in preparation).

-
-
-

Specification

-

Revisions

-
    -
  • Revision 0: The initial version of this specification.
  • -
- -

A Revision 0 UA/UVK is distinguished from a Revision 1 UA/UVK by its Human-Readable Part, as follows.

-

Let prefix be:

-
    -
  • u”, if this is a UA/UVK prior to Revision 1;
  • -
  • ur”, if this is a UA/UVK from Revision 1 onward.
  • -
-

The Human-Readable Parts (as defined in 36) of Unified Addresses are defined as:

-
    -
  • prefix, for Unified Addresses on Mainnet;
  • -
  • prefix || “test”, for Unified Addresses on Testnet.
  • -
-

The Human-Readable Parts of Unified Viewing Keys are defined as:

-
    -
  • prefix || “ivk” for Unified Incoming Viewing Keys on Mainnet;
  • -
  • prefix || “ivktest” for Unified Incoming Viewing Keys on Testnet;
  • -
  • prefix || “view” for Unified Full Viewing Keys on Mainnet;
  • -
  • prefix || “viewtest” for Unified Full Viewing Keys on Testnet.
  • -
-

While support for Revision 1 UAs/UVKs is still being rolled out across the Zcash ecosystem, a Producer can maximize interoperability by generating a Revision 0 UA/UVK in cases where the conditions on its use are met (i.e. there are no MUST-understand Metadata Items, and at least one shielded item). At some point when Revision 1 UA/UVKs are widely supported, this will be unnecessary and it will be sufficient to always produce Revision 1 UA/UVKs.

-
-

Encoding of Unified Addresses

-

Rather than defining a Bech32 string encoding of Orchard Shielded Payment Addresses, we instead define a Unified Address format that is able to encode a set of Receivers of different types. This enables the Consumer of a Unified Address to choose the Receiver of the best type it supports, providing a better user experience as new Receiver Types are added in the future.

-

Assume that we are given a set of one or more Receiver Encodings for distinct types. That is, the set may optionally contain one Receiver of each of the Receiver Types in the following fixed Priority List:

-
    -
  • Typecode - \(\mathtt{0x03}\) - — an Orchard raw address as defined in 11;
  • -
  • Typecode - \(\mathtt{0x02}\) - — a Sapling raw address as defined in 10;
  • -
  • 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 specification of the experiment MAY include additions to the above Priority List (such additions SHOULD maintain the intent of preferring more recent shielded protocols).

-

We say that a Receiver Type is “preferred” over another when it appears earlier in this Priority List (as potentially modified by experiments).

-

The Sender of a payment to a Unified Address MUST use the Receiver of the most preferred Receiver Type that it supports from the set.

-

For example, consider a wallet that supports sending funds to Orchard Receivers, and does not support sending to any Receiver Type that is preferred over Orchard. If that wallet is given a UA that includes an Orchard Receiver and possibly other Receivers, it MUST send to the Orchard Receiver.

-

The raw encoding of a Unified Address is a concatenation of - \((\mathtt{typecode}, \mathtt{length}, \mathtt{addr})\) - encodings of the constituent Receivers, in ascending order of Typecode:

-
    -
  • - \(\mathtt{typecode} : \mathtt{compactSize}\) - — the Typecode from the above Priority List;
  • -
  • - \(\mathtt{length} : \mathtt{compactSize}\) - — the length in bytes of - \(\mathtt{addr};\) -
  • -
  • - \(\mathtt{addr} : \mathtt{byte[length]}\) - — the Receiver Encoding.
  • -
-

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 - \(\mathtt{length}\) - in practice.)

-

A Receiver Encoding is the raw encoding of a Shielded Payment Address, or the - \(160\!\) - -bit script hash of a P2SH address 38, or the - \(160\!\) - -bit validating key hash of a P2PKH address 37.

-

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 - \(\mathsf{F4Jumble}\) - algorithm as described in Jumbling. (In order for the limitation on 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 36, ignoring any length restrictions. This is chosen over Bech32 in order to better handle variable-length inputs.

-

To decode a Unified Address Encoding, a Consumer MUST use the following procedure:

-
    -
  • Decode using Bech32m, rejecting any address with an incorrect checksum.
  • -
  • 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; otherwise reject.
  • -
  • Parse the result as a raw encoding as described above, rejecting the entire Unified Address if it does not parse correctly.
  • -
-

The Human-Readable Part is as specified for a Unified Address in Revisions.

-

A wallet MAY allow its user(s) to configure which Receiver Types it can send to. It MUST NOT allow the user(s) to change the order of the Priority List used to choose the Receiver Type, except by opting into experiments.

-
-

Encoding of Unified Full/Incoming Viewing Keys

-

Unified Full or Incoming Viewing Keys are encoded and decoded analogously to Unified Addresses. A Consumer MUST use the decoding procedure from the previous section. For Viewing Keys, a Consumer will normally take the union of information provided by all contained Receivers, and therefore the Priority List defined in the previous section is not used.

-

For each FVK Type or IVK Type currently defined in this specification, the same Typecode is used as for the corresponding Receiver Type in a Unified Address. Additional FVK Types and IVK Types MAY be defined in future, and these will not necessarily use the same Typecode as the corresponding Unified Address.

-

The following FVK or IVK Encodings are used in place of the - \(\mathtt{addr}\) - field:

-
    -
  • 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 - \(\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 15. 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 - \(\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 - \(\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 30 and BIP 44 33, the FVK and IVK Encodings have 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 31.) However, the FVK uses the key at the Account level, i.e. at path - \(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\) - .
  • -
-

The Human-Readable Part is as specified for a Unified Viewing Key in Revisions.

-

Rationale for address derivation

-
-Click to show/hide -

The design of address derivation is designed to maintain unlinkability between addresses derived from the same UIVK, to the extent possible. (This is only partially achieved if the UA contains a Transparent P2PKH Address, since the on-chain transaction graph can potentially be used to link transparent addresses.)

-

Note that it may be difficult to retain this property for Metadata Items, and this should be taken into account in the design of such Items.

-
-
-

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 - \(\mathtt{0x02}\) - and - \(\mathtt{0x03}\) - ). This requirement is dropped for Revision 1 UA/UVKs.
  • -
  • The - \(\mathtt{typecode}\) - and - \(\mathtt{length}\) - fields are encoded as - \(\mathtt{compactSize}.\) - 39 (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.)
  • -
  • Within a single UA or UVK, all HD-derived Receivers, FVKs, and IVKs SHOULD represent an Address or Viewing Key for the same account (as used in the ZIP 32 or BIP 44 Account level).
  • -
  • 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 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.
  • -
  • If the encoding of a Unified Address/Viewing Key is shown to a user in an abridged form due to lack of space, at least the first 20 characters MUST be included.
  • -
-

Rationale for dropping the "at least one shielded Item" restriction

-
-Click to show/hide -

The original rationale for this restriction was that the existing P2SH and P2PKH transparent-only address formats, and the existing P2PKH extended public key format, sufficed for representing transparent Items and were already supported by the existing ecosystem.

-

However, as of Revision 1 there are uses for transparent-only UAs and UVKs that are not covered by the existing formats. In particular, they can use Metadata Items to represent expiration heights/dates as described in Address Expiration Metadata, or source restrictions as proposed in ZIP 320 28.

-
-

Rationale for Item ordering

-
-Click to show/hide -

The rationale for requiring Items to be canonically ordered by Typecode is that it enables implementations to use an in-memory representation that discards ordering, while retaining the same round-trip serialization of a UA/UVK (provided that unrecognised Items are retained).

-
-

Rationale for showing at least the first 20 characters

-
-Click to show/hide -

Showing fewer than 20 characters of the String Encoding of a UA/UVK would potentially allow practical attacks in which the adversary constructs another UA/UVK that matches in the characters shown. When a UA/UVK is abridged it is preferable to show a prefix rather than some other part, both for a more consistent user experience across wallets, and because security analysis of the cost of partial UA/UVK string matching attacks is more complicated if checksum characters are included in the characters that are compared.

-
-
-

Adding new types

-

It is intended that new Receiver Types and Viewing Key Types SHOULD be introduced either by a modification to this ZIP or by a new ZIP, in accordance with the ZIP Process 14.

-

For experimentation prior to proposing a ZIP, experimental types MAY 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 allocated a Typecode outside this reserved range) or discontinued.

-

New types SHOULD maintain the same distinction between FVK and IVK authority as existing types, i.e. an FVK is intended to give access to view all transactions to and from the address, while an IVK is intended to give access only to view incoming payments (as opposed to change).

-
-

Metadata Items

-

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).

-

As of Revision 1 of this ZIP, the subset of Metadata Typecodes in 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.

-

A Revision 0 UA/UVK (determined by its HRP as specified in Revisions) MUST NOT include any Metadata Items with a MUST-understand Typecode; a Consumer MUST reject as invalid any UA/UVK that violates this requirement.

-

Since Metadata Items are not Receivers, they MUST NOT be selected by a Sender when choosing a Receiver to send to, and since they are not Viewing Keys, they MUST NOT provide additional authority to view information about transactions.

-

New Metadata Types SHOULD be introduced either by a modification to this ZIP or by a new ZIP, in accordance with the ZIP Process 14.

-

Rationale for making Revision 0 UA/UVKs with MUST-understand Typecodes invalid

-
-Click to show/hide -

A Consumer implementing this ZIP prior to Revision 1 will not recognise the Human-Readable Parts beginning with “ur” that mark a Revision 1 UA/UVK. So if a UA/UVK that includes MUST-understand Typecodes is required to use these Revision 1 HRPs, this will ensure that the MUST-understand specification is correctly enforced even for such implementations.

-
-
-

Address Expiration Metadata

-

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 - \(\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 - \(\mathtt{0xE0}\) - MUST be considered expired when the height of the Zcash chain is greater than this value.

-

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 - \(\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 a non-zero nExpiryHeight field in transactions it creates that are sent to a Unified Address that defines an Address Expiry Height. If the nExpiryHeight normally constructed by the Sender would be greater than 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 - \(\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 all of the Address Expiry constraints imposed by the individual addresses apply.

-

If a wallet user attempts to send to an expired address, the error presented to the user by the wallet SHOULD include a suggestion that the user should attempt to obtain a currently-valid address for the intended recipient. A wallet MUST NOT send to an address that it knows to have expired.

-

Address expiration imposes no constraints on the Producer of an address. A Producer MAY generate multiple Unified Addresses with the same Receivers but different expiration metadata and/or any number of distinct Diversified Unified Addresses with the same or different expiry metadata, in any combination. Note 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 - \(\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 - \(\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}\) - , 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.

-

Producers of Diversified Unified Addresses should be aware that the expiration metadata could potentially be used to link addresses from the same source. Normally, if Diversified Unified Addresses derived from the same UIVK contain only Sapling and/or Orchard Receivers and no Metadata Items, they will be unlinkable as described in 8; this property does not hold when Metadata Items are present. It is RECOMMENDED that when deriving Unified Addresses from a UFVK or UIVK containing expiry metadata that the Expiry Height and Expiry Time of each distinct address vary from one another, so as to reduce the likelihood that addresses may be linked via their expiry metadata.

-

Rationale

-

The intent of this specification is that Consumers of Unified Addresses must not send to expired addresses. If only an Address Expiry Time is specified, a transaction to the associated address could be mined after the Address Expiry Time within a 24-hour window.

-

The reason that the transaction MUST NOT be sent when its nExpiryHeight as normally constructed is greater than the Address Expiry Height is to avoid unnecessary information leakage in that field about which address was used as the destination. If a sender were to instead use the expiry height to directly set the nExpiryHeight field, this would leak the expiry information of the destination address, which may then be identifiable.

-

When honoring an Address Expiry Time, the reason that a sender SHOULD choose a nExpiryHeight that is expected to occur within 24 hours of the time of transaction construction is to, when possible, ensure that the expiry time is respected to within a day. Address Expiry Times are advisory and do not represent hard bounds because computer clocks often disagree, but every effort should be made to ensure that transactions expire instead of being mined more than 24 hours after a recipient address's expiry time. When chain height information is available to the Sender, it is both permissible and advisable to set this bound more tightly; a common expiry delta used by many wallets is 40 blocks from the current chain tip, as suggested in ZIP 203 24.

-
-
-

Deriving Internal Keys

-

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

-

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

-
    -
  • A holder of an FVK can derive external and internal IVKs, and external and internal - \(\mathsf{ovk}\) - components.
  • -
  • A holder of the external IVK cannot derive the internal IVK, or any of the - \(\mathsf{ovk}\) - components.
  • -
  • A holder of the external - \(\mathsf{ovk}\) - component cannot derive the internal - \(\mathsf{ovk}\) - component, or any of the IVKs.
  • -
-

For shielded keys, these properties are achieved by the one-wayness of - \(\mathsf{PRF^{expand}}\) - and of - \(\mathsf{CRH^{ivk}}\) - or - \(\mathsf{Commit^{ivk}}\) - (for Sapling and Orchard respectively). Derivation of an internal shielded FVK from an external shielded FVK is specified in the "Sapling internal key derivation" 18 and "Orchard internal key derivation" 20 sections of ZIP 32.

-

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

-
    -
  • Let - \(I_\mathsf{ovk} = \mathsf{PRF^{expand}}_{\mathsf{LEOS2BSP}_{256}(\mathsf{c})}\big([\mathtt{0xd0}] \,||\, \mathsf{ser_P}(\mathsf{pk})\big)\) - where - \(\mathsf{ser_P}(pk)\) - is - \(33\) - bytes, as specified in 31.
  • -
  • Let - \(\mathsf{ovk_{external}}\) - be the first - \(32\) - bytes of - \(I_\mathsf{ovk}\) - and let - \(\mathsf{ovk_{internal}}\) - be the remaining - \(32\) - bytes of - \(I_\mathsf{ovk}\) - .
  • -
-

Since an external P2PKH FVK encodes the chain code and public key at the Account level, we can derive both external and internal child keys from it, as described in BIP 44 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.

-
-

Deriving a UIVK from a UFVK

-

As a consequence of the specification in MUST-understand Typecodes, as of Revision 1 a Consumer of a UFVK MUST understand the meaning of all "MUST-understand" Metadata Item Typecodes present in the UFVK in order to derive a UIVK from it.

-

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

-

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

-

The following derivations are applied to each component FVK:

-
    -
  • For a Sapling FVK, the corresponding Sapling IVK is obtained as specified in 4.
  • -
  • For an Orchard FVK, the corresponding Orchard IVK is obtained as specified in 5.
  • -
  • For a Transparent P2PKH FVK, the corresponding Transparent P2PKH IVK is obtained by deriving the child key with non-hardened index - \(0\) - as described in 32.
  • -
-

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

-

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

-
-

Deriving a Unified Address from a UIVK

-

As a consequence of the specification in MUST-understand Typecodes, as of Revision 1 a Consumer of a UIVK MUST understand the meaning of all "MUST-understand" Metadata Item Typecodes present in the UIVK in order to derive a Unified Address from it.

-

If the source UIVK is Revision 1 then the derived Unified Address SHOULD be Revision 1; if the source UIVK includes any Metadata Items then the derived Unified Address MUST be Revision 1.

-

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

-

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

-
    -
  • A Sapling diversifier index MUST generate a valid diversifier as defined in ZIP 32 section “Sapling diversifier derivation” 17.
  • -
  • 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.
  • -
-

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.
  • -
  • For an Orchard IVK, the corresponding Orchard Receiver is obtained as specified in 5.
  • -
  • For a Transparent P2PKH IVK, the diversifier index is used as a BIP 44 child key index at the Index level 35 to derive the corresponding Transparent P2PKH Receiver. As is usual for derivations below the BIP 44 Account level, non-hardened (public) derivation 32 MUST be used. The IVK is assumed to correspond to the extended public key for the external (non-change) element of the path. That is, if the UIVK was constructed correctly then the BIP 44 path of the Transparent P2PKH Receiver will be - \(m / 44' / \mathit{coin\_type\kern0.05em'} / \mathit{account\kern0.1em'} / 0 / \mathit{diversifier\_index}.\) -
  • -
-

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

-

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

-

See Address Expiration Metadata for discussion of potential linking of Diversified Unified Addresses via their metadata.

-
-

Usage of Outgoing Viewing Keys

-

When a Sender constructs a transaction that creates Sapling or Orchard notes, it uses an outgoing viewing key, as described in 6 and 7, to encrypt an outgoing ciphertext. Decryption with the outgoing viewing key allows recovering the sent note plaintext, including destination address, amount, and memo. The intention is that this outgoing viewing key should be associated with the source of the funds.

-

However, the specification of which outgoing viewing key should be used is left somewhat open in 6 and 7; in particular, it was unclear whether transfers should be considered as being sent from an address, or from a ZIP 32 account 21. The adoption of multiple shielded protocols that support outgoing viewing keys (i.e. Sapling and Orchard) further complicates this question, since from NU5 activation, nothing at the consensus level prevents a wallet from spending both Sapling and Orchard notes in the same transaction. (Recommendations about wallet usage of multiple pools will be given in ZIP 315 27.)

-

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

-

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

-

The Sender also determines a "preferred sending protocol" —one of "transparent", "Sapling", or "Orchard"— corresponding to the most preferred Receiver Type (as given in Encoding of Unified Addresses) of any funds sent in the transaction.

-

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

-

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

-
-

Jumbling

-

Security goal (near second preimage resistance):

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

Security goal (nonmalleability):

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

Discussion

-

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

-

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

-

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

-
-

Solution

-

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

-

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

-

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

-

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

-
    -
  • let - \(\ell_L = \mathsf{min}(\ell_H, \mathsf{floor}(\ell_M/2))\) -
  • -
  • let - \(\ell_R = \ell_M - \ell_L\) -
  • -
  • split - \(M\) - into - \(a\) - of length - \(\ell_L\) - bytes and - \(b\) - of length - \(\ell_R\) - bytes
  • -
  • let - \(x = b \oplus G_0(a)\) -
  • -
  • let - \(y = a \oplus H_0(x)\) -
  • -
  • let - \(d = x \oplus G_1(y)\) -
  • -
  • let - \(c = y \oplus H_1(d)\) -
  • -
  • return - \(c \,||\, d.\) -
  • -
-

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

-

The first argument to BLAKE2b below is the personalization.

-

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

-

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

-
- -
Diagram of 4-round unkeyed Feistel construction
-
-

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

-
-

Usage for Unified Addresses, UFVKs, and UIVKs

-

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

-

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

-
-

Rationale for length restrictions

-
-Click to show/hide -

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

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

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

-

Allowing only a Transparent P2PKH Receiver is consistent with dropping the requirement to have at least one shielded Item in Revision 1 UA/UVKs (see rationale).

-

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

-
-

Heuristic analysis

-

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 - \((a \,||\, b, c \,||\, d),\) - and that the input to - \(H_0\) - is - \(x.\) - By fixing - \(x,\) - we can obtain another pair - \(((a \oplus t) \,||\, b', (c \oplus t) \,||\, d')\) - such that - \(a \oplus t\) - is close to - \(a\) - and - \(c \oplus t\) - is close to - \(c.\) - ( - \(b'\) - and - \(d'\) - will not be close to - \(b\) - and - \(d,\) - but that isn't necessarily required for a valid attack.)

-

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

-
    -
  • if - \((x', y')\) - are fixed to the same values as - \((x, y),\) - then - \((a', b', c', d') = (a, b, c, d);\) -
  • -
  • if - \(x' = x\) - but - \(y' \neq y,\) - then the adversary is able to introduce a controlled - \(\oplus\!\) - -difference - \(a \oplus a' = y \oplus y',\) - but the other three pieces - \((b, c, d)\) - are all randomized, which is sufficient;
  • -
  • if - \(y' = y\) - but - \(x' \neq x,\) - then the adversary is able to introduce a controlled - \(\oplus\!\) - -difference - \(d \oplus d' = x \oplus x',\) - but the other three pieces - \((a, b, c)\) - are all randomized, which is sufficient;
  • -
  • if - \(x' \neq x\) - and - \(y' \neq y,\) - all four pieces are randomized.
  • -
-

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

-

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

-

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

-
-

Efficiency

-

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 - \(\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 - \(128 < \ell_M \leq 192,\) - and 10 BLAKE2b compressions for - \(192 < \ell_M \leq 256,\) - for example. The maximum cost for which the algorithm is defined would be 196608 BLAKE2b compressions at - \(\ell_M = \ell^\mathsf{MAX}_M\) - bytes.

-

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

-

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

-
-

Dependencies

-

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

-
- -
-
-

Reference implementation

-

Revision 0: * https://github.com/zcash/librustzcash/pull/352 * https://github.com/zcash/librustzcash/pull/416

-

Revision 1: * https://github.com/zcash/librustzcash/pull/1135

-
-

Acknowledgements

-

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

-
-

References

- - - - - - - -
1Information 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"
- - - - - - - -
2Zcash Protocol Specification, Version 2023.4.0 or later
- - - - - - - -
3Zcash Protocol Specification, Version 2023.4.0. Section 2: Notation
- - - - - - - -
4Zcash Protocol Specification, Version 2023.4.0. Section 4.2.2: Sapling Key Components
- - - - - - - -
5Zcash Protocol Specification, Version 2023.4.0. Section 4.2.3: Orchard Key Components
- - - - - - - -
6Zcash Protocol Specification, Version 2023.4.0. Section 4.7.2: Sending Notes (Sapling)
- - - - - - - -
7Zcash Protocol Specification, Version 2023.4.0. Section 4.7.3: Sending Notes (Orchard)
- - - - - - - -
8Zcash Protocol Specification, Version 2023.4.0. Section 5.4.1.6: DiversifyHash^Sapling and DiversifyHash^Orchard Hash Functions
- - - - - - - -
9Zcash Protocol Specification, Version 2023.4.0. Section 5.6: Encodings of Addresses and Keys
- - - - - - - -
10Zcash Protocol Specification, Version 2023.4.0. Section 5.6.3.1: Sapling Payment Addresses
- - - - - - - -
11Zcash Protocol Specification, Version 2023.4.0. Section 5.6.4.2: Orchard Raw Payment Addresses
- - - - - - - -
12Zcash Protocol Specification, Version 2023.4.0. Section 5.6.4.3: Orchard Raw Incoming Viewing Keys
- - - - - - - -
13Zcash Protocol Specification, Version 2023.4.0. Section 5.6.4.4: Orchard Raw Full Viewing Keys
- - - - - - - -
14ZIP 0: ZIP Process
- - - - - - - -
15ZIP 32: Shielded Hierarchical Deterministic Wallets — Sapling helper functions
- - - - - - - -
16ZIP 32: Shielded Hierarchical Deterministic Wallets — Sapling extended full viewing keys
- - - - - - - -
17ZIP 32: Shielded Hierarchical Deterministic Wallets — Sapling diversifier derivation
- - - - - - - -
18ZIP 32: Shielded Hierarchical Deterministic Wallets — Sapling internal key derivation
- - - - - - - -
19ZIP 32: Shielded Hierarchical Deterministic Wallets — Orchard child key derivation
- - - - - - - -
20ZIP 32: Shielded Hierarchical Deterministic Wallets — Orchard internal key derivation
- - - - - - - -
21ZIP 32: Shielded Hierarchical Deterministic Wallets — Specification: Wallet usage
- - - - - - - -
22ZIP 32: Shielded Hierarchical Deterministic Wallets — Sapling key path
- - - - - - - -
23ZIP 32: Shielded Hierarchical Deterministic Wallets — Orchard key path
- - - - - - - -
24ZIP 203: Transaction Expiry — Changes for Blossom
- - - - - - - -
25ZIP 211: Disabling Addition of New Value to the Sprout Chain Value Pool
- - - - - - - -
26ZIP 224: Orchard Shielded Protocol
- - - - - - - -
27ZIP 315: Best Practices for Wallet Handling of Multiple Pools
- - - - - - - -
28ZIP 320: Defining an Address Type to which funds can only be sent from Transparent Addresses
- - - - - - - -
29ZIP 321: Payment Request URIs
- - - - - - - -
30BIP 32: Hierarchical Deterministic Wallets
- - - - - - - -
31BIP 32: Hierarchical Deterministic Wallets — Serialization Format
- - - - - - - -
32BIP 32: Hierarchical Deterministic Wallets — Child key derivation (CKD) functions: Public parent key → public child key
- - - - - - - -
33BIP 44: Multi-Account Hierarchy for Deterministic Wallets
- - - - - - - -
34BIP 44: Multi-Account Hierarchy for Deterministic Wallets — Path levels: Change
- - - - - - - -
35BIP 44: Multi-Account Hierarchy for Deterministic Wallets — Path levels: Index
- - - - - - - -
36BIP 350: Bech32m format for v1+ witness addresses
- - - - - - - -
37Transactions: P2PKH Script Validation — Bitcoin Developer Guide
- - - - - - - -
38Transactions: P2SH Scripts — Bitcoin Developer Guide
- - - - - - - -
39Variable length integer. Bitcoin Wiki
-
-
- - \ No newline at end of file diff --git a/rendered/zip-0317.html b/rendered/zip-0317.html deleted file mode 100644 index 1ada72c08..000000000 --- a/rendered/zip-0317.html +++ /dev/null @@ -1,563 +0,0 @@ - - - - ZIP 317: Proportional Transfer Fee Mechanism - - - - -
-
ZIP: 317
-Title: Proportional Transfer Fee Mechanism
-Owners: Aditya Bharadwaj <nighthawk24@gmail.com>
-        Daira-Emma Hopwood <daira-emma@electriccoin.co>
-Credits: Madars Virza
-         Kris Nuttycombe
-         Jack Grigg
-         Francisco Gindre
-Status: Active
-Category: Standards / Wallet
-Obsoletes: ZIP 313
-Created: 2022-08-15
-License: MIT
-Discussions-To: <https://forum.zcashcommunity.com/t/zip-proportional-output-fee-mechanism-pofm/42808>
-Pull-Request: <https://github.com/zcash/zips/pull/631>
-

Terminology

-

The key words "SHOULD", "SHOULD NOT", "RECOMMENDED", 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 "conventional transaction fee" in this document is in reference to the value of a transaction fee that is conventionally used by wallets, and that a user can reasonably expect miners on the Zcash network to accept for including a transaction in a block.

-

The terms "Mainnet", "Testnet", and "zatoshi" in this document are defined as in 2.

-
-

Abstract

-

The goal of this ZIP is to change the conventional fees for transactions by making them dependent on the number of inputs and outputs in a transaction, and to get buy-in for this change from wallet developers, miners and Zcash users.

-
-

Motivation

-

In light of recent Mainnet network activity, it is time to review and update the standard 1,000 zatoshi transaction fee set in ZIP 313 6.

-

The conventional transaction fee presently is 0.00001 ZEC or 1,000 zatoshis, as specified in ZIP 313. This allowed exploration of novel use cases of the Zcash blockchain. The Zcash network has operated for almost 2 years at a conventional transaction fee of 1,000 zatoshis, without consideration for the total number of inputs and outputs in each transaction. Under this conventional fee, some usage of the chain has been characterized by high-output transactions with 1,100 outputs, paying the same conventional fee as a transaction with 2 outputs.

-

The objective of the new fee policy, once it is enforced, is for fees paid by transactions to fairly reflect the processing costs that their inputs and outputs impose on various participants in the network. This will tend to discourage usage patterns that cause either intentional or unintentional denial of service, while still allowing low fees for regular transaction use cases.

-
-

Requirements

-
    -
  • The conventional fee formula should not favour or discriminate against any of the Orchard, Sapling, or transparent protocols.
  • -
  • The fee for a transaction should scale linearly with the number of inputs and/or outputs.
  • -
  • Users should not be penalised for sending transactions constructed with padding of inputs and outputs to reduce information leakage. (The default policy employed by zcashd and the mobile SDKs pads to two inputs and two outputs for each shielded pool used by the transaction).
  • -
  • Users should be able to spend a small number of UTXOs or notes with value below the marginal fee per input.
  • -
-
-

Specification

-

Notation

-

Let - \(\mathsf{min}(a, b)\) - be the lesser of - \(a\) - and - \(b\!\) - .
Let - \(\mathsf{max}(a, b)\) - be the greater of - \(a\) - and - \(b\!\) - .
Let - \(\mathsf{floor}(x)\) - be the largest integer - \(\leq x\!\) - .
Let - \(\mathsf{ceiling}(x)\) - be the smallest integer - \(\geq x\!\) - .

-
-

Fee calculation

-

This specification defines several parameters that are used to calculate the conventional fee:

- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
ParameterValueUnits
- \(marginal\_fee\) - - \(5000\) - zatoshis per logical action (as defined below)
- \(grace\_actions\) - - \(2\) - logical actions
- \(p2pkh\_standard\_input\_size\) - - \(150\) - bytes
- \(p2pkh\_standard\_output\_size\) - - \(34\) - bytes
-

Wallets implementing this specification SHOULD use a conventional fee calculated in zatoshis per the following formula:

-
\(\begin{array}{rcl} - contribution_{\,\mathsf{Transparent}} &=& - \mathsf{max}\big(\mathsf{ceiling}\big(\frac{tx\_in\_total\_size}{p2pkh\_standard\_input\_size}\big),\, - \mathsf{ceiling}\big(\frac{tx\_out\_total\_size}{p2pkh\_standard\_output\_size}\big)\big) \\ - contribution_{\,\rlap{\mathsf{Sprout}}\phantom{\mathsf{Transparent}}} &=& 2 \cdot nJoinSplit \\ - contribution_{\,\rlap{\mathsf{Sapling}}\phantom{\mathsf{Transparent}}} &=& \mathsf{max}(nSpendsSapling,\, nOutputsSapling) \\ - contribution_{\,\rlap{\mathsf{Orchard}}\phantom{\mathsf{Transparent}}} &=& nActionsOrchard \\ - \\ - logical\_actions &=& contribution_{\,\mathsf{Transparent}} + - contribution_{\,\mathsf{Sprout}} + - contribution_{\,\mathsf{Sapling}} + - contribution_{\,\mathsf{Orchard}} \\ - conventional\_fee &=& marginal\_fee \cdot \mathsf{max}(grace\_actions,\, logical\_actions) -\end{array}\)
-

The inputs to this formula are taken from transaction fields defined in the Zcash protocol specification 3:

- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
InputUnitsDescription
- \(tx\_in\_total\_size\) - bytestotal size in bytes of the tx_in field
- \(tx\_out\_total\_size\) - bytestotal size in bytes of the tx_out field
- \(nJoinSplit\) - numberthe number of Sprout JoinSplits
- \(nSpendsSapling\) - numberthe number of Sapling spends
- \(nOutputsSapling\) - numberthe number of Sapling outputs
- \(nActionsOrchard\) - numberthe number of Orchard actions
-

It is not a consensus requirement that fees follow this formula; however, wallets SHOULD create transactions that pay this fee, in order to reduce information leakage, unless overridden by the user.

-

Rationale for logical actions

-
-Click to show/hide -

The intention is to make the fee paid for a transaction depend on its 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 - \(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 to ensure that the number of inputs and outputs are the same. Usage of Sapling and transparent protocols does not require this padding, and so this could have effectively discriminated against Orchard.

-
-

Rationale for the chosen parameters

-
-Click to show/hide -
Grace Actions
-

Why not just charge per-action, without a grace window?

-
    -
  • This ensures that there is no penalty to padding a 1-action transaction to a 2-action transaction. Such padding is desirable to reduce information leakage from input and output arity, and is the standard approach used by zcashd and the mobile SDK 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 - \(marginal\_fee\) - is worth including, if a second input is available that covers both the primary output amount and the conventional transaction fee.
  • -
-

Why a grace window of 2?

-

A 1-in, 2-out (or 2-action) transaction is the smallest possible 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 - \(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\) - .

-

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\) - , 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 - \(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.

-
-
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)\) - . 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\) - and - \(p2pkh\_standard\_output\_size\) - are based on the maximum encoded length for P2PKH inputs and outputs, as follows:

-
    -
  • - \(p2pkh\_standard\_input\_size\) -
      -
    • outpoint: 36 bytes
    • -
    • script: 110 bytes -
        -
      • 1 (overall length) + 1 (signature length) + 72 (signature) + 1 (sighash type) + 1 (pubkey length) + 33 (pubkey) + 1 (margin)
      • -
      -
    • -
    • sequence: 4 bytes
    • -
    -
  • -
  • - \(p2pkh\_standard\_output\_size\) -
      -
    • value: 8 bytes
    • -
    • script: 26 bytes -
        -
      • 1 (script length) + 25 (P2PKH script)
      • -
      -
    • -
    -
  • -
-

P2SH outputs are smaller than P2PKH outputs, but P2SH inputs may be larger than P2PKH inputs. For example a 2-of-3 multisig input is around 70% larger, and is counted as such when computing the number of logical actions.

-
-
Marginal Fee
-

This returns the conventional fee for a minimal transaction (as described above) to the original conventional fee of 10000 zatoshis specified in 6, and imposes a non-trivial cost for potential denial-of-service attacks.

-
-
-
-

Transaction relaying

-

zcashd, zebrad, and potentially other node implementations, implement fee-based restrictions on relaying of mempool transactions. Nodes that 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 - \(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 Deployment section for actual behaviour of node implementations).

-
-

Mempool size limiting

-

zcashd and zebrad limit the size of the mempool as described in 7. 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.

-
-

Block production

-

Miners, mining pools, and other block producers, select transactions for inclusion in blocks using a variety of criteria. The algorithm in the following section is planned to be implemented by zcashd and zebrad.

- -

Rationale for block template construction algorithm

-

It is likely that not all wallets will immediately update to pay the (generally higher) fees specified by this ZIP. In order to be able to deploy 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 - \(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 7 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 - \(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 - \(weight\_ratio\_cap\) - times greater than a transaction that pays exactly the conventional fee.
  2. -
  3. Compare the case where the adversary pays - \(c\) - times the conventional fee for one transaction, to that where they pay the conventional fee for - \(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.
  4. -
-

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 - \(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

-

Miners have an incentive to make this change because:

-
    -
  • it will tend to increase the fees they are due;
  • -
  • fees will act as a damping factor on the time needed to process blocks, and therefore on orphan rate.
  • -
-
-
-
-

Security and Privacy considerations

-

Non-standard transaction fees may reveal specific users or wallets or wallet versions, which would reduce privacy for those specific users and the rest of the network. However, the advantage of faster deployment weighed against synchronizing the change in wallet behaviour at a specific block height.

-

Long term, the issue of fees needs to be revisited in separate future proposals as the blocks start getting consistently full. Wallet developers and operators should monitor the Zcash network for rapid growth in transaction rates, and consider further changes to fee selection and/or other scaling solutions if necessary.

-

Denial of Service

-

A transaction-rate-based denial of service attack occurs when an attacker generates enough transactions over a window of time to prevent legitimate transactions from being mined, or to hinder syncing blocks for full nodes or miners.

-

There are two primary protections to this kind of attack in Zcash: the block size limit, and transaction fees. The block size limit ensures that full nodes and miners can keep up with the blockchain even if blocks are completely full. However, users sending legitimate transactions may not have their transactions confirmed in a timely manner.

-

This proposal does not alter how fees are paid from transactions to miners.

-
-
-

Deployment

-

Wallets SHOULD deploy these changes immediately. Nodes SHOULD deploy the change to the - \(low\_fee\_penalty\) - threshold described in Mempool size limiting immediately.

-

Nodes supporting block template construction SHOULD deploy the new Recommended algorithm for block template construction immediately, and miners SHOULD use nodes that have been upgraded to this algorithm.

-

Node developers SHOULD coordinate on schedules for deploying restrictions to their policies for transaction mempool acceptance and peer-to-peer relaying. These policy changes SHOULD NOT be deployed before the changes to block template construction for miners described in the preceding paragraph.

-

Deployment in zcashd

-

zcashd v5.5.0 implemented use of ZIP 317 fees by default for its internal wallet in the following PRs:

- -

zcashd v5.5.0 implemented the Recommended algorithm for block template construction in:

- -

The value used for - \(block\_unpaid\_action\_limit\) - by zcashd can be overridden using the -blockunpaidactionlimit configuration parameter.

-

zcashd v5.5.0 also implemented the change to Mempool size limiting to use the ZIP 317 fee for the low fee penalty threshold, in:

- -

As described in section Transaction relaying, nodes MAY drop transactions with more unpaid actions than a given limit. From zcashd v5.6.0, this is controlled by the -txunpaidactionlimit configuration option, which defaults to 50 unpaid actions (the same default as -blockunpaidactionlimit). This behaviour is implemented in:

- -

Note that zcashd also requires transactions to pay at least a "relay threshold" fee. As part of the ZIP 317 work, this rule was simplified for zcashd v5.5.0:

- -
-

Deployment in zebra

-

zebra does not provide a wallet, and so does not need to calculate ZIP 317 fees in order to construct transactions.

-

zebra v1.0.0-rc.3 implemented the current Recommended algorithm for block template construction in:

- -

zebra v1.0.0-rc.2 had implemented an earlier version of this algorithm. 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:

- -

zebra v1.0.0-rc.8 implemented Transaction relaying changes in:

- -

zebra uses a similar relay threshold rule to zcashd, but additionally enforces a minimum fee of 100 zatoshis (this differs from zcashd only for valid transactions of less than 1000 bytes, assuming that zcashd uses its default value for -minrelaytxfee).

-
-
-

Considered Alternatives

-

This section describes alternative proposals that have not been adopted.

-

In previous iterations of this specification, the marginal fee was multiplied by the sum of inputs and outputs. This means that the alternatives given below are roughly half of what they would be under the current formula.

-

Possible alternatives for the parameters:

-
    -
  • - \(marginal\_fee = 250\) - in @nuttycom's proposal.
  • -
  • - \(marginal\_fee = 1000\) - adapted from @madars' proposal 5.
  • -
  • - \(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 - \(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.)

-
-

Endorsements

-

The following entities and developers of the listed software expressed their support for the updated fee mechanism:

-
    -
  • Zecwallet Suite (Zecwallet Lite for Desktop/iOS/Android & Zecwallet FullNode)
  • -
  • Nighthawk Wallet for Android & iOS
  • -
  • Electric Coin Company
  • -
  • Zcash Foundation
  • -
-
-

Acknowledgements

-

Thanks to Madars Virza for initially proposing a fee mechanism similar to that proposed in this ZIP 5, and for finding a potential weakness in an earlier version of the block template construction algorithm. Thanks also to Kris Nuttycombe, Jack Grigg, Francisco Gindre, Greg Pfeil, Teor, and Deirdre Connolly for reviews and suggested improvements.

-
-

References

- - - - - - - -
1Information 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"
- - - - - - - -
2Zcash Protocol Specification, Version 2022.3.8. Section 3.12: Mainnet and Testnet
- - - - - - - -
3Zcash Protocol Specification, Version 2022.3.8. Section 7.1: Transaction Encoding and Consensus
- - - - - - - -
4zcash/zips issue #568 - Document block transparent sigops limit consensus rule
- - - - - - - -
5Madars concrete soft-fork proposal
- - - - - - - -
6ZIP 313: Reduce Conventional Transaction Fee to 1000 zatoshis
- - - - - - - -
7ZIP 401: Addressing Mempool Denial-of-Service
-
-
- - \ No newline at end of file diff --git a/rendered/zip-0318.html b/rendered/zip-0318.html deleted file mode 100644 index 1bf2b988a..000000000 --- a/rendered/zip-0318.html +++ /dev/null @@ -1,20 +0,0 @@ - - - - ZIP 318: Associated Payload Encryption - - - -
-
ZIP: 318
-Title: Associated Payload Encryption
-Owners: Kris Nuttycombe <kris@electriccoin.co>
-        Daira-Emma Hopwood <daira-emma@electriccoin.co>
-Status: Reserved
-Category: Standards Track
-Created: 2022-09-19
-License: MIT
-Discussions-To: <https://github.com/zcash/zips/issues/633>
-
- - \ No newline at end of file diff --git a/rendered/zip-0319.html b/rendered/zip-0319.html deleted file mode 100644 index 6d801d6b0..000000000 --- a/rendered/zip-0319.html +++ /dev/null @@ -1,20 +0,0 @@ - - - - ZIP 319: Options for Shielded Pool Retirement - - - -
-
ZIP: 319
-Title: Options for Shielded Pool Retirement
-Owners: Nathan Wilcox <nathan@electriccoin.co>
-        Daira-Emma Hopwood <daira-emma@electriccoin.co>
-Status: Reserved
-Category: Informational
-Created: 2022-09-20
-License: MIT
-Discussions-To: <https://github.com/zcash/zips/issues/635>
-
- - \ No newline at end of file diff --git a/rendered/zip-0320.html b/rendered/zip-0320.html deleted file mode 100644 index 0094e0110..000000000 --- a/rendered/zip-0320.html +++ /dev/null @@ -1,236 +0,0 @@ - - - - ZIP 320: Defining an Address Type to which funds can only be sent from Transparent Addresses - - - - -
-
ZIP: 320
-Title: Defining an Address Type to which funds can only be sent from Transparent Addresses
-Owners: Daira-Emma Hopwood <daira-emma@electriccoin.co>
-        Kris Nuttycombe <kris@nutty.land>
-Credits: Hanh
-Status: Proposed
-Category: Standards / Wallet
-Created: 2024-01-12
-License: MIT
-Discussions-To: <https://github.com/zcash/zips/issues/757>
-                <https://github.com/zcash/zips/issues/795>
-Pull-Request: <https://github.com/zcash/zips/pull/760>
-              <https://github.com/zcash/zips/pull/766>
-              <https://github.com/zcash/zips/pull/798>
-

Terminology

-

The key words "MUST", "SHOULD", "NOT RECOMMENDED", 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 terms "Recipient", "Producer", "Consumer", "Sender", "Receiver", "Address", and "Unified Address" are to be interpreted as described in ZIP 316 7.

-

The terms "Testnet" and "Mainnet" are to be interpreted as described in section 3.12 of the Zcash Protocol Specification 10.

-
-

Abstract

-

This ZIP defines a new encoding for transparent Zcash addresses. Wallets must ensure that no shielded notes are spent in transactions that send to a transparent address encoded in the specified fashion.

-
-

Background

-

In November 2023, the Zcash community received notice from the Binance cryptocurrency exchange that Zcash was at risk of being delisted from the exchange unless the community could provide a mechanism by which Binance could refuse deposits from shielded addresses and return them to the depositor. This issue was raised and discussed at length in the Zcash Community forum 2.

-

In the course of that discussion thread, wallet developer and community member @hanh 3 suggested a wallet-oriented approach 4 that involved defining a new encoding for Zcash transparent P2PKH addresses. A Consumer of such an address, whether it be a wallet or an exchange, could recognize this encoding as a directive that the wallet should only spend transparent funds when creating an output to that address. This ZIP formalizes that proposal.

-
-

Motivation

-

The Binance cryptocurrency exchange requires that funds sent to their deposit addresses come from source addresses that are readily identifiable using on-chain information, such that if necessary funds may be rejected by sending them back to one of the source addresses. This ZIP is intended to standardize a transparent address encoding that is not yet understood by preexisting Consumers, in order to prevent inadvertent shielded spends when sending to such addresses. Then, Consumers that upgrade to support the new encoding will do so with the understanding that they must respect the restrictions on sources of funds described in this ZIP.

-

It is not expected that other exchanges or Producers of Zcash addresses will generate Transparent-Source-Only Addresses unless they have a specific need to be able to identify the address or addresses from which a payment was funded. However, all Consumers of Zcash addresses should implement this specification, in order to promote interoperability across the Zcash ecosystem.

-
-

Requirements

-
    -
  1. A Recipient wishing to receive funds from exclusively transparent sources must be able to generate a receiving address such that only transparent funds will be spent in transactions with an output to this address. The purpose of this is to ensure that it is reliably possible for the Recipient to send back funds received from a Sender that conforms to this ZIP.
  2. -
  3. Wallets and other Consumers that have not been upgraded to recognize the new address format cannot mistake the address for another address type or inadvertently send shielded funds to the address.
  4. -
  5. No changes to Recipient infrastructure beyond changes to address encoding and decoding should be required as a consequence of this ZIP. In particular, conversion between a Transparent-Source-Only Address and the corresponding unrestricted transparent address should be possible using only dependencies that are available to Binance's front-end code.
  6. -
-
-

Non-requirements

-
    -
  1. It is only required to support a Transparent-Source-Only form of P2PKH addresses; P2SH address support is not necessary.
  2. -
  3. It is not required to limit the source of transparent funds sent to a Transparent-Source-Only Address to a single source address. This implies that if the Recipient chooses to send back the funds, it is acceptable for it to send them back to any of the source addresses if there is more than one.
  4. -
  5. It is not necessary for the restriction on the source of funds to be enforced as a consensus rule. If a Sender fails to adhere to the restriction, it risks loss of funds, which is acceptable in the case of a non-conforming Sender implementation.
  6. -
-
-

Specification

-

A TEX Address, also called a Transparent-Source-Only Address, is a Bech32m 15 reencoding of a transparent Zcash P2PKH address 11.

-

Wallets and other Senders sending to a TEX address (as any output) MUST ensure that only transparent (P2SH or P2PKH) UTXOs are spent in the creation of the transaction. For simplicity of parsing and interpreting such transactions, they also SHOULD only send to transparent outputs.

-

A TEX address can be produced from a Mainnet Zcash P2PKH Address by executing the following steps:

-
    -
  1. Decode the address to a byte sequence using the Base58Check decoding algorithm 13.
  2. -
  3. 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}]\) - , return an error. Otherwise, let the validating key hash be the remaining 20 bytes of the sequence after removing the two-byte address prefix.
  4. -
  5. Reencode the 20-byte validating key hash using the Bech32m encoding defined in 15 with the human-readable prefix (HRP) "tex".
  6. -
-

For Testnet addresses, the required lead bytes of a P2PKH address in step 2 are - \([\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.:

-
    -
  1. Decode the address to a byte sequence using Bech32m 15, checking that the HRP is "tex" for a Mainnet TEX Address and "textest" for a Testnet TEX Address.
  2. -
  3. If the length of the resulting byte sequence is not 20 bytes, return an error. Otherwise, the validating key hash is this byte sequence.
  4. -
-

Design considerations for Senders

-

For a transaction that spends only from transparent funds to a TEX Address, this specification imposes no additional requirements.

-

If, on the other hand, a user desires to spend shielded funds to a TEX Address, a Sender supporting this ZIP MUST create two transactions: one that unshields the funds to an ephemeral transparent address, and one that spends from that ephemeral address to the destination TEX Address. This does not defeat the intent of the ZIP, because it is still possible for a Recipient to return the funds to the Sender by sending them back to the ephemeral address.

-

Wallets MUST be able to recognize funds that have been returned in this way and spend them if desired. In order for this to be possible without use of TEX Addresses increasing the risk of loss of funds, wallets based on ZIP 32 5 SHOULD choose ephemeral addresses in a way that allows the corresponding private keys to be recovered from a ZIP 32 master seed.

-

However, ephemeral addresses SHOULD NOT be chosen in a way that allows them to be linked between transactions, without knowledge of the wallet seed or the relevant transparent viewing keys. This also implies that they SHOULD be chosen in a way that avoids collisions with addresses for previously generated outputs (including change outputs), such as might have been created by a transparent-only wallet using Bitcoin-derived code based on BIP 44 14.

-

In order to show accurate transaction history to a user, wallets SHOULD remember when a particular transaction output was sent to a TEX Address, so that they can show that form rather than its P2PKH form. It is acceptable that this information may be lost on recovery from seed.

-
-
-

Reference Implementation

-

Javascript:

-
import bs58check from 'bs58check'
-import {bech32m} from 'bech32'
-
-// From t1 to tex
-var b58decoded = bs58check.decode('t1VmmGiyjVNeCjxDZzg7vZmd99WyzVby9yC')
-console.assert(b58decoded.length == 22, 'Invalid length');
-console.assert(b58decoded[0] == 0x1C && b58decoded[1] == 0xB8, 'Invalid address prefix');
-var pkh = b58decoded.slice(2)
-var tex = bech32m.encode('tex', bech32m.toWords(pkh))
-console.log(tex)
-
-// From tex to t1
-var bech32decoded = bech32m.decode('tex1s2rt77ggv6q989lr49rkgzmh5slsksa9khdgte')
-console.assert(bech32decoded.prefix == 'tex', 'Invalid address prefix')
-var pkh2 = Uint8Array.from(bech32m.fromWords(bech32decoded.words))
-console.assert(pkh2.length == 20, 'Invalid length');
-var t1 = bs58check.encode(Buffer.concat([Uint8Array.from([0x1C, 0xB8]), pkh2]))
-console.log(t1)
-
-

Rationale

-

TEX addresses are the simplest possible approach to creating a new address type that indicates that only transparent sources of funds should be used.

-

As required by Binance, it will be possible to convert between a TEX address and an unrestricted transparent P2PKH address using extremely straightforward code that depends only on Base58Check and Bech32m encoding/decoding, as shown in the above Reference Implementation.

-

An earlier version of this ZIP also described another alternative using metadata in Unified Addresses, as specified in ZIP 316 6. That alternative was designed to enable better integration with the Zcash Unified Address ecosystem, and had the advantage of being able to combine different types of metadata along with the Transparent-Source-Only indicator, such as an expiration block height or time 9 12.

-

However, ultimately the Unified Address-based approach did not meet all of the requirements, since it would in practice have required dependencies on address handling libraries that Binance did not want to depend on in their front-end code.

-

Some design elements of that approach that apply to metadata in general have been incorporated into ZIP 316 Revision 1 8. A more general form of Source Restriction Metadata is also under consideration.

-

Disadvantages

-

A disadvantage of TEX Addresses (and also of the alternative approach using Unified Addresses) is that the information that a TEX Address was used does not appear on-chain, i.e. a transaction sending to a TEX Address is indistinguishable from one sending to the underlying P2PKH address. This is inevitable given the desire not to change the underlying consensus protocol to support this functionality.

-
-
-

References

- - - - - - - -
1Information 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"
- - - - - - - -
2Zcash Community Forum thread "Important: Potential Binance Delisting"
- - - - - - - -
3Zcash Community Forum user @hanh
- - - - - - - -
4Ywallet developer @hanh's proposal
- - - - - - - -
5ZIP 32: Shielded Hierarchical Deterministic Wallets
- - - - - - - -
6ZIP 316: Unified Addresses and Unified Viewing Keys
- - - - - - - -
7ZIP 316: Unified Addresses and Unified Viewing Keys — Terminology
- - - - - - - -
8ZIP 316: Unified Addresses and Unified Viewing Keys — Revision 1
- - - - - - - -
9ZIP 316: Unified Addresses and Unified Viewing Keys — Address Expiration Metadata
- - - - - - - -
10Zcash Protocol Specification, Version 2023.4.0. Section 3.12: Mainnet and Testnet
- - - - - - - -
11Zcash Protocol Specification, Version 2023.4.0. Section 5.6.1.1 Transparent Addresses
- - - - - - - -
12Zcash Community Forum post describing motivations for address expiry
- - - - - - - -
13Base58Check encoding — Bitcoin Wiki
- - - - - - - -
14BIP 44: Multi-Account Hierarchy for Deterministic Wallets
- - - - - - - -
15BIP 350: Bech32m format for v1+ witness addresses
-
-
- - \ No newline at end of file diff --git a/rendered/zip-0321.html b/rendered/zip-0321.html deleted file mode 100644 index 447bcf50e..000000000 --- a/rendered/zip-0321.html +++ /dev/null @@ -1,286 +0,0 @@ - - - - ZIP 321: Payment Request URIs - - - -
-
ZIP: 321
-Title: Payment Request URIs
-Owners: Kris Nuttycombe <kris@electriccoin.co>
-        Daira-Emma Hopwood <daira-emma@electriccoin.co>
-Credits: Francisco Gindre
-Status: Proposed
-Category: Standards / Wallet
-Created: 2020-08-28
-Discussions-To: <https://github.com/zcash/zips/issues/347>
-Pull-Request: <https://github.com/zcash/zips/pull/395>
-License: MIT
-

Terminology

-

The key words "MUST", "REQUIRED", "MUST NOT", "SHOULD", "RECOMMENDED", 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 terms "Testnet" and "Mainnet" are to be interpreted as described in section 3.11 of the Zcash Protocol Specification 12.

-

The terms below are to be interpreted as follows:

-
-
payment
-
A transfer of funds implemented by a shielded or transparent output of a Zcash transaction.
-
payment request
-
A request for a wallet to construct a single Zcash transaction containing one or more payments.
-
-
-

Abstract

-

This ZIP proposes a standard format for payment request URIs. Wallets that recognize this format enable users to construct transactions simply by clicking links on webpages or scanning QR codes.

-
-

Motivation

-

In order for a robust transactional ecosystem to evolve for Zcash, it is necessary for vendors to be able to issue requests for payment. At present, the best option available is to manually specify a payment address, a payment amount, and potentially memo field content. Of these three components, existing wallets only provide functionality for reading payment addresses in a semi-automated fashion. It is then necessary for the user to manually enter payment amounts and any associated memo information, which is tedious and may be error-prone, particularly if a payment is intended for multiple recipients or the memo field information contains structured data that must be faithfully reproduced.

-

This ZIP seeks to eliminate these issues by proposing a standard format that wallet vendors may support so that human intervention is required only for approval, not creation, of such a transaction.

-

In Bitcoin, two different standards exist to permit vendors to issue payment requests that are understood by wallets: BIP 21 5 and BIP 70 6. BIP 21 provides a URI format that can be interpreted by a wallet to construct simple, single-recipient transactions; BIP 70 uses a protobuf-based protocol that permits requests for transactions of arbitrary complexity.

-

The format proposed in this ZIP seeks a middle ground between these approaches: to provide a URI-based format which supports both the trivial use case and the slightly-more-complex situation where a transaction may include payments to multiple recipients.

-
-

Requirements

-

The format must be a valid URI format 3.

-

The format must permit the representation of one or more (payment address, amount, memo) tuples.

-
-

Specification

-

URI Syntax

-

The following syntax specification uses ABNF 2.

-
zcashurn        = "zcash:" ( zcashaddress [ "?" zcashparams ] / "?" zcashparams )
-zcashaddress    = 1*( ALPHA / DIGIT )
-zcashparams     = zcashparam [ "&" zcashparams ]
-zcashparam      = [ addrparam / amountparam / memoparam / messageparam / labelparam / reqparam / otherparam ]
-NONZERO         = %x31-39
-DIGIT           = %x30-39
-paramindex      = "." NONZERO 0*3DIGIT
-addrparam       = "address" [ paramindex ] "=" zcashaddress
-amountparam     = "amount"  [ paramindex ] "=" 1*DIGIT [ "." 1*8DIGIT ]
-labelparam      = "label"   [ paramindex ] "=" *qchar
-memoparam       = "memo"    [ paramindex ] "=" *base64url
-messageparam    = "message" [ paramindex ] "=" *qchar
-paramname       = ALPHA *( ALPHA / DIGIT / "+" / "-" )
-reqparam        = "req-" paramname [ paramindex ] [ "=" *qchar ]
-otherparam      = paramname [ paramindex ] [ "=" *qchar ]
-qchar           = unreserved / pct-encoded / allowed-delims / ":" / "@"
-allowed-delims  = "!" / "$" / "'" / "(" / ")" / "*" / "+" / "," / ";"
-

Here, ALPHA, unreserved and pct-encoded are as defined in 3. "base64url" is defined as in 4 with padding omitted. (Note that this uses a different alphabet to the usual base64; the values 62 and 63 in the alphabet are encoded as - and _ respectively. Implementations MUST NOT accept the characters +, /, and = that occur only in the usual base64.)

-

Productions of the form 1*x indicate one or more successive instances of the production x. Productions of the form <n>*<m>x indicate at least <n> and at most <m> instances of production x.

-

Note that this grammar does not allow percent encoding outside the productions that use qchar, i.e. the values of label, message, reqparam, and otherparam parameters.

-

Purported ZIP 321 URIs that cannot be parsed according to the above grammar MUST NOT be accepted.

-
-

URI Semantics

-

A ZIP-321 URI represents a request for the construction of a transaction having one or more payments. In the case that only a single payment is being requested, the recipient address SHOULD be included in the hier-part component of the RFC 3986 URI; otherwise, multiple recipient addresses can be specified using addrparam parameters with different indices.

-

Addresses, amounts, labels, and messages sharing the same paramindex (including the empty paramindex) are interpreted to be associated with the same payment for the purposes of payment construction. A paramindex MUST NOT have leading zero(s). There is no significance to the ordering of parameters, and paramindex values need not be sequential.

-

Implementations SHOULD construct a single transaction that pays all of the specified instances of zcashaddress. The number of such addresses is therefore limited by restrictions on transaction construction. In general this limit depends, at least, on the mix of destination address types. For example, if all payments were to Sapling payment addresses (each specified either directly or as a Receiver of a Unified Address), the limit described in 13 implies that constructing a transaction for a ZIP-321 URI might fail if it requests more than 2109 distinct payments. The effective limit might be lower if payments to Orchard addresses or other future types of address are included.

-

A URI of the form zcash:<address>?... MUST be considered equivalent to a URI of the form zcash:?address=<address>&... where <address> is an instance of zcashaddress.

-

If there are any non-address parameters having a given paramindex, then the URI MUST contain an address parameter having that paramindex. There MUST NOT be more than one occurrence of a given parameter and paramindex.

-

Implementations SHOULD check that each instance of zcashaddress is a valid string encoding of an address, other than a Sprout address, as specified in the subsections of section 5.6 (Encoding of Addresses and Keys) of the Zcash protocol specification 14. At the time of writing this includes the following address formats:

-
    -
  • a Zcash transparent address, as defined in 15, using Base58Check 8;
  • -
  • a Zcash Sapling payment address as defined in 16, using Bech32 9;
  • -
  • a Zcash Unified Address as defined in 17 and 11, using Bech32m 7.
  • -
-

New address formats may be added to 14 in future, and these SHOULD be supported whether or not this ZIP is updated to explicitly include them.

-

If the context of whether the payment URI is intended for Testnet or Mainnet is available, then each address SHOULD be checked to be for the correct network.

-

All of the requirements of ZIP 316 11 apply in the case of payments to Unified Addresses.

-

Sprout addresses MUST NOT be supported in payment requests. The rationale for this is that transfers to Sprout addresses are, since activation of the Canopy network upgrade, restricted by ZIP 211 10. It cannot generally be expected that senders will have funds available in the Sprout pool with which to satisfy requests for payment to a Sprout address. If the same rationale applies to other address types in future, consideration should be given to updating this ZIP to exclude these types, as part of their deprecation.

-
-

Transfer amount

-

If an amount is provided, it MUST be specified in decimal ZEC. If a decimal fraction is present then a period (.) MUST be used as the separating character to separate the whole number from the decimal fraction, and both the whole number and the decimal fraction MUST be nonempty. No other separators (such as commas for grouping or thousands) are permitted. Leading zeros in the whole number or trailing zeros in the decimal fraction are ignored. There MUST NOT be more than 8 digits in the decimal fraction.

-
-
For example,
-
-
    -
  • amount=50.00 or amount=50 or amount=050 is treated as 50 ZEC;
  • -
  • amount=0.5 or amount=00.500 is treated as 0.5 ZEC; and
  • -
  • amount=50,000.00 or amount=50,00 or amount=50. or amount=.5 or amount=0.123456789 are invalid.
  • -
-
-
-

The amount MUST NOT be greater than 21000000 ZEC (in general, monetary amounts in Zcash cannot be greater than this value).

-
-

Query Keys

-
-
label
-
Label for an address (e.g. name of receiver). If a label is present at a paramindex, a client rendering a payment for inspection by the user SHOULD display this label (if possible) as well as the associated address. If the label is displayed, it MUST be identifiable as distinct from the address.
-
address
-
Zcash address string (shielded or transparent)
-
memo
-
Contents for the Zcash shielded memo field, encoded as base64url without = padding. The decoded memo contents MUST NOT exceed 512 bytes, and if shorter, will be filled with trailing zeros to 512 bytes. Parsers MUST consider the entire URI invalid if the address associated with the same paramindex does not permit the use of memos (i.e. it is a transparent address).
-
message
-
Message that clients can display for the purpose of presenting descriptive information about the payment at the associated paramindex to the user.
-
-
-

Examples

-

Valid examples

-
zcash:ztestsapling10yy2ex5dcqkclhc7z7yrnjq2z6feyjad56ptwlfgmy77dmaqqrl9gyhprdx59qgmsnyfska2kez?amount=1&memo=VGhpcyBpcyBhIHNpbXBsZSBtZW1vLg&message=Thank%20you%20for%20your%20purchase
-

A valid payment request for a payment of 1 ZEC to a single shielded Sapling address, with a base64url-encoded memo and a message for display by the wallet.

-
zcash:?address=tmEZhbWHTpdKMw5it8YDspUXSMGQyFwovpU&amount=123.456&address.1=ztestsapling10yy2ex5dcqkclhc7z7yrnjq2z6feyjad56ptwlfgmy77dmaqqrl9gyhprdx59qgmsnyfska2kez&amount.1=0.789&memo.1=VGhpcyBpcyBhIHVuaWNvZGUgbWVtbyDinKjwn6aE8J-PhvCfjok
-

A valid payment request with one transparent and one shielded Sapling recipient address, with a base64url-encoded Unicode memo for the shielded recipient.

-
-

Invalid Examples

-
zcash:?amount=3491405.05201255&address.1=ztestsapling10yy2ex5dcqkclhc7z7yrnjq2z6feyjad56ptwlfgmy77dmaqqrl9gyhprdx59qgmsnyfska2kez&amount.1=5740296.87793245
-

An invalid payment request; this is missing a payment address with empty paramindex.

-
zcash:?address=tmEZhbWHTpdKMw5it8YDspUXSMGQyFwovpU&amount=1&amount.1=2&address.2=ztestsapling10yy2ex5dcqkclhc7z7yrnjq2z6feyjad56ptwlfgmy77dmaqqrl9gyhprdx59qgmsnyfska2kez
-

Also invalid; this request is missing address.1=.

-
zcash:?address.0=ztestsapling10yy2ex5dcqkclhc7z7yrnjq2z6feyjad56ptwlfgmy77dmaqqrl9gyhprdx59qgmsnyfska2kez&amount.0=2
-

Also invalid; address.0= and amount.0= are not permitted as leading 0s are forbidden in paramindex.

-
zcash:?amount=1.234&amount=2.345&address=tmEZhbWHTpdKMw5it8YDspUXSMGQyFwovpU
-
-zcash:?amount.1=1.234&amount.1=2.345&address.1=tmEZhbWHTpdKMw5it8YDspUXSMGQyFwovpU
-

Also invalid; duplicate amount= or amount.1= fields

-
zcash:tmEZhbWHTpdKMw5it8YDspUXSMGQyFwovpU?amount=1%30
-zcash:tmEZhbWHTpdKMw5it8YDspUXSMGQyFwovpU?%61mount=1
-zcash:%74mEZhbWHTpdKMw5it8YDspUXSMGQyFwovpU?amount=1
-

Invalid; percent encoding is only allowed in qchar productions, which do not include addresses, amounts, or parameter names.

-
zcash://tmEZhbWHTpdKMw5it8YDspUXSMGQyFwovpU?amount=1
-

Invalid; the grammar does not allow //. ZIP 321 URIs are not "hierarchical URIs" in the sense defined in 3 section 1.2.3, and do not have an "authority component".

-
-
-

Forward compatibility

-

Variables which are prefixed with a req- are considered required. If a parser does not recognize any variables which are prefixed with req-, it MUST consider the entire URI invalid. Any other variables that are not recognized, but that are not prefixed with a req-, SHOULD be ignored.

-

req- is potentially part of a given parameter name that may be defined in a future version of this ZIP, not a modifier that can be applied to an arbitrary parameter. None of the originally defined parameters (address, amount, label, memo, and message) include the req- prefix, because these parameters are REQUIRED to be understood by all conformant ZIP 321 URI parsers.

-
-

Backward compatibility

-

As this ZIP is written, several clients already implement a zcash: URI scheme similar to this one, however usually without the additional req- prefix requirement or the facility to specify multiple payments using paramindex. These implementations also generally do not support URIs, even with a single payment, where the address is specified as an address= query parameter rather than in the hier-part of the URI. They may also not support the memo parameter, or may not treat it as base64url-encoded.

-
-
-

References

- - - - - - - -
1Information 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"
- - - - - - - -
2RFC 5234: Augmented BNF for Syntax Specifications: ABNF
- - - - - - - -
3RFC 3986: URI Generic Syntax, Appendix A. Collected ABNF for URI
- - - - - - - -
4RFC 4648 section 5: Base64 Encoding with URL and Filename Safe Alphabet
- - - - - - - -
5BIP 21: URI Scheme
- - - - - - - -
6BIP 70: Payment Protocol
- - - - - - - -
7BIP 350: Bech32m format for v1+ witness addresses
- - - - - - - -
8Bitcoin Wiki: Base58Check encoding
- - - - - - - -
9ZIP 173: Bech32 Format
- - - - - - - -
10ZIP 211: Disabling Addition of New Value to the Sprout Value Pool
- - - - - - - -
11ZIP 316: Unified Addresses and Unified Viewing Keys
- - - - - - - -
12Zcash Protocol Specification, Version 2023.4.0. Section 3.11: Mainnet and Testnet
- - - - - - - -
13Zcash Protocol Specification, Version 2023.4.0. Section 4.12: Balance and Binding Signature (Sapling)
- - - - - - - -
14Zcash Protocol Specification, Version 2023.4.0. Section 5.6: Encodings of Addresses and Keys
- - - - - - - -
15Zcash Protocol Specification, Version 2023.4.0. Section 5.6.1.1: Transparent Addresses
- - - - - - - -
16Zcash Protocol Specification, Version 2023.4.0. Section 5.6.3.1: Sapling Payment Addresses
- - - - - - - -
17Zcash Protocol Specification, Version 2023.4.0. Section 5.6.4.1: Unified Payment Addresses and Viewing Keys
-
-
- - \ No newline at end of file diff --git a/rendered/zip-0322.html b/rendered/zip-0322.html deleted file mode 100644 index 9ad8f3dc0..000000000 --- a/rendered/zip-0322.html +++ /dev/null @@ -1,18 +0,0 @@ - - - - ZIP 322: Generic Signed Message Format - - - -
-
ZIP: 322
-Title: Generic Signed Message Format
-Owners: Jack Grigg <jack@electriccoin.co>
-        Daira-Emma Hopwood <daira-emma@electriccoin.co>
-Status: Reserved
-Category: Standards / RPC / Wallet
-Discussions-To: <https://github.com/zcash/zips/issues/429>
-
- - \ No newline at end of file diff --git a/rendered/zip-0323.html b/rendered/zip-0323.html deleted file mode 100644 index 0fa4f5385..000000000 --- a/rendered/zip-0323.html +++ /dev/null @@ -1,18 +0,0 @@ - - - - ZIP 323: Specification of getblocktemplate for Zcash - - - -
-
ZIP: 323
-Title: Specification of getblocktemplate for Zcash
-Owners: Daira-Emma Hopwood <daira-emma@electriccoin.co>
-        Jack Grigg <jack@electriccoin.co>
-Status: Reserved
-Category: RPC / Mining
-Discussions-To: <https://github.com/zcash/zips/issues/405>
-
- - \ No newline at end of file diff --git a/rendered/zip-0324.html b/rendered/zip-0324.html deleted file mode 100644 index 2816bce7c..000000000 --- a/rendered/zip-0324.html +++ /dev/null @@ -1,386 +0,0 @@ - - - - ZIP 324: URI-Encapsulated Payments - - - - -
-
ZIP: 324
-Title: URI-Encapsulated Payments
-Owners: Jack Grigg <jack@electriccoin.co>
-        Daira-Emma Hopwood <daira-emma@electriccoin.co>
-        Kris Nuttycombe <kris@electriccoin.co>
-Original-Authors: Ian Miers
-                  Eran Tromer
-                  Jack Grigg
-                  Kevin Gorham
-                  Daira-Emma Hopwood
-Credits: Sean Bowe
-         Deirdre Connolly
-         Linda Naeun Lee
-         George Tankersley
-         Henry de Valence
-Status: Draft
-Category: Standards / Wallet
-Created: 2019-07-17
-License: MIT
-

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.

-

Zcash protocol terms are as defined in the Zcash Protocol Specification. 3

- -
-

Abstract

-

This proposal specifies a mechanism for sending Zcash payments via any unmodified (secure) messaging service, e.g., Signal or WhatsApp. The sender need not know the recipient's address and the recipient need not have a Zcash wallet already installed. Payments occur via an ordinary text/WhatsApp/Signal message containing a URI. The URI encodes the secret spending key of an ephemeral Zcash “wallet address”, to which the funds have been transferred. Anyone who learns the URI can accept this payment, by a “finalization” process which uses the key given in the URI to transfer the encapsulated funds to their own wallet. After the payment is finalized, via a suitable on-chain transaction by the recipient, it becomes irrevocable.

-

The proposal specifies the syntax and semantics of URI-Encapsulated Payments, the workflow of generating and handling them, and requisite infrastructure.

-

At its core, a URI encapsulated payment communicates the existence of a transaction (specifically a note committing to an amount of funds) to a receiving client. The URI encodes the amount of the payment and a key used to derive all necessary randomness for note construction including the address and secret key needed to spend it.

-

Usage Story

-

Alice wants to send a 1.23 ZEC payment to Bob. She doesn't have Bob's Zcash address — and Bob may not even have a wallet or have heard of Zcash! However, she does have some end-to-end encrypted channel to Bob on a secure messaging app, such as Signal or WhatsApp. She instructs her own Zcash wallet to send 1.23 ZEC on that channel. Her wallet then automatically generates a new ephemeral Zcash address and sends 1.23001 ZEC to this address. It then constructs a payment URI containing the secret key corresponding to the ephemeral address, and sends it to Bob via the secure messaging app.

-

Bob receives the message, which looks as follows:

-
-

This message contains a Zcash payment. Click the following link to view it and receive the funds using your Zcash wallet app:

-

https://pay.withzcash.com:65536/v1#amount=1.23&desc=Payment+for+foo&key=...

-

If you do not yet have a Zcash wallet app, see: https://z.cash/wallets

-
-

Bob clicks the link. His Zcash mobile wallet app (which is already installed and has configured itself as a handler for URLs of that form) shows up, and tells Bob that a payment of 1.23 ZEC awaits him. The wallet app confirms the existence of the pertinent transactions on the blockchain, and then offers to finalize the payment. Bob clicks the “Finalize” button, and his wallet app generates a transaction moving the money to his own address (using the extra 0.00001 ZEC he has received to pay the transaction fee). When this transaction is confirmed on-chain, Alice's and Bob's wallets both indicate that the payment is finalized, and thus Bob can send the funds to other parties.

-
-
-

Motivation

-

This proposal enables sending of funds without exposing users to the notion of payment addresses and their secure distribution. Instead, funds can be sent using any pre-existing communication channel, by a single message sent unidirectionally from the sender to the recipient. This message conveys all the information needed to obtain control of the funds, compactly expressed as a textual URI.

-

Consequently, all functionality related to contact discovery and secure-channel establishment can be delegated to the message app(s) with which the user is already familiar, and in which the user has already established communication channels to many of their contacts.

-

Moreover, funds can be sent to users who have not yet installed wallet software and who do not yet have a payment address. The recipient can collect the funds at any later time by installing suitable software.

-

Additionally, the proposal greatly improves the scalability of Zcash. If a recipient only receives URI payments, they need not scan the blockchain or delegate their view keys to a third party to do so.

-

Finally, this avoids the fat-finger problem of sending funds to the wrong address. The user sends funds via a known contact on, e.g., WhatsApp, who they have a relationship with or at least can confirm the recipient's identity. Moreover, even once funds are sent via a URI, they can be recovered if the other party does not claim them.

-

The proposal is complementary to ZIP 321 4, which will standardize Payment Request URIs using which the payment recipient can convey their persistent payment address to the sender, for subsequent fund transfers (to be done using the normal on-chain mechanism rather than the encapsulated payments described in the current proposal).

-
-

Requirements

-

This proposal's specification of URI-Encapsulated Payments, and the intended protocols for using them, is meant to fulfill the following requirements:

-
    -
  • The protocol must not require the sender of a payment to stay online until the recipient receives the URI (let alone finalizes the payment).
  • -
  • For convenient rendering, URIs should be short; this also maximizes compatibility with length-limited messaging platforms.
  • -
  • It must not be feasible for someone who has not seen the URI (or has compromised a party who has) to collect the funds.
  • -
  • The URIs and protocol should minimize the likelihood of inadvertent misuse, and in particular the risks discussed in “Security Considerations” below.
  • -
  • The protocol must not leak any information (sender identity, recipient identity, amount, description) to third parties, other than inevitable metadata about the existence of a transaction, the inevitable network communication around sending/receipt of transactions, whatever leakage is induced by the communication channel used to transmit the URI, and whatever is voluntarily shared by the parties.
  • -
  • The URIs should allow for future modifications and expansion of the format, without risk of ambiguous parsing.
  • -
  • The on-chain footprint of payments that use this mechanism should be indistinguishable from normal fully-shielded transactions (except, possibly, for the statistics of the number of shielded inputs and outputs).
  • -
  • Don't lose funds, even if wallets crash, or everything but the sending wallet master secret is lost.
  • -
-
-

Non-requirements

-
    -
  • It is outside the scope of this proposal to establish a secure communication channel for transmission of URI-Encapsulated Payments, or to protect the parties' devices from security compromise.
  • -
  • Finalizing the payment may involve significant wait times, on the scale of minutes, as the requisite on-chain transactions are generated, mined and confirmed. This proposal does not try to solve this (though it does try to avoid imposing significant additional delays, and it does address how the intermediate state is conveyed to the user).
  • -
-
-

Specification

-

A Payment-Encapsulating URI represents the capability to claim the Zcash funds from specific on-chain transactions, as long as they're unspent. See Usage Story for an example.

-

Syntax

-

A Payment-Encapsulating URI is a Universal Resource Locator (URL), as defined in RFC 3986 2, of the following form.

-

Scheme: https

-

Host: pay.withzcash.com

-

Port: 65536 (this is intentionally not a valid TCP/IP port number)

-

Path: payment/v1

-

Fragment parameters: these attribute-value pairs, in this order, separated by &, and with all values percent-encoded where necessary:

-
    -
  • amount=... where the attribute is a decimal number representing the amount of ZEC included in the payment. MUST be present. If a decimal fraction is present then a period (.) MUST be used as the separating character to separate the whole number from the decimal fraction, and both the whole number and the decimal fraction MUST be nonempty. No other separators (such as commas for grouping or thousands) are permitted. Leading zeros in the whole number or trailing zeros in the decimal fraction are ignored. There MUST NOT be more than 8 digits in the decimal fraction.
  • -
  • desc=... where the attribute is a human-readable string associated with the payment. MAY be present. If present, it MUST be encoded as “textual data consisting of characters from the Universal Character Set” as specified in RFC 3986 section 2.5.
  • -
  • key= is a 256-bit random number encoded with Bech32 as specified in Section 5.6.9 of the Zcash Protocol Specification 3). MUST be present.
  • -
-
-

Semantics

-

The values of key and amount deterministically imply a unique payment note corresponding to this URI, which is a Zcash Sapling note that carries the given amount and is spendable by a Sapling spending key derived from key. The derivation of this note is done by the following procedure:

-

DerivePaymentNote(key,amount):

-
    -
  • Derive pk_d from key via the process defined in 3 Section 4.2.2 (setting sk = key).
  • -
  • Fix the diversified d = DefaultDiversifier(key).
  • -
  • Derive rseed = PRF^expand(sk_m || [0xFIXME]) as specified in 3 Section 5.4.2.
  • -
  • Define the corresponding payment note as n = (d, pk_d, amount, rseed) (see 3 Section 3.2 (https://zips.z.cash/protocol/protocol.pdf#notes)).
  • -
-

TODO: Possible alternate way to derive pk_d and rseed from key:

-
    -
  • Use PRF^expand on key with to-be-defined domain separation to obtain 64 bytes. Split this into two 32-byte values. -
      -
    • First 32-byte value is sk; derive pk_d from this as in the spec.
    • -
    • Second 32-byte value is rseed.
    • -
    -
  • -
  • Could also mix in other parts of the URI (amount, desc) to bind them here, without interfering with the existing key derivation process in the spec.
  • -
-

Construct a shielded zcash transaction containing that note as an output.

-

The payment note SHOULD be unspent at the time it is intended to be received by the recipient.

-

Clients MAY generate and send the URI before the transaction is built, sent, or confirmed.

-

The amount parameter MUST match the total amount of ZEC in the payment note plus the standard transaction fee for fully-shielded transactions (currently 0.00001 ZEC).

-

There MUST NOT exist any other notes on the blockchain, or broadcast to the node network, beyond the payment note derived from the Payment URI, that are addressed to any payment address derived from key (with any diversifier). Such notes MAY be generated within an implementation (e.g., as speculative pre-generation with various note values) but MUST NOT be broadcast for mining.

-

Wallet software MUST NOT expose the ephemeral payment address corresponding to a payment URI (which helps to ensure the prior paragraph).

-

The desc parameter MAY convey a human-readable description of the payment, entered manually by the user or generated by the application in any reasonable manner.

-

The encrypted memo fields in the output description containing the payment note commitment SHOULD be either empty (all-zero), or identical to the desc parameter (padded with zeros).

-

The payment associated with an URI is not deemed “received” by the recipient until they execute a “finalization” process (see section Finalization).

-

When conveying payment to users, the sender's and recipient's wallet software MAY convey the description encoded in the desc parameter.

-

The recipient's wallet software SHOULD convey to the user that the desc value is merely a claim made by the party who sent the URI, and may be tentative, inaccurate or malicious.

-

In particular, the recipient's wallet software SHOULD convey to the user that the amount of ZEC they can successfully transfer to their wallet may be different than that given by the amount parameter, and may change (possibly to zero), until the finalization process has been completed.

-
-

Centralized Deployment

-

The owner of the withzcash.com domain name MUST NOT create a DNS record for the pay.withzcash.com domain name, nor a TLS certificate for it. All feasible means SHOULD be taken to ensure this, and to prevent unintended transfer of ownership or control over the withzcash.com domain name. (See Rationale for URI Format and Security Considerations below for discussion.)

-

Applink mechanisms let domain name owners provide a whitelist, specifying which apps are authorized to handle URLs with that domain name. This is implemented by serving suitable files at well-known paths on the web server of that domain or, in the case of a subdomain, its parent domain. Thus, the owner of the withzcash.com domain effectively controls the whitelist of apps that may be launched by users' platform to handle URI-Encapsulated Payments (see Security Considerations). This whitelist should protect users from installing rogue apps that intercept incoming payments. Thus, the domain owner MUST do the following:

-
    -
  • Maintain such a whitelist and serve it as needed for the applink mechanisms of major platforms.
  • -
  • Publish a policy for inclusion of apps in this whitelist.
  • -
  • Use all feasible means to whitelist only apps that comply with the published policy.
  • -
  • Publish the whitelist's content in human-readable form.
  • -
  • Provide clear and effective means for rapid removal of apps from the whitelist when required as security response.
  • -
  • Use all feasible means to protect the whitelist's integrity (in particular, this includes protecting the web server that serves the whitelist, the domain's TLS certificate, and the means by which the whitelist is modified).
  • -
  • Use effective means for keeping a precise, irrevocable and public history of the whitelist (e.g., using a timestamped Git repository, or an accountability mechanism akin to Certificate Transparency).
  • -
-

They also SHOULD:

-
    -
  • Strive for the whitelist to include all apps that would not place the user at any greater security risk than reputable state-of-the-art wallet apps.
  • -
-
-

Testing

-

For testing purposes, all of the above specification is duplicated for the Zcash testnet network, substituting TAZ (Zcash testnet coins) for ZEC and testzcash.com for withzcash.com.

-

A separate “testnet whitelist” MUST be maintained by the owner of the testzcash.com domain name, with a separate policy that SHOULD allow any legitimate third-party developer to add their work-in-progress wallet for testing purposes. Integrity and availability MAY be looser.

-

Wallets apps MAY support just one type of payments (ZEC or TAZ), and if they support both then they MUST keep separate accounting and must clearly distinguish the type when payments or balances are conveyed to users.

-
-
-

Lifecycle Specification

-

The lifecycle of a Payment-Encapsulating URI consists of several stages, which in the usual case culminate in the funds being irrevocably deposited into the recipient's personal wallet irrevocably:

-

Generating the notes and URI

-

The sender's Zcash wallet app creates an ephemeral spending key, sends ZEC funds to the payment addressed derived from that key, and creates a Payment-Encapsulating URI that contains this ephemeral spending key and the newly-generated note commitments.

-

Ephemeral key derivation

-

The ephemeral keys within payment URIs are derived deterministically from the same seed as the main wallet. This ensures that if a wallet is recovered from backup, sent-but-unfinalized payments can be reclaimed.

-

The derivation mechanism is as follows:

-
    -
  • Use a ZIP 32 derivation pathway to obtain a child extended spending key from path m_Sapling/324'/coin_type'/payment_index' -
      -
    • Implementations need to remember which payment_index values they have used (in range 0..2^31), and not reuse them.
    • -
    -
  • -
  • Compute key = BLAKE2b-256(extended spending key, personal='Zcash_PaymentURI')
  • -
-
-
-

URI Transmission

-

The sender conveys the Payment-Encapsulating URI to the intended recipient, over some secure channel (e.g., an end-to-end encrypted messaging platform such as Signal, WhatsApp or Magic Wormhole; or a QR code scanned in person).

-

If transmitted via a human-readable medium, such as a messaging app, the Payment-Encapsulating URI MAY be accompanied by a contextual explanation that the URI encapsulates a payment, and a suggested action by the recipient to complete the process (see Usage Story above for an example).

-

When sent via a human-readable medium that consists of discrete messages, the message that contains the URI SHOULD NOT contain any payment-specific or manually-entered information outside the URI itself, since this information may not be visible to the recipient (see “Message Rendering” below).

-

From this point, and until finalization or cancellation (see below), from the sender's perspective the payment is “in progress”; it SHOULD be conveyed as such to the sender; and MUST NOT be conveyed as “finalized” or other phrasing that conveys successful completion.

-
-

Message Rendering

-

The recipient's device renders the Payment-Encapsulating URI, or an indication of its arrival, along with the aforementioned contextual explanation (if any). The user has the option of “opening” the URI (i.e., by clicking it), which results in the device opening a Zcash wallet app, using the local platforms app link mechanism.

-

A messaging app MAY recognize URI-Encapsulated Payments, and render them in a way that conveys their nature more clearly than raw URI strings. If the messaging medium consists of discrete messages, and a message contains one or more URI-Encapsulated Payments, then the messaging app MAY assume that all other content in that message is automatically generated and contains no payment-specific or manually-generated information, and thus may be discarded during rendering.

-
-

Payment Rendering and Blockchain Lookup

-

The recipient's Zcash wallet app SHOULD present the payment amount and MAY present the description, as conveyed in the URI, along with an indication of the tentative nature of this information.

-

In parallel, the wallet app SHOULD retrieve the relevant transactions from the Zcash blockchain, by looking up the transaction given by the cmu parameter (this MAY use an efficient index, perhaps assisted by a server), and check whether:

-
    -
  • such transactions are indeed present on the blockchain
  • -
  • the notes are unspent
  • -
  • the notes can be spent using an ephemeral spending keys given by the key parameter.
  • -
-

The wallet conveys to the user one of the following states:

-
    -
  • Ready-to-finalize: The tests all verify, and the payment is ready to be finalized. The wallet SHOULD present the user with an option to finalize the payment (e.g., a “Finalize” button).
  • -
  • Invalid: The tests fail irreversibly (e.g., some of the notes are already spent, or the amounts to not add up). The wallet MAY convey the reason to the user, but in any case MUST convey that the funds cannot be received.
  • -
  • Pending: The tests fail in a way that may be remedied in the future, namely, some of the notes are not yet present on the blockchain (and no other tests are violated).
  • -
-

Within the Pending state, the wallet app MAY also consider “0 confirmations” transactions (i.e., transactions that have been broadcast on the node network but are neither mined nor expired), and convey their existence to the user. These do not suffice for entering the Ready-to-finalize state (since unmined notes cannot be immediately spent.)

-

The aforementioned conditions may change over time (e.g., the transactions may be spent by someone else in the interim), so the status SHOULD be updated periodically.

-
-

Finalization

-

When the recipient chooses to finalize the payment, the wallet app generates transactions that spends the aforementioned notes (using the ephemeral spending key) and send these Zcash funds to the user's own persistent payment address. These transactions carry the default expiry time (currently 100 blocks).

-

The recipient's wallet app SHOULD convey the payment status as “Finalizing…” starting at the time that the uses initiates the finalization process. It MAY in addition convey the specific action done or event waited.

-

The sender's wallet SHOULD convey the payment status as “Finalizing…” as soon as it detects that relevant transactions have been broadcast on the peer-to-peer network, or mined to the blockchain.

-

Once these transactions are confirmed (to an extent considered satisfactory by the local wallet app; currently 10 confirmations is common practice), their status SHOULD be conveyed as “Finalized”, by both the sender's wallet app and the recipient's wallet app. Both wallets MUST NOT convey the payment as “finalized”, or other phrasing that conveys irrevocability, until this point.

-

If these transactions expire unmined, or are otherwise rendered irrevocably invalidated (e.g., by a rollback), then both wallets' status SHOULD convey this, and the recipient's wallet SHOULD revert to the “Payment Rendering and Blockchain Lookup” stage above.

-
-

Payment Cancellation

-

At any time prior to the payment being finalized, the sender is capable of cancelling the payment, by themselves finalizing the payment into their own wallet (thereby “clawing back” the funds). If the wallet has not yet sent, for inclusion in the blockchain, any of the transactions associated with the ephemeral spending key, then cancellation can also be done by discarding these transactions or aborting their generation. The sender's wallet app SHOULD offer this feature, and in this case, MUST appropriately handle the race condition where the recipient initiated finalization concurrently.

-

Cancellation requires the sender to know the ephemeral spending key. If the sender has lost this state, it can be recovered deterministically (see Recovery From Wallet Crash, below).

-
-

Status View

-

Wallet apps SHOULD let the user view the status of all payments they have generated, as well as all inbound payment (i.e., URI-Encapsulated Payments that have been sent to the app, e.g., by invocation from messaging apps). The status includes the available metadata, and the payment's current state. When pertinent, the wallet app SHOULD offer the ability to finalize any Pending inbound payment, and MAY offer the ability to cancel any outbound payment.

-

Wallet apps SHOULD actively alert the user (e.g., via status notifications) if a payment that they sent has not been finalized within a reasonable time period (e.g., 1 week), and offer to cancel the payment.

-
-

Recovery From Wallet Crash

-

When recovering from a backed-up wallet phrase, wallet implementations already need to scan the entire chain (from the wallet's birthday) to find transactions that were received by or sent from the wallet. Simultaneously with this, the wallet may recover state about previously-created payment URIs, and regain access to non-finalized funds.

-

We define a “gap limit” N, similar to the “address gap limit” in BIP 44. If a wallet implementation observes N sequentially-derived payment URIs that have no corresponding on-chain note, they may safely expect that no payment URIs beyond that point have ever been derived.

-

Given that both the derivation of a payment URI and the action of “filling” it with a note are performed by the same entity (and in most cases sequentially), it is unlikely that there would be a significantly large gap in payment URI usage. As a balance between the cost of scanning multiple ivks, and the likelihood of missing on-chain funds due to out-of-order payment URI generation, we specify a standard gap limit of N = 3.

-

The process for determining the position of this gap during wallet recovery is as follows:

-
    -
  • Derive the first N payment URI keys.
  • -
  • Derive the N ivks corresponding to these keys via the process defined in 3 Section 4.2.2 (setting sk = key).
  • -
  • Scan the chain for spent nullifiers (for the wallet's own notes, or any payment URI notes it currently knows about). This is part of the normal chain-scanning process for wallets.
  • -
  • When a nullifier is detected as spent, trial-decrypt every output of the corresponding transaction with the current set of payment URI ivks. If a note is detected: -
      -
    • Store the note details along with the corresponding payment URI (which can be derived from the note).
    • -
    • Add the note's nullifier to the set of wallet nullifiers (to enable discovery of funded payment URIs that the sender has recalled).
    • -
    • Drop the ivk from the set of current payment URI ivks.
    • -
    • Derive the next ivk in line, and add it to the set.
    • -
    -
  • -
-

For this recovery process to succeed, wallet implementations MUST fund payment URIs with a Sapling spending key in the wallet. Alternatively, wallet implementations MAY include the set of payment URI ivks within the set of ivks they are using for normal chain scanning, but this will slow down the recovery process by a factor of 4 (for a gap limit of N = 3, and a wallet with one Sapling account).

-
-
-

Security Considerations

-
    -
  • Anyone who intercepts the URI-Encapsulated Payments may steal the encapsulated funds. Therefore, URI-Encapsulated Payments should be sent over a secure channel, and should be kept secret from anyone but the intended recipient. -
      -
    • The Payment-Encapsulating URI is like a magic spell that will teleport the money to the first person that clicks it and then does "finalize".
    • -
    -
  • -
  • URI-Encapsulated Payments may be captured by malicious local apps on the sender or receiver's platform, e.g., by screen capturing or clipboard eavesdropping. Wallet apps should use the platform's interaction and communication facilities in a way that minimizes these risks (e.g., use the “Share” API rather than a clipboard that is visible to all apps).
  • -
  • Likewise, if the URI is transferred by presenting and optically scanning a QR code, anyone who observes this QR code may be able to finalize the payment and thus take ownership of the funds before the intended recipient. For example, an attacker may use a telephoto lens aimed at a point-of-sale terminal to steal QR-encoded payments sent to that terminal.
  • -
  • Users may have casually-established communication channels (e.g., they have entered the phone number of a new contact without bothering to double-check it), but may later mistakenly consider these to be adequately-authenticated secure channels for the purpose of sending Payment-Encapsulating URI. Wallet apps should mitigate this where feasible, e.g., by indicating that the chosen messaging channel is previously-unused and thus should be more carefully checked.
  • -
  • Users may incorrectly believe that the payment has been irrevocably received even though they have not invoked the finalization procedure, or even though the finalization procedure has failed. Wallet software should correctly convey the status and set expectations, as discussed above.
  • -
  • Payment recipients may not notice the incoming payment notification and act on it (i.e., invoke finalization) in a timely fashion. By the time they see it, the payment may have been cancelled by the sender.
  • -
  • Users may not understand that URI-Encapsulated Payments are for one-time use, and attempt to use the same URI for multiple people or payments, resulting in race conditions on who receives the funds.
  • -
  • Users may confuse URI-Encapsulated Payments (as specified in the current ZIP) with Payment Request URIs of the form zcash:payment-address?amount=... as specified in ZIP 321 4. Normally these serve different workflows, and work in opposing directions (send vs. receive of funds), and thus ought to not arise in ambiguous context. Wallet apps should take care to not create or send a Payment-Encapsulating URI (which is for sending funds) in a context where the user may be intending to receive funds.
  • -
  • Users may attempt to use a Payment-Encapsulating URI as a “cold wallet”, e.g., by writing the URI on paper and putting it in a safe. This is dangerous. The spending key is known to the sending wallet at the time when the URI is produced, and possibly also at other times (e.g., if there are storage remnants, or if deterministic derivation is used; see “Ephemeral key derivation” below). Thus, an adversary who compromises the sending wallet may drain the cold wallet.
  • -
  • The act and timing of finalizing a payment is visible to the sender, which may be a privacy leak. Likewise, if the on-chain transactions are sent in advance, their timing can be linked to the later payment, which may be a privacy leak.
  • -
  • The payment amount is readily visible to anyone who observes the Payment-Encapsulating URI, even in retrospect after payment has already been finalized (e.g., if their device or chat log backups are later compromised). This may be a privacy concern, and in particular may put recipients of large payments at risk of undesired attention.
  • -
  • Users attempting to follow URI-Encapsulated Payments as a regular HTTPS hyperlink may inadvertently leak the payment information to a remote attacker, if all layers of defense listed in Rationale for URI Format are somehow breached.
  • -
  • The owner of the withzcash.com domain effectively controls the whitelist of apps that may be launched by users' platform to handle URI-Encapsulated Payments using the applink mechanism. If the whitelist is too permissive and includes a malicious or vulnerable app, and a user installs that app (which itself may be subject to the platform vendor's app review mechanism), then the user is placed at risk of having their payments intercepted by an attacker. Conversely, if the whitelist is too restrictive, or altogether unavailable, then users would not be able to trigger desirable wallet apps by simply following links, and would need to instead ”share” the message containing the URI into their wallet app (note that, as discussed above, clipboard copy-and-paste is insecure).
  • -
  • Usage of URI-Encapsulated Payments may train users to, generally, click on other types of URI/URL links sent in other messaging contexts. Malicious links sent via unauthenticated messaging channels (e.g., emails and SMS texts) are a common attack vector, used for exploiting vulnerabilities in the apps triggered to handle these links. Even though the fault for vulnerabilities lies with those other apps, and even though this ZIP uses deep link URIs in the way intended, there are none the less these negative externalities to encouraging such use.
  • -
-
-

Design Decisions and Rationale

-

Rationale for URI Format

-

The URI format https://pay.withzcash.com:65536/v1#... was chosen to allow automatic triggering of wallet software on mobile devices, using the platform's applink mechanism, while minimizing the risk of payment information being intercepted by third parties. The latter is prevented by a defense in depth, where any of the following suffices to prevent the payment information from being exposed over the network:

-
    -
  • The pay.withzcash.com domain should not resolve.
  • -
  • A valid TLS certificate for pay.withzcash.com should not exist..
  • -
  • The port number 65536 is not valid for the TCPv4, TCPv6 or UDP protocols. Empirically, the common behavior in browsers and messaging apps, when following HTTPS links with port number port number 65536, is to render an empty or about:blank page rather than a DNS error; a network fetch is not triggered. (This may change if a network proxy protocol is used, but SOCKS5 also cannot represent port 65536.)
  • -
  • The contents of the fragment identifier are specified by HTTP as being resolved locally, rather than sent over the network (but see the caveat about active JavaScript attacks below).
  • -
-

The downside is that if the user follows the link prior to installing a suitable wallet app, they get a weird-looking DNS error or a blank page. Also, the URL looks weird due to the port number.

-

Several alternatives were considered, but found to have inferior usability and/or security ramifications:

-
    -
  1. https://pay.withzcash.com/v1#...: similar to above, but without the port number, and backed by a DNS record, TLS certificate and web server for pay.withzcash.com that serves an informative HTML page (e.g., “Please install a wallet to receive this payment”). This still allows handling by wallet apps using an applink mechanism, and provides a friendlier fallback in case the user follows the link prior to installing a suitable app. However, it creates a security risk. If the web server serving that web page is compromised, or impersonated using an DNS+TLS attack, then the attacker can capture they payment parameters and steal the funds. (Note that the sensitive information is in the fragment following the #, which is not sent in an HTTP GET request; but the malicious server can serve JavaScript code which retrieves the fragment.)
  2. -
  3. zcash-data:payment/v1?amount=1.23&desc=Payment+for+foo&key=...: a custom URI scheme, such as zcash-data. This still allows for triggering application action (e.g., using Mobile Deep Links). However, on most platorms, any app installed on the device is able to register to handle links from (almost) any custom URI scheme. If the request is received by a rogue party, then the funds could be stolen. Even if received by an honest operator, funds could be stolen if they are compromised. Also, custom URI schemes are not linkified when displayed in some messaging apps. -

    Note the use of the zcash-data URI scheme, rather than the more elegant zcash, because URIs of the form zcash:address?... are already used to specify Zcash addresses and payment requests in ZIP 321 4, by analogy to the bitcoin URIs of BIP 21. An alternative is to use zcash:v1/payment?...; legacy software may parse this as a payment request to the address v1, which is invalid. Another alternative is to use zcash-payment:v1?..., which is appealing in terms of length and readability, but may be gratuitous pollution of the URI scheme namespace.

    -
  4. -
-

Another option, which can be added to any of the above, is to add a confirmation code outside the URI that needs to be manually entered by the user into the wallet app, so that merely intercepting the URI link would not suffice. This does not seem to significantly reduce risk in the scenarios considered, and so deemed to not justify the reduced usability.

-
-

Identifying Notes

-

The recipient's wallet needs to identify the notes related to the payment (and the on-chain transactions that contain them), in order to verify their validity and then (during the finalization process) spend them.

-

The following is out of date, and reflects an earlier design choice (“0”), while we have transitioned to a different choice (“4”). To be revised.

-

In the above description, we explicitly list the notes involved in the payment (which are easily mapped to the transactions containing them, using a suitable index). This results in long URIs when multiple notes are involved (e.g., when using the aforementioned “powers-of-2 amounts” technique).

-

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:

-

- \(\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.
  2. -
  3. Derive a tag from a seed included in the URI, and put this tag within the encrypted memo field of the output descriptors in the associated transactions. Put the tag plaintext within the space reserved for the memo field ciphertext (breaking the AEAD abstraction). The recipient's wallet (or the service assisting it) would maintain an index of such tags, and efficiently look up the tags derived from the URI. The tags are publicly-visible and thus may leak information on the payment amount (e.g., when using the powers-of-2 pre-generation technique).
  4. -
  5. Similarly to the above, but place the tag in an additional zero-value output descriptor added to each pertinent transaction. The recipient can recompute this note commitment and use that as the identifier, to be looked up in an index in order to locate the transaction. Here too, the tags are publicly-visible and thus may leak information on the payment amount (e.g., when using the powers-of-2 pre-generation technique).
  6. -
  7. Have the URI include a seed and the amount of the (single) output note. Let the seed determine not only the spending key, but also all randomness involved in the generation of the note. Thus, the recipient can deterministically derive the note commitment from the seed and amount, and look it up to find the relevant transaction. This requires the recipient (or the server assisting them) to maintain an index mapping note commitments (of output descriptors that are the first in their transaction) to the transaction that contains them. Additional notes can be included in the same transaction.
  8. -
-
-

Additional rationale

-
    -
  1. The metadata (amount and description) is provided within the URI. An alternative would be to encode the description in the encrypted memo fields of the associated shielded transactions, and compute the amount from those transactions. However, in that case the metadata would not be available for presentation to the user until the transactions have been retrieved from the blockchain.
  2. -
  3. We support multiple spending keys and multiple notes in one URI, because these payments may be speculatively generated and mined before the payment amount is determined (to allow payments with no latency). For example, the sending wallets may pre-generate transactions for powers-of-2 amounts, and then include only a subset of them in the URI, totalling to the desired amount.
  4. -
  5. We do not include the sender or receiver's identity in the URI, because the sending wallet many not know the name of who it is sending to (or even from). Moreover there is the risk that fraudulent sender/recipient information could be used. If necessitated by circumstances (e.g., the FinCEN "Travel Rule" 8), claimed sender and recipient identity can be included in desc parameter.
  6. -
-
-
-

Open Questions

-

URI Usability

-

The URI could be changed in several ways due to usability concerns:

-
    -
  1. It may be desirable to prevent the amount and desc parameters from being human readable. This is to discourage people from just looking at the URI, seeing the numbers and text, and mistakenly thinking this is already a confirmation of successful receipt (without going through the finalization process).
  2. -
  3. Perhaps the URI should be contain the phrase “password” early on (e.g., zcash-data:/payment/v1/password=, as a cue that this string must be kept secret. (Note that technically nothing here is a password in the usual sense of the term.)
  4. -
  5. Perhaps we should actually use BIP 39 words as an actual password. So you could memorize it or read it over the phone. The BIP 39 words can be embedded in the URI itself (which is highly unusual): -

    zcash-data:payment/v1/password=witch+collapse+practice+feed+shame+open+despair+creek+road+again+ice+least

    -

    or

    -

    zcash-data:payment/v1/password=WitchCollapsePracticeFeedShameOpenDespairCreekRoadAgainIceLeast

    -

    This provides an additional cue that the URI contains a sensitive password (for users who are accustomed to BIP 39 style word lists; to others the Base 64 encoding may be more evocative of a password). Moreover, users may discover the fact that they can manually send these words to recipients, in writing or verbally, as a way to send money without a textual messaging service. Alternatively, the BIP 39 words can be used as an alternative syntax for the encapsulation, without the confusing-to-humans URI syntax (but generating this alternative syntax this may complicate the UI).

    -
  6. -
-
-

Note retrieval

-

Ideally: a lightweight wallet can receive the funds with the assistance of a more powerful node, with minimal information leakage to that node (e.g., using simple lookups queries that can be implemented via Private Information Retrieval). The open question is how to do this given that most practical PIR are for retrieving an index out of an array, not a key from a key value standpoint.

-
-

Other Questions

-

Should senders delay admitting a generated transaction by a random amount to prevent traffic analysis (i.e., so the messaging service operator cannot correlate messages with on-chain transactions)?

-

Consider the behavior in case a chain reorgs invalidates a sent payment. Should we specify a Merkle root or block hash to help detect this reason for payment failure? Or have some servers that maintain a cache of payments that were invalidated by reorgs?

-
-
-

References

- - - - - - - -
1Information 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"
- - - - - - - -
2Uniform Resource Identifier (URI): Generic Syntax
- - - - - - - -
3Zcash Protocol Specification, Version 2023.4.0 or later
- - - - - - - -
4ZIP 321: Payment Request URIs
- - - - - - - - - - - - - - - - - - - - - - - -
7Microsoft Universal Windows Platform Documentation: Enable apps for websites using app URI handlers
- - - - - - - -
8FinCEN Guidance FIN-2019-G001. May 9, 2019. Application of FinCEN’s Regulations to Certain Business Models Involving Convertible Virtual Currencies
-
-

Publication Blockers

-
    -
  • Clean up semantics.
  • -
  • Clean up rationale.
  • -
-
-
- - \ No newline at end of file diff --git a/rendered/zip-0332.html b/rendered/zip-0332.html deleted file mode 100644 index 60c742bdd..000000000 --- a/rendered/zip-0332.html +++ /dev/null @@ -1,18 +0,0 @@ - - - - ZIP 332: Wallet Recovery from zcashd HD Seeds - - - -
-
ZIP: 332
-Title: Wallet Recovery from zcashd HD Seeds
-Owners: Kris Nuttycombe <kris@electriccoin.co>
-        Daira-Emma Hopwood <daira-emma@electriccoin.co>
-Status: Reserved
-Category: Wallet
-Discussions-To: <https://github.com/zcash/zips/issues/675>
-
- - \ No newline at end of file diff --git a/rendered/zip-0339.html b/rendered/zip-0339.html deleted file mode 100644 index ff4297622..000000000 --- a/rendered/zip-0339.html +++ /dev/null @@ -1,17 +0,0 @@ - - - - ZIP 339: Wallet Recovery Words - - - -
-
ZIP: 339
-Title: Wallet Recovery Words
-Owners: Daira-Emma Hopwood <daira-emma@electriccoin.co>
-Status: Reserved
-Category: Wallet
-Discussions-To: <https://github.com/zcash/zips/issues/364>
-
- - \ No newline at end of file diff --git a/rendered/zip-0400.html b/rendered/zip-0400.html deleted file mode 100644 index 430a65164..000000000 --- a/rendered/zip-0400.html +++ /dev/null @@ -1,515 +0,0 @@ - - - - ZIP 400: Wallet.dat format - - - -
-
ZIP: 400
-Title: Wallet.dat format
-Owners: Alfredo Garcia <oxarbitrage@gmail.com>
-Status: Draft
-Category: Wallet
-Created: 2020-05-26
-License: MIT
-

Terminology

-

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

-
-

Abstract

-

This proposal defines the current format used in zcashd for wallet persistent storage, commonly known as wallet.dat.

-
-

Motivation

-

The process of saving wallet data into disk is currently unspecified. The key-values used in the current implementation are undocumented, and their structure and functionality are unknown without a deep analysis of the involved source code. This document details the schema and the mechanics of the wallet database. This is an informational document, no changes will be done to the source code.

-
-

Specification

-

Zcash stores wallet information in a Berkeley database (BDB) 2 commonly known as wallet.dat. The main purpose of this is the persistence of public and private keys the user created and the ability to recover the wallet state after a node restart. This file also allows the migration of user information from one node to another by moving the database to the corresponding new data directory, assuming both zcashd instances are running the same or similar version. A re-index may be necessary after this operation.

-

The current database is a key-value store where keys and values can have multiple data types in binary format. The first data found in a database key is always the property name, the rest of the key is generally used to identify a record, for example:

-
<------ KEY ----+- VALUE ->
----------------------------
-| zkey | pubkey | privkey |
----------------------------
-

Here zkey is the property name located at the first position of the database key; the public key is also part of the database key, and it is located in the second position; the private key is saved in the database value column at the first position.

-

Schema

-

According to Zcash v3.0.0-rc1 the following key-values can be found: the property names in bold mean only one instance of this type can exist in the entire database, while the others, suffixed by '*' can have multiple instances. Keys and Values columns of the table contain the types that the stored data is representing. Included also there are the variable names hoping it will add some clarity to what the stored data is representing.

- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
NameDescriptionKeysValues
acc*Account data -
    -
  1. string strAccount
  2. -
-
-
    -
  1. CAccount account
  2. -
-
acentry*Track internal transfers between accounts in the same wallet -
    -
  1. string strAccount
  2. -
  3. uint64_t nNumber
  4. -
-
-
    -
  1. CAccountingEntry acentry
  2. -
-
bestblockThe current best block of the blockchain. -
    -
  1. CBlockLocator locator
  2. -
-
chdseedEncrypted HD seed -
    -
  1. uint256 seedFp
  2. -
-
-
    -
  1. vector<unsigned char> vchCryptedSecret
  2. -
-
ckey*Encrypted transparent pubkey and private key. -
    -
  1. vector<unsigned char> vchPubKey
  2. -
-
-
    -
  1. vector<unsigned char> vchPrivKey
  2. -
-
csapzkey*Encrypted Sapling pubkey and private key. -
    -
  1. libzcash::SaplingIncomingViewingKey ivk
  2. -
-
-
    -
  1. libzcash::SaplingExtendedFullViewingKey extfvk
  2. -
  3. vector<unsigned char> vchCryptedSecret
  4. -
-
cscriptSerialized script, used inside transaction inputs and outputs -
    -
  1. uint160 hash
  2. -
-
-
    -
  1. CScript script
  2. -
-
czkey*Encrypted Sprout pubkey and private key. -
    -
  1. libzcash::SproutPaymentAddress addr
  2. -
-
-
    -
  1. uint256 rkValue
  2. -
  3. vector<unsigned char> vchCryptedSecret
  4. -
-
defaultkeyDefault Transparent key. -
    -
  1. CPubKey CWallet::vchDefaultKey
  2. -
-
destdata*Adds a destination data tuple to the store. -
    -
  1. std::string strAddress
  2. -
  3. std::string strKey
  4. -
-
-
    -
  1. std::string strValue
  2. -
-
hdchainHierarchical Deterministic chain code, derived from seed. -
    -
  1. CHDChain chain
  2. -
-
hdseed*Hierarchical Deterministic seed. 4 -
    -
  1. uint256 seedFp
  2. -
-
-
    -
  1. RawHDSeed rawSeed
  2. -
-
key*Transparent pubkey and privkey. -
    -
  1. CPubKey vchPubKey
  2. -
-
-
    -
  1. CPrivKey pkey
  2. -
-
keymeta*Transparent key metadata. -
    -
  1. CPubKey vchPubKey
  2. -
-
-
    -
  1. CKeyMetadata keyMeta
  2. -
-
minversionWallet required minimal version.
mkeyMaster key, used to encrypt public and private keys of the database. -
    -
  1. unsigned int nID
  2. -
-
-
    -
  1. CMasterKey kMasterKey
  2. -
-
name*Name of an address to insert in the address book. -
    -
  1. string strAddress
  2. -
-
-
    -
  1. string strAddress
  2. -
-
orderposnextIndex of next tx. -
    -
  1. int64_t nOrderPosNext
  2. -
-
pool* -
    -
  1. int64_t nIndex
  2. -
-
-
    -
  1. CKeyPool keypool
  2. -
-
purpose*Short description or identifier of an address. -
    -
  1. string strAddress
  2. -
-
-
    -
  1. string strPurpose
  2. -
-
sapzaddr*Sapling z-addr Incoming Viewing key and address. -
    -
  1. libzcash::SaplingPaymentAddress addr
  2. -
-
-
    -
  1. libzcash::SaplingIncomingViewingKey ivk
  2. -
-
sapextfvk*Sapling Extended Full Viewing Key
sapzkey*Sapling Incoming Viewing Key and Extended Spending Key -
    -
  1. libzcash::SaplingIncomingViewingKey ivk
  2. -
-
-
    -
  1. libzcash::SaplingExtendedSpendingKey key
  2. -
-
tx*Store all transactions that are related to wallet. -
    -
  1. uint256 hash
  2. -
-
-
    -
  1. CWalletTx wtx
  2. -
-
versionThe CLIENT_VERSION from clientversion.h. -
    -
  1. int nFileVersion
  2. -
-
vkey*Sprout Viewing Keys. -
    -
  1. libzcash::SproutViewingKey vk
  2. -
-
-
    -
  1. char fYes
  2. -
-
watchs*Watch-only t-addresses. -
    -
  1. CScript script
  2. -
-
-
    -
  1. char fYes
  2. -
-
witnesscachesizeShielded Note Witness cache size. -
    -
  1. int64_t nWitnessCacheSize
  2. -
-
wkey*Wallet key.
zkey*Sprout Payment Address and Spending Key. -
    -
  1. libzcash::SproutPaymentAddress addr
  2. -
-
-
    -
  1. libzcash::SproutSpendingKey key
  2. -
-
zkeymeta*Sprout Payment Address and key metadata. -
    -
  1. libzcash::SproutPaymentAddress addr
  2. -
-
-
    -
  1. CKeyMetadata keyMeta
  2. -
-
-
-

Functionality

-

When a zcashd node built with wallet support is started for the first time, a new wallet database is created. By default the node will automatically execute wallet actions that will be saved in the database at the first flush time.

-

The following flow will happen when a node with wallet support is started for the first time:

-
    -
  • DEFAULT_KEYPOOL_SIZE (100 by default) keys will be added to the pool, creating 100 records with pool as property name (first value of database key).
  • -
  • Also 100 key properties will be added.
  • -
  • 100 keymeta.
  • -
  • Wallet will create a default transparent key to receive, this will be also added as key, pool and keymeta properties.
  • -
  • This default key is also added as a defaultkey property.
  • -
  • The last action created an entry in the address book that is reflected in the database by the name and purpose properties.
  • -
  • If the wallet is created with HD support, it will have additional properties hdseed and hdchain that will be saved.
  • -
  • version, minversion, witnesscachesize and bestblock properties are added. These are settings and state information: the bestblock property is a good example of the database being populated that is happening without any user interaction, but it will just update as the best block of the current chain changes.
  • -
-

At any time after the database is created, new properties can be added as the wallet users perform actions. For example, if the user creates a new Sapling address with the RPC command z_getnewaddress then new records with properties sapzkey and sapzkeymeta will be added to the database.

-

In zcashd, database changes do not happen immediately but they are flushed in its own thread by ThreadFlushWalletDB() function periodically to avoid overhead. The internal counter nWalletDBUpdated is increased each time a new write operation to the database is done, this is compared with the last flush in order to commit new stuff.

-

When the node goes down for whatever reason the information in the wallet database SHOULD persist in the disk; the next time the node starts, the software will detect the database file, read from there and add the values into memory structures that will guarantee wallet functionality.

-

Transactions

-

The wallet database will not save all the transactions that are happening in the blockchain however it will save all transactions where wallet keys are involved. This is needed for example to get balances. Therefore the wallet must have all the transactions related to a key to compute the final value of coin available in the derived address.

-

The tx property will hold the transaction-related data with the transaction hash as the key and the full transaction as the value.

-
-

Wallet state and transaction reordering

-

Transactions are saved in the database tx key as they arrive, this means transactions have a sequence. The set of all transactions from the begging to a specified timestamp is the wallet state at that instant. Wallet state is important among other things to get current balance for a wallet or address.

-

In the blockchain, transactions can be invalidated by rollbacks; wallet code will handle this by updating the transactions in the memory database. New state needs to be reflected in the disk database, this is done in zcashd by the flag fAnyUnordered where if true at start time, will launch a rescan over all transactions again.

-
-

Wallet Recovery

-

The wallet database file may become corrupted. There are utilities in the zcutil/bin directory that may help with recovering it if this happens. Please ask for help on the Zcash forum or Community Discord.

-
-

Wallet Encryption

-

Encryption will not be discussed in this document in detail as it is expected for the algorithm to change in the future according to the Wallet format ZIP issue: 3.

-

For a deeper understanding of the current encryption mechanism please refer to 5

-
-
-
-

References

- - - - - - - -
1Information 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"
- - - - - - - -
2Oracle Berkeley Database
- - - - - - - -
3ZIP 400 issue
- - - - - - - -
4ZIP 32: Shielded Hierarchical Deterministic Wallets
- - - - - - - -
5Database key encryption implementation
-
-
- - \ No newline at end of file diff --git a/rendered/zip-0401.html b/rendered/zip-0401.html deleted file mode 100644 index aaec293e4..000000000 --- a/rendered/zip-0401.html +++ /dev/null @@ -1,157 +0,0 @@ - - - - ZIP 401: Addressing Mempool Denial-of-Service - - - - -
-
ZIP: 401
-Title: Addressing Mempool Denial-of-Service
-Owners: Daira-Emma Hopwood <daira-emma@electriccoin.co>
-Status: Active
-Category: Network
-Created: 2019-09-09
-License: MIT
-

Terminology

-

The key words "MUST", "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.

-
-

Abstract

-

This proposal specifies a change to the behaviour of zcashd nodes intended to mitigate denial-of-service from transaction flooding.

-
-

Motivation

-

Adoption of this proposal would increase robustness of Zcash nodes against denial-of-service attack, in particular attacks that attempt to exhaust node memory.

-

Bitcoin Core added size limitation for the mempool in version 0.12 8, defaulting to 300 MB. This was after Zcash forked from Bitcoin Core.

-
-

Requirements

-

The memory usage of a node’s mempool should be bounded.

-

The eviction policy should as far as possible not be “gameable” by an adversary, i.e. an adversary should not be able to cause legitimate transactions (that do not themselves present any denial-of-service problem) to be preferentially evicted relative to its own transactions.

-

Any configuration options should have reasonable defaults, i.e. without changing relevant configuration, a node should be adequately protected from denial-of-service via mempool memory exhaustion.

-
-

Non-requirements

-

The current architecture of Zcash imposes fundamental limits on scaling of transaction throughput. This proposal does not increase the aggregate transaction capacity of the network. (The Blossom upgrade does increase transaction capacity, by a factor of two 2.)

-

Denial-of-service issues in the messaging layer of the peer-to-peer protocol are out of scope for this proposal.

-

This proposal is focused primarily on memory exhaustion attacks. It does not attempt to use fees to make denial-of-service economically prohibitive, since that is unlikely to be feasible while maintaining low fees for legitimate users. It does not preclude changes in fee policy.

-
-

Specification

-

This specification describes the intended behaviour of zcashd nodes. Other node implementations MAY implement the same or similar behaviour, but this is not a requirement of the network protocol. Thus, RFC 2119 conformance keywords below are to be interpreted only as placing requirements on the zcashd implementation (and potentially other implementations that have adopted this specification in full).

-

The mempool of a node holds a set of transactions. Each transaction has a cost, which is an integer defined as:

-
-

max(memory size in bytes, 10000)

-
-

The memory size is an estimate of the size that a transaction occupies in the memory of a node. It MAY be approximated as the serialized transaction size in bytes.

-

Each transaction also has an eviction weight, which is cost + low_fee_penalty, where low_fee_penalty is 40000 if the transaction pays a fee less than the conventional fee, otherwise 0. The conventional fee is currently defined in ZIP 317 5.

-

Each node also MUST hold a FIFO queue RecentlyEvicted of pairs (txid, time), where the time indicates when the transaction with the given txid was evicted. The txid (rather than the wtxid as defined in 3) is used even for version 5 transactions after activation of NU5 4.

-

The RecentlyEvicted queue SHOULD be empty on node startup. The size of RecentlyEvicted SHOULD never exceed eviction_memory_entries entries, which is the constant 40000.

-

There MUST be a configuration option mempooltxcostlimit, which SHOULD default to 80000000.

-

There MUST be a configuration option mempoolevictionmemoryminutes, which SHOULD default to 60.

-

On receiving a transaction:

-
    -
  • If it is in RecentlyEvicted, the transaction MUST be dropped.
  • -
  • Calculate its cost. If the total cost of transactions in the mempool including this one would exceed mempooltxcostlimit, then the node MUST repeatedly call EvictTransaction (with the new transaction included as a candidate to evict) until the total cost does not exceed mempooltxcostlimit.
  • -
-

EvictTransaction MUST do the following:

-
    -
  • Select a random transaction to evict, with probability in direct proportion to eviction weight.
  • -
  • Add the txid and the current time to RecentlyEvicted, dropping the oldest entry in RecentlyEvicted if necessary to keep it to at most eviction_memory_entries entries.
  • -
  • Remove it from the mempool.
  • -
-

Nodes SHOULD remove transactions from RecentlyEvicted that were evicted more than mempoolevictionmemoryminutes minutes ago. This MAY be done periodically, and/or just before RecentlyEvicted is accessed when receiving a transaction.

-
-

Rationale

-

The accounting for transaction size should include some overhead per transaction, to reflect the cost to the network of processing them (proof and signature verification; networking overheads; size of in-memory data structures). The implication of not including overhead is that a denial-of-service attacker would be likely to use minimum-size transactions so that more of them would fit in a block, increasing the unaccounted-for overhead. A possible counterargument would be that the complexity of accounting for this overhead is unwarranted given that the format of a transaction already imposes a minimum size. However, the proposed cost function is almost as simple as using transaction size directly.

-

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\) - ).

-

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.

-

The mempooltxcostlimit is a per-node configurable parameter in order to provide flexibility for node operators to change it either in response to attempted denial-of-service attacks, or if needed to handle spikes in transaction demand. It may also be useful for nodes running in memory-constrained environments to reduce this parameter.

-

The limit of eviction_memory_entries = 40000 entries in RecentlyEvicted bounds the memory needed for this data structure. Since a txid is 32 bytes and a timestamp 8 bytes, 40000 entries can be stored in ~1.6 MB, which is small compared to other node memory usage (in particular, small compared to the maximum memory usage of the mempool itself under the default mempooltxcostlimit). eviction_memory_entries entries should be sufficient to mitigate any performance loss caused by re-accepting transactions that were previously evicted. In particular, since a transaction has a minimum cost of 10000, and the default mempooltxcostlimit is 80000000, at most 8000 transactions can be in the mempool of a node using the default parameters. While the number of transactions “in flight” or across the mempools of all nodes in the network could exceed this number, we believe that is unlikely to be a problem in practice.

-

Note that the RecentlyEvicted queue is intended as a performance optimization under certain conditions, rather than as a DoS-mitigation measure in itself.

-

The default expiry of 40 blocks after Blossom activation represents an expected time of 50 minutes. Therefore (even if some blocks are slow), most legitimate transactions are expected to expire within 60 minutes. Note however that an attacker’s transactions cannot be relied on to expire.

-
-

Deployment

-

This specification was implemented in zcashd v2.1.0-1. It is independent of the Blossom network upgrade.

-

The fee threshold for applying the low_fee_penalty was reduced from 10000 to 1000 zatoshis as part of the deployment of ZIP 313 in zcashd v4.2.0.

-

The fee threshold for applying the low_fee_penalty changed again in zcashd v5.5.0 and zebrad v1.0.0-rc.7 to match the ZIP 317 conventional fee. At the same time, the minimum cost threshold and the low_fee_penalty constant was increased as proposed in 6.

-
-

Reference implementation

- -
-

References

- - - - - - - -
1Information 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"
- - - - - - - -
2ZIP 208: Shorter Block Target Spacing
- - - - - - - -
3ZIP 239: Relay of Version 5 Transactions
- - - - - - - -
4ZIP 252: Deployment of the NU5 Network Upgrade
- - - - - - - -
5ZIP 317: Proportional Transfer Fee Mechanism
- - - - - - - -
6zcash/zips issue #565 - ZIP 401: Increase the minimum eviction cost to avoid penalizing Orchard
- - - - - - - -
7zcash/zips issue #673 - ZIP 401 uses serialized size to calculate cost but the zcashd implementation uses RecursiveDynamicUsage
- - - - - - - -
8Bitcoin Core PR 6722: Limit mempool by throwing away the cheapest txn and setting min relay fee to it
-
-
- - \ No newline at end of file diff --git a/rendered/zip-0402.html b/rendered/zip-0402.html deleted file mode 100644 index 27bdd4c21..000000000 --- a/rendered/zip-0402.html +++ /dev/null @@ -1,16 +0,0 @@ - - - - ZIP 402: New Wallet Database Format - - - -
-
ZIP: 402
-Title: New Wallet Database Format
-Status: Reserved
-Category: Wallet
-Discussions-To: <https://github.com/zcash/zips/issues/365>
-
- - \ No newline at end of file diff --git a/rendered/zip-0403.html b/rendered/zip-0403.html deleted file mode 100644 index 885951a14..000000000 --- a/rendered/zip-0403.html +++ /dev/null @@ -1,16 +0,0 @@ - - - - ZIP 403: Verification Behaviour of zcashd - - - -
-
ZIP: 403
-Title: Verification Behaviour of zcashd
-Status: Reserved
-Category: Informational
-Discussions-To: <https://github.com/zcash/zips/issues/404>
-
- - \ No newline at end of file diff --git a/rendered/zip-0416.html b/rendered/zip-0416.html deleted file mode 100644 index 00519ad24..000000000 --- a/rendered/zip-0416.html +++ /dev/null @@ -1,22 +0,0 @@ - - - - ZIP 416: Support for Unified Addresses in zcashd - - - -
-
ZIP: 416
-Title: Support for Unified Addresses in zcashd
-Owners: Daira-Emma Hopwood <daira-emma@electriccoin.co>
-        Jack Grigg <jack@electriccoin.co>
-        Sean Bowe <sean@electriccoin.co>
-        Kris Nuttycombe <kris@electriccoin.co>
-        Ying Tong Lai <yingtong@electriccoin.co>
-        Steven Smith <steven@electriccoin.co>
-Status: Reserved
-Category: RPC / Wallet
-Discussions-To: <https://github.com/zcash/zips/issues/503>
-
- - \ No newline at end of file diff --git a/rendered/zip-1001.html b/rendered/zip-1001.html deleted file mode 100644 index 8aeb58081..000000000 --- a/rendered/zip-1001.html +++ /dev/null @@ -1,114 +0,0 @@ - - - - ZIP 1001: Keep the Block Distribution as Initially Defined — 90% to Miners - - - -
-
ZIP: 1001
-Title: Keep the Block Distribution as Initially Defined — 90% to Miners
-Owners: mistfpga (zcash forums) <steve@mistfpga.net>
-Status: Obsolete
-Category: Consensus Process
-Created: 2019-08-01
-License: CC BY-SA 4.0 <https://creativecommons.org/licenses/by-sa/4.0/>
-Discussions-To: <https://forum.zcashcommunity.com/t/zip-proposal-keep-the-block-distribution-as-initaly-defined-90-to-miners/33843>
-

Terminology

-

The key words "MUST", "MUST NOT", "SHOULD", and "SHOULD NOT" in this document are to be interpreted as described in BCP 14 2 when, and only when, they appear in all capitals.

-

For clarity this ZIP defines these terms:

-
    -
  • Mining software in the context of this ZIP refers to pool software, local mining software, or staking software.
  • -
  • Mining is defined as the action of processing transactions, so this would include proof of stake, if Zcash would switch to that.
  • -
  • Mining coins transferred via fees are considered rewards (infinite), coins generated via block generation are considered distribution (finite).
  • -
  • Block distribution is defined as the block reward minus transaction fees. the protocol specification uses "block subsidy".
  • -
  • Spirit is defined as what is the intended outcome of the ZIP. 1
  • -
  • Initial promise is non-neutral language referencing the block distribution rules as initially set out. 3
  • -
- - - - - - - -
1If there is contradiction between Spirit and any other part of the proposal that needs to be addressed, in the event it is not addressed Spirit is assumed to overrule all.
-
-

Abstract

-

The spirit of this ZIP is to is to ensure that the Founders’ Reward ends. It is not the intention of this ZIP to stop protocol-based donations.

-

It is a simple short ZIP.

-

Hopefully it will be compatible with a number of other ZIPs and can be worked into them.

-
-

Out of Scope for this Proposal

-
    -
  • Governance on how decisions are made; this ZIP is not meant to be used as a form of governance.
  • -
  • Future funding.
  • -
  • It does not cover other donations or revenue streams.
  • -
-
-

Motivation

-
    -
  • The Founders’ Reward is set to expire in 2020.
  • -
  • To honour the initial promise of giving 90% of total block distribution to miners. Therefore the protocol will give them 100% of the block distribution after the first halving.
  • -
-
-

Requirements

-
    -
  • The Founders’ Reward MUST end at the first halving in October 2020.
  • -
  • This ZIP does not preclude the Electric Coin Company from sourcing funding elsewhere, or from donations.
  • -
-
-

Specification

-
    -
  • The existing Founders’ Reward consensus rules 4 5 MUST be preserved.
  • -
  • Specifically, FoundersReward(height) MUST equal 0 if Halving(height) >= 1. (For clarity once the halving happens the Founders’ Reward stops, as per the rules outlined in 4 and 5.)
  • -
  • This specification is only meant to stop the Founders’ Reward, not protocol-based donations.
  • -
  • Enforcing some kind of mandatory donation via whatever mechanism would be seen as continuation of the Founders’ Reward.
  • -
-
-

Implications to other users

-
    -
  • Block distribution payouts to Founders’ Reward addresses will cease at the first halving.
  • -
  • Pools and other software need to take this into account.
  • -
-
-

Technical implementation

-

This ZIP requires no changes to current consensus implementations.

-
-

References

- - - - - - - -
2Information 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"
- - - - - - - -
3Zcash blog: Funding, Incentives, and Governance. February 1, 2016
- - - - - - - -
4Zcash Protocol Specification, Version 2019.0.8 exactly. Section 7.7: Calculation of Block Subsidy and Founders Reward
- - - - - - - -
5Zcash Protocol Specification, Version 2019.0.8 exactly. Section 7.8: Payment of Founders’ Reward
-
-
- - \ No newline at end of file diff --git a/rendered/zip-1002.html b/rendered/zip-1002.html deleted file mode 100644 index 35a0b1020..000000000 --- a/rendered/zip-1002.html +++ /dev/null @@ -1,151 +0,0 @@ - - - - ZIP 1002: Opt-in Donation Feature - - - -
-
ZIP: 1002
-Title: Opt-in Donation Feature
-Owners: mistfpga (zcash forums) <steve@mistfpga.net>
-Status: Obsolete
-Category: Consensus Process
-Created: 2019-07-17
-License: CC BY-SA 4.0 <https://creativecommons.org/licenses/by-sa/4.0/>
-Discussions-To: <https://forum.zcashcommunity.com/t/zip-proposal-a-genuine-opt-in-protocol-level-development-donation-option/33846>
-

Terminology

-

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

-

This ZIP defines these terms:

-
    -
  • Signalling is defined as expressing a voice through whatever mechanism is implemented or sought for that decision. In the context of this ZIP it primarily refers to signalling what to do with funds. This could be done by miners, straw poll, coinbase, proof of value, some internet poll thing, etc.
  • -
  • Mining software in the context of this ZIP refers to pool software, local mining software, or staking software.
  • -
  • Custodial services include any service in which a party controls the private keys of another party; mining pools and online wallets are examples.
  • -
  • Mining is defined as the action of processing transactions, so this would include proof of stake, if Zcash would switch to that.
  • -
  • User is defined as anyone that uses ZEC or another coin that adopts this ZIP.
  • -
  • Mining coins transferred via fees are considered rewards (infinite), coins generated via block generation are considered distribution (finite).
  • -
  • Opt-in vs opt-out - Opting out is a purely selfish act in the context of this ZIP. They do not burn the coins therefore giving everyone value. They keep them.
  • -
  • Burning coins is purposefully taking them out of circulation forever at the protocol block distribution level.
  • -
  • Initial promise is defined as complete honour of distributing all rewards to the miner. - This is a non neutral phrase. I accept that.
  • -
  • Transaction sender is defined as anyone who sends a transaction across the Zcash network, be it t-t, z-z, t-z, z-t.
  • -
  • Fee is the standard transaction fee that a sender puts on a transaction to get it included into a block and that is collected by the miner of that block.
  • -
  • Transaction donation is an optional signalling string that creates a payment to the coins base donations.
  • -
  • Block Reward is defined as block distribution plus mining fees.
  • -
  • Spirit is defined as what is the intended outcome of the ZIP. 1
  • -
- - - - - - - -
1If there is contradiction between Spirit and any other part of the proposal that needs to be addressed, in the event it is not addressed Spirit is assumed to overrule all.
-
-

Out of Scope for this Proposal

-

Governance on how decisions are made. This ZIP is not meant to be used as a form of governance. It is a protocol-level opt-in for supporting the Zcash network development (like the Founders’ Reward, just with opt-out).

-

Signalling. Whilst a lot of the ZIP relies on the ability to signal intent in one way or another, it does not put forward such a mechanism and is designed to work with various form of signalling, or potentially without signalling at all.

-
-

Abstract

-

The spirit of this ZIP is:

-
    -
  • To allow continual funding of the Electric Coin Company, the Zcash Foundation, or some combination of these should a user choose to do so.
  • -
  • To add a genuine opt-in feature, which is done at the user's choice.
  • -
-
-

Motivation

-

Technology changes, and it changes fast. What works now, may be easily breakable in 10 years, 20 years and certainly 50 years.

-

To help ensure ZEC can keep up with these changes, now and in 50 or 500 years' time, there needs to be a continual funding for research into new technology and financial stability in order to attract new talent.

-

The only source of indefinite wealth transfer is transaction fees or donations. This ZIP is specifically about voluntary donations (including via mining fees).

-
-

Requirements

-
    -
  • An additional opt-in mechanism, baked into the protocol. This is a condition of the Zcash Foundation too. 2
  • -
  • Give an alterative to redistribution of either the current block distribution structure or the emission curve.
  • -
  • The funding received by the Electric Coin Company and/or Zcash Foundation under this proposal MUST only be used to fund ZEC development for the lifetime of their receipt of it.
  • -
  • To give a strong indication to the community and users that they have freedom to decide what they do with their coins and donations.
  • -
  • Bake the addresses into the node codebase, in order that the wallet software or pool software does not need to keep track of donation addresses.
  • -
  • Prevent users from sending donations to old addresses.
  • -
  • Make it easier for pools to add support and prove that they are actually donating the percentage they say they are.
  • -
  • Users MUST NOT be forced to signal.
  • -
- - - - - - - -
2The Zcash Foundation has stated (later clarified in 4) that the Foundation would only support proposals that: a) don’t rely on the Foundation being a single gatekeeper of funds; b) don’t change the upper bound of ZEC supply; and c) have some kind of opt-in mechanism for choosing to disburse funds (from miners and/or users).
-
-

Specification

-
    -
  • This ZIP MUST enforce the initial promise as defined by default.
  • -
  • The official client MUST default to be counted as initial promise.
  • -
  • No signal MUST be counted as whatever the pool is signalling for, when using a pool.
  • -
  • Security MUST NOT be lessened.
  • -
  • This ZIP MAY be set to opt-in via a user set flag.
  • -
  • This ZIP MUST contain donation addresses in the coinbase, in a similar fashion to the current FR.
  • -
  • When sending transactions the sender MAY signal their donation.
  • -
  • A signal from a transaction sender MUST NOT override the default transaction processor signal for that transaction.
  • -
  • A transaction sender MAY elect to include separate donation fees which MUST NOT be overridden by the transaction processor if this used or not.
  • -
-

this proposal is being published as a ZIP for the purpose of discussion and for the Zcash Foundation's sentiment collection process, despite significant issues with lack of clarity in the above specification.

-
-

Raised objections and issues so far

-
    -
  • This adds complexity to the protocol, which is technically not needed and generally a bad idea.
  • -
  • This does not add anything that cannot already be done under the current protocol by users manually, although not to the same extent.
  • -
  • Block sizes, this may impact the motivation to increase block sizes should that need arise.
  • -
  • Signalling from shielded addresses to donations at taddresses?
  • -
  • Once zcash goes full z address, how will transparency of donations be proven?
  • -
  • ZEC is designed to not have high transaction fees or a secondary transaction fee market. Is this a core principle?
  • -
  • A similar goal can be achieved without initial promise and just burn - mistfpga: I dislike taking coins out of circulation intentionally - it is an attempt to avoid that.
  • -
  • Further note: If burn must be an option I would like to use something like the "rolling burn" option. this is not defined; it was intended that another ZIP be written to define it, but that has not been done.
  • -
-
-

Implications to other users

-
    -
  • Wallet development will need to be considered. Hopefully the requirements will lessen this impact after the first initial change.
  • -
  • What happens if the Electric Coin Company and/or the Zcash Foundation close down, will the donations: -
      -
    • go to into the mining fee
    • -
    • get burnt
    • -
    • get sent as change to the original sender
    • -
    • be distributed via some other mechanism?
    • -
    -
  • -
-
-

Technical implementation

-

Stuff that is already implemented in some form or another:

-
    -
  • Optional fees are already implemented in some wallet software.
  • -
  • Optional fees already cannot be overridden by miners.
  • -
  • Hardcoded donation addresses are already baked into the protocol so it should be minor work to adjust them to the signalling addresses.
  • -
  • Hardcoded donation address already cannot be changed by pools or software.
  • -
  • Signalling could be handled at the pool level
  • -
  • Pools already add their own addresses to the coinbase, including donations.
  • -
-
-

References

- - - - - - - -
3Information 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"
- - - - - - - -
4Zcash Foundation Guidance on Dev Fund Proposals. Zcash Foundation blog, August 6, 2019.
-
-
- - \ No newline at end of file diff --git a/rendered/zip-1003.html b/rendered/zip-1003.html deleted file mode 100644 index 8b675b1b2..000000000 --- a/rendered/zip-1003.html +++ /dev/null @@ -1,118 +0,0 @@ - - - - ZIP 1003: 20% Split Evenly Between the ECC and the Zcash Foundation, and a Voting System Mandate - - - -
-
ZIP: 1003
-Title: 20% Split Evenly Between the ECC and the Zcash Foundation, and a Voting System Mandate
-Owners: aristarchus (zcash forums)
-Status: Obsolete
-Category: Consensus Process
-Created: 2019-06-19
-License: MIT
-Discussions-To: <https://forum.zcashcommunity.com/t/dev-fund-proposal-20-split-between-the-ecc-and-the-foundation/33862>
-

Terminology

-

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

-

For clarity in this ZIP I define these terms:

-
-
2nd Halvening period
-
the 4-year period of time, roughly from October 2020 to October 2024, during which at most 5,250,000 ZEC will be minted.
-
3rd Halvening period
-
the 4-year period of time roughly from October 2024 to October 2028.
-
DF%
-
Dev Fund Percentage, the portion of newly minted ZEC in each block reserved for a development fund.
-
-
-

Abstract

-

This proposal would allocate a 20% Dev Fund Percentage to be split evenly between the Electric Coin Company (ECC) and the Zcash Foundation during the 2nd Halvening period. This proposal aims to be simple to implement, without a single point of failure, and comes with mandates for transparency, accountability and a mandate to build a development fund voting mechanism to be used during the 3rd Halvening period. This proposal is designed to strike a balance between ensuring that high quality development work can continue uninterrupted, with the need to further decentralize Zcash development funding as soon as possible.

-
-

Motivation

-

Strengths of this proposal:

-
    -
  1. Simple to implement. I would rather developers spend time scaling Zcash rather than implementing the development funding mechanism.
  2. -
  3. Developers will have several years to work on a great decentralized development funding voting mechanism.
  4. -
  5. 20% is a large enough percentage that there should be enough development funding for many different ZEC price scenarios. To those who want to decrease this percentage: Overpaying for security is a gift to miners, to the detriment of every other stakeholder in the Zcash community. I will even make the strong statement that intentionally overpaying the miners for security is stealing from the other stakeholders.
  6. -
  7. With two entities receiving funds there is no single point of failure.
  8. -
-
-

Requirements and Specification

-
    -
  1. DF% MUST be 20 percent, split evenly between ECC and the Zcash Foundation during the 2nd Halvening period.
  2. -
  3. The Dev Fund MUST only be spent on research, development and adoption of Zcash.
  4. -
  5. A voting system for development funding MUST be built and implemented in order to be used during the 3rd Halvening period.
  6. -
-

Voting System Requirements

-

Here are the general properties of the mandated voting mechanism. I don’t want to specify the technical implementation details, since I believe this is a job suited for the engineers building this system.

-
    -
  1. Voting SHOULD be private.
  2. -
  3. Only ZEC holders can vote.
  4. -
  5. Voting should happen on-chain.
  6. -
  7. In order to vote, you must lock your ZEC so it cannot be spent for a period of time. This is to force the voters to have ‘skin in the game’ and prevent someone nefarious from buying a lot of ZEC just before an election and then dumping it immediately after.
  8. -
  9. Voters can choose how long to lock their ZEC, and their voting power is proportional to the time that the ZEC is locked. For example, someone who votes with 10 ZEC and locks it for 6 months would have the same voting power as someone who votes with 20 ZEC and locks it for 3 months. Of course there must be a maximum lock time, perhaps a year, to prevent anyone from getting ‘infinite’ voting power by locking their ZEC permanently.
  10. -
  11. The final results of the vote should be transparent to and verifiable by everyone.
  12. -
  13. The system should be totally open and allow anyone/any organization to compete for funding to develop Zcash.
  14. -
-
-

Transparency and Accountability for the ECC and the Zcash Foundation

-

These requirements would apply to both ECC and the Zcash Foundation. The mandate is to adhere to these accountability requirements originally put forward by the Foundation:

-
    -
  • Monthly public developer calls, detailing current technical roadmap and updates.
  • -
  • Quarterly technology roadmap reports and updates.
  • -
  • Quarterly financial reports, detailing spending levels/burn rate and cash/ZEC on hand.
  • -
  • A yearly, audited financial report akin to the Form 990 for US-based nonprofits.
  • -
  • Yearly reviews of organization performance, along the lines of the State of the Zcash Foundation report 2.
  • -
-
-

Requirements Specifically for the ECC

-

Motivated by the Zcash Foundation’s proposal that the ECC become a non-profit 3, I am going to list general requirements for the ECC to abide by if they choose to receive funds and work on behalf of ZEC holders.

-
    -
  1. Because I share the Foundation’s concern that the ECC could be “beholden to its shareholders”, I am mandating that the ECC should be working in the service of the Zcash community and shall serve no other masters. The original investors/founders who are not still working in the service of the Zcash community SHOULD NOT have control over the use of the new development funds.
  2. -
  3. The revenue received from the Dev Fund SHOULD NOT be used to give further rewards to, even indirectly, the investors, founders, or shareholders of the ECC, who are not working on Zcash after the first halving. They have already received the Founders’ Reward and this new development fund is not supposed to further benefit them.
  4. -
  5. The ECC SHOULD offer competitive pay and a stake in upside of the success of Zcash as a way to attract the best and brightest. I do want the ECC be able to maintain a world class team capable of competing with the tech giants of the world (Google, Apple etc.).
  6. -
  7. The ECC SHOULD continue to engage with regulators and advocate for privacy preserving technology. The legal structure of the ECC must not hamper these critical efforts in any way.
  8. -
-

I am not mandating non-profit status for the ECC. Maybe that is the best legal structure, maybe something else is better.

-

Finally, in the event that the voting system isn’t implemented by the start of the 3rd Halvening period, the 20% of funds intended to go to the ‘voting development fund’ should instead not be minted.

-
-
-

References

- - - - - - - -
1Information 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"
- - - - - - - -
2The State of the Zcash Foundation in 2019. Zcash Foundation blog, January 31, 2019.
- - - - - - - -
3Zcash Foundation Guidance on Dev Fund Proposals. Zcash Foundation blog, August 6, 2019.
-
-

Change Log

-
    -
  • 2019-06-19 Initial post
  • -
  • 2019-26-07 Listed three strengths of this proposal
  • -
  • 2019-08-13 Voting System Requirements
  • -
  • 2019-08-20 Requirements Specifically for the ECC
  • -
  • 2019-08-29 Update to be more like a ZIP draft.
  • -
-
-
- - \ No newline at end of file diff --git a/rendered/zip-1004.html b/rendered/zip-1004.html deleted file mode 100644 index e4ea6d50c..000000000 --- a/rendered/zip-1004.html +++ /dev/null @@ -1,148 +0,0 @@ - - - - ZIP 1004: Miner-Directed Dev Fund - - - -
-
ZIP: 1004
-Title: Miner-Directed Dev Fund
-Owners: Andrew Miller (@amiller on zcash forums)
-Status: Obsolete
-Category: Consensus Process
-Created: 2019-06-19
-License: public domain
-Discussions-To: <https://forum.zcashcommunity.com/t/dev-fund-proposal-miner-directed-dev-fund-was-20-to-any-combination-of-ecc-zfnd-parity-or-burn/33864>
-

Terminology

-

The key words "MUST", "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.

-

For clarity, this ZIP defines these terms:

-
-
2nd Halvening Period
-
the 4-year period of time, roughly from October 2020 - October 2024, during which at most 5,250,000 ZEC will be minted.
-
DF%
-
Dev Fund Percentage, the portion of newly minted ZEC in each block reserved for a development fund.
-
MR%
-
Miner Reward Percentage, the portion of newly minted ZEC in each block given to miners (so that DF% + MR% = 100%).
-
-
-

Abstract

-

This proposal reserves a portion (20%) of the newly minted coins in each block for the development fund. A fixed set of developer entities would be eligible to receive these funds. The fund would be miner-directed in the sense that the miner of each block can determine how to allocate these funds to eligible developers.

-
-

Out of Scope for this proposal

-
    -
  • This proposal does not (currently) specify any process for reaching agreement on or modifying the fixed set of development entities.
  • -
  • This proposal does not specify how miners should reach a decision on how to direct the development fund, or how developers should appeal to miners to do so. Other development fund proposals include specific processes for accountability and to support community decision making, such as monthly developer calls, lists of planned features and goals, etc. Any of these can be compatible with this proposal as well, by providing non-binding advice to miners, by reaching agreement on implementation defaults, by guiding the choice of the fixed set of developers, etc.
  • -
  • This proposal only provides a guideline for the 2nd Halvening Period.
  • -
-
-

Motivation

-

Like most development fund proposals, this is motivated by the potential value to the Zcash community of using newly minted coins to hire developers to continue improving Zcash. 2

-

Unlike most other development fund proposals, this proposal is distinct in providing a fine-grained “opt-in” 3 feature, since miners have the choice to provide a small amount of development funding or none at all.

-
-

Requirements

-
    -
  • Simplicity: A design goal of this proposal is to be simple to define and implement, without specifying much process for on-chain or off-chain governance.
  • -
  • Opt-in: The proposed development fund is not mandatory, since miners can decide not to allocate any funds at all to the developer entities.
  • -
  • Incentive-compatible: Miners cannot directly pay the development fund to themselves.
  • -
-
-

Specification

-

During the 2nd Halvening Period, a fixed portion (DF% = 20%) of the newly minted coins in each block are reserved for a Miner-Directed Dev Fund (MDDF). A hardcoded set of developer entities (e.g., Electric Coin Company, Zcash Foundation, Parity, or others), represented in the code by their t-address or z-address public keys, are eligible to receive funding from the MDDF. The fund is “miner-directed” in the sense that the miner in each block chooses how to allocate the MDDF coins among the developer entities, simply by creating outputs in the coinbase transaction. The DF% is a maximum — miners can also “opt out” by minting a lower number of coins for the MDDF, or none at all.

-

This proposal is explicitly limited in scope to the 2nd Halvening Period. After the end of this period, the entire block reward in each block is awarded to the miner. The upper bound on the rate of newly minted coins MUST remain the same as before this proposal (i.e., at most 25 ZEC minted per 10 minutes during the 2nd Halvening Period).

-

Implementations MAY define a default opt-in allocation (e.g., DF%/2 to the Electric Coin Company and DF%/2 to the Zcash Foundation).

-

Implementations SHOULD support changing the allocation (overriding any such default) through a configuration option.

-

Examples

-

The following examples illustrate how miners can build the outputs of the coinbase transactions to allocate the MDDF to eligible developers. Assume Dev1, Dev2 are the hardcoded addresses of eligible developers, and Miner is the address of the mining pool mining this block. Assume that the total newly minted coins are 3.125 ZEC per block during the 2nd Halvening Period (this takes into account the change to a 75-second block target spacing after the Blossom Network Upgrade 5), and that DF% = 20%, MR% = 80%.

-

Example 1: Split equally between two developers

-

The transaction outputs of the coinbase transaction are as follows:

-
    -
  • 2.5 ZEC to Miner
  • -
  • 0.3125 ZEC to Dev1
  • -
  • 0.3125 ZEC to Dev2.
  • -
-

Example 2: Opt-out of the development fund

-

The transaction outputs of the coinbase transaction are as follows:

-
    -
  • 2.5 ZEC to Miner.
  • -
-
-
-

Issues and Further Discussion

-

Raised objections and issues so far:

-
    -
  • Miners may have adverse incentives, such as: -
      -
    • Stonewalling any development of Proof-of-Work alternatives, such as GPU-friendly variants or Proof-of-Stake.
    • -
    • Extortion for more funds. To illustrate: "We’ll direct all 20% of the development fund to DeveloperX, but only if they promise to keep just 5% and pass 15% back to the mining pool.”
    • -
    • Blocking the development fund out of greed.
    • -
    -
  • -
  • This proposal modifies the terms of what some may consider a social contract: given the original code in Zcash implementations, by the end of the issuance schedule when all 21 million ZEC have been minted, a total of 90% of all minted coins would have originally been awarded to miners. Under this proposal, less reward would be available to miners, than would be available to them according to the original minting schedule.
  • -
  • Several others, notably the Blocktown Capital proposal 4, have suggested that a 20% development fund would set a precedent for a perpetual 20% development fund. This proposal is explicitly limited in scope to the 2nd Halvening Period. Thus adopting this proposal on its own, if there are no further updates, would result in the the development fund ending in 2024.
  • -
-
-

References

- - - - - - - -
1Information 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"
- - - - - - - -
2Notes on reaching agreement about a potential Zcash development fund. Andrew Miller, June 3, 2019.
- - - - - - - -
3Comment on a post “The future of Zcash in the year 2020” in the Zcash Community Forum. Josh Cincinnati, June 3, 2019.
- - - - - - - -
4Executive Summary: Blocktown Proposal for Zcash 2020 Network Upgrade. Blocktown Capital, August 15, 2019.
- - - - - - - -
5ZIP 208: Shorter Block Target Spacing
-
-

Change Log

-
    -
  • 2019-06-19 Initial post
  • -
  • 2019-08-28 -
      -
    • Update to be more like a ZIP draft
    • -
    • Renamed to Miner-Directed Dev Fund
    • -
    • Removed references to “Burn”, instead opt-out is in terms of coins never being minted in the first place
    • -
    -
  • -
  • 2019-08-29 -
      -
    • Address informal pre-ZIP feedback
    • -
    • Add example, requirements, fix incomplete sentence about default allocations
    • -
    -
  • -
  • 2019-09-15 Move to GitHub
  • -
-
-
- - \ No newline at end of file diff --git a/rendered/zip-1005.html b/rendered/zip-1005.html deleted file mode 100644 index 5da3c7c90..000000000 --- a/rendered/zip-1005.html +++ /dev/null @@ -1,69 +0,0 @@ - - - - ZIP 1005: Zcash Community Funding System - - - -
-
ZIP: 1005
-Title: Zcash Community Funding System
-Owners: Dimitris Apostolou <dimitris.apostolou@icloud.com>
-Status: Obsolete
-Category: Consensus Process
-Created: 2019-06-23
-License: MIT
-Discussions-To: <https://forum.zcashcommunity.com/t/zip-proposal-zcfs-zcash-community-funding-system/33898>
-

Abstract

-

This proposal introduces a new funding mechanism called the Zcash Community Funding System (ZCFS).

-
-

Motivation

-

The motivations for ZCFS are:

-
    -
  • The Founders’ Reward is set to expire in 2020.
  • -
  • The Founders’ Reward has caused significant friction in the Zcash community and sparked forks due to disagreement with its very existence.
  • -
  • There needs to be a more fair and decentralized funding mechanism.
  • -
-
-

Specification

-

This specification is a modification of the Monero Community Crowdfunding System (CCS) and is defined as follows:

-
    -
  1. The Founders’ Reward ends in October 2020 as specified by the current consensus rules.
  2. -
  3. An individual, team or company (for-profit or non-profit), henceforth ‘proposer’, has an idea to improve the Zcash ecosystem that requires funds.
  4. -
  5. The proposer creates a ZCFS proposal in a modified version of the existing ZF Grants website, to be called the ZCFS website. The ZF Grants website already has the basic infrastructure for this mechanism and needs to be tweaked in order to facilitate this specification. The ZF Grants website will continue to operate in its current form.
  6. -
  7. Upon activation of this proposal, the Zcash Foundation is put in charge of the ZCFS.
  8. -
  9. The Zcash Foundation is required to make ZCFS proposals for its own funding. If the community decides not to fund it, then the ownership of the ZCFS is transferred to the proposer who is instead funded by the community for that matter. the meaning of "the proposer" here is unclear.
  10. -
  11. After a ZCFS proposal has been created, the community discusses the pros and cons of the proposal, and offers feedback and critique.
  12. -
  13. The proposer changes the proposal (if necessary), utilizing the feedback and critique of the community.
  14. -
  15. Repeat steps 6 and 7 as needed.
  16. -
  17. After the Zcash Foundation (or whoever has ownership of the ZCFS at the time) has determined that the community has reached loose consensus, the funding begins by ZEC holders who wish to donate.
  18. -
  19. Once fully funded (not guaranteed), the proposer begins on the work, if they haven’t already.
  20. -
  21. Milestones are completed and funds are disbursed upon their completion.
  22. -
  23. After all milestones are completed, the proposal is locked and all information is retained for posterity.
  24. -
-
-

Rules and Expectations

-

The ZCFS is intentionally left as informal as possible. This allows for flexibility of the system, and keeps things from being red-taped into oblivion. However, there are some things you should understand, things that will be expected of you, as either a proposer or a donor, and a recommended way of structuring a proposal for maximum likelihood that your project will be funded.

-

For Donors

-
    -
  1. The ZCFS is escrowed by the Zcash Foundation (or whoever has ownership of the ZCFS at the time). When you make a donation, you are releasing funds to them to disburse when they deem the community agrees that a milestone is complete. They do not do the work to verify donors, and the final decision for all disputes falls with them, although they do their best to follow community sentiment.
  2. -
  3. In the event that a proposal is overfunded, unable to be completed, or otherwise put in a state where donated money will not be disbursed to the proposer, the default is that the remaining ZEC will be put in the ZF Grants fund.
  4. -
  5. Refunds are extraordinarily rare. Donate accordingly.
  6. -
  7. If the proposer disappears, no problem, someone else can pick up from their last milestone.
  8. -
  9. Milestone and payout structures vary per proposal based on the proposer’s wishes. It is up to the donor to do their due diligence in whether or not they support the proposal in its entirety.
  10. -
-
-

For Proposers

-
    -
  1. There is no guarantee that your project will get past the community feedback stage, and if it does, there is no guarantee that it will be funded.
  2. -
  3. You have to drum up support for your proposal during the feedback and funding stages. Do not expect others (especially the Zcash Foundation or other trusted members of the community) to do it for you. Others may share and support if they are excited about your project, but ultimately it is nobody’s responsibility but your own.
  4. -
  5. It is expected that you provide updates on the progress of your proposal to the community. For every milestone completed there should be a written report put into your ZCFS proposal announcing its completion and the work done, but depending on the timeline of your project, it may be wise to update the community more frequently.
  6. -
  7. All work must be licensed permissively at all stages of the proposal. There is no time where your work can be licensed under a restrictive license (even as you’re working on it). Your proposal will be terminated if this is not remedied.
  8. -
  9. You may NOT under any circumstances include a donation address directly in your proposal. This circumvents the ZCFS, and can lead to scams.
  10. -
  11. Your work on the project can begin before the proposal is fully funded but disbursement of funds is done only upon completion of milestones and only if the proposal is fully funded.
  12. -
-
-
-
- - \ No newline at end of file diff --git a/rendered/zip-1006.html b/rendered/zip-1006.html deleted file mode 100644 index bc3fdc188..000000000 --- a/rendered/zip-1006.html +++ /dev/null @@ -1,200 +0,0 @@ - - - - ZIP 1006: Development Fund of 10% to a 2-of-3 Multisig with Community-Involved Third Entity - - - -
-
ZIP: 1006
-Title: Development Fund of 10% to a 2-of-3 Multisig with Community-Involved Third Entity
-Owners: James Todaro <james@blocktown.capital>
-        Joseph Todaro <joseph@blocktown.capital>
-Credits: Mario Laul
-         Chris Burniske
-Status: Obsolete
-Category: Consensus Process
-Created: 2019-08-31
-License: MIT
-Discussions-To: <https://forum.zcashcommunity.com/t/blocktown-development-fund-proposal-10-to-a-2-of-3-multisig-with-community-involved-third-entity/34782>
-

Terminology

-

The key words “MUST”, “SHOULD”, “SHOULD NOT”, 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 additional terms below are to be interpreted as follows:

-
-
Mining
-
The actions of processing transactions, which include processing transactions in a Proof-of-Stake or Proof-of-Work/Proof-of-Stake hybrid system, in the event Zcash implements either at a future date.
-
Mining software
-
Pool software, local mining software or staking software.
-
Mining rewards / Block rewards
-
Network transaction fees and/or coinbase rewards (e.g. newly issued ZEC associated with block generation).
-
Network Upgrade
-
Any consensus rule change to the Zcash protocol, introduced as part of the standard Zcash Network Upgrade Pipeline 9 or otherwise.
-
Founder’s Reward
-
The 20% ZEC from mined blocks allocated to the Electric Coin Company (ECC), Zcash Foundation (ZF), employees, investors and/or other entities prior to the expected first halving in October 2020.
-
Zcash Development Fund
-
Transparent address(es) controlled jointly by the Electric Coin Company, Zcash Foundation, and a “Third Entity”. The fund is intended for research, development, maintenance, and other technical work directly connected to the Zcash protocol, as well as non-technical initiatives (including design, marketing, events, regulatory outreach, education, governance, and any other form of business or community development) that contribute to the long-term success of the Zcash network. In the context of this proposal, the Zcash Development Fund consists of 10% of newly issued ZEC from block rewards between the first and second halvings of the Zcash network.
-
Applicant
-
Any individual, group, or entity that seeks funding from the Zcash Development Fund.
-
Recipient
-
Any individual, group, or entity that receives funding from the Zcash Development Fund.
-
-
-

Abstract

-

This proposal puts forward the financing mechanism and fundamental rules of governance for the creation of a Zcash Development Fund.

-
-

Specification

-

Funding mechanism of the Zcash Development Fund

-
    -
  • This funding mechanism MUST be hard-coded so that 10% of newly issued ZEC from block rewards are automatically directed to the transparent address(es) of the Zcash Development Fund.
  • -
  • The above requirement MUST be met between the first halving and second halving. Upon the second halving, future governance decisions MAY result in a further decrease of the Zcash Development Fund to 5% of newly issued ZEC from block rewards, or alternatively MAY result in another percent allocation which includes the possibility of a system whereby 100% of block rewards go to miners.
  • -
  • The two aforementioned requirements above MUST remain regardless of any additional Network Upgrades or changes to mining or mining software prior to the second halving.
  • -
  • The Zcash Development Fund MAY outlive the period of its initial funding mechanism, either through the appreciation in the price of ZEC, or from alternative funding sources upon the second halving in 2024.
  • -
  • The hard-coded transparent address(es) of the Zcash Development Fund MAY be periodically rotated for operational security purposes to decrease the risk of any potential loss of funds associated with the address(es). The ECC, ZF, and/or “Third Entity” described below SHOULD take any possible precautions within the confines of this Specification section to avoid loss of funds.
  • -
-
-

Governance of the Zcash Development Fund

-
    -
  • Funds allocated to the Zcash Development Fund MUST be used only for their intended purpose as defined in the following Rationale section of this proposal.
  • -
  • The transparent address(es) of the Zcash Development Fund MUST be jointly controlled by the ECC, ZF, and Third Entity, and all funds transferred from the Zcash Development Fund MUST be publicly confirmed in an official manner by a majority decision among the ECC, ZF, and Third Entity–commonly referred to as “2-of-3 multisig”. That is, funding decisions MUST be put to an officially documented vote which MUST NOT pass unless at least 2 of the 3 entities above vote approvingly.
  • -
  • Prior to any movement of funds from the Zcash Development Fund, the ZF and ECC MUST coordinate with each other and the community to establish the Third Entity that will be involved in governance of the Zcash Development Fund. The process of determining the exact initial composition and rules of governance of the Third Entity MUST involve the Zcash community at large in a process similar to that outlined in the section "How the Foundation will select a particular proposal" in the ZF’s August 6, 2019 statement 2.
  • -
-

The governance rules of the Third Entity MUST include the following:

-
    -
  • All decision-making and other governing processes of the Third Entity MUST be independent of the ECC and ZF, and MUST include measures that are necessary to avoid conflicts of interest in relation to the ECC and ZF.
  • -
  • At creation, the Third Entity MUST include an uneven number of at least 5 individuals with independent previous affiliations, each having a single vote. All such decisions MUST have majority support within the Third Entity to result in an overall approving vote by the Third Entity.
  • -
  • Once the Third Entity is established, it MAY decide to change its rules of governance (e.g. simple majority versus supermajority rules), but any such change MUST be preceded by the involvement of the Zcash community at large, similar to the process outlined in the ZF’s August 6, 2019 statement 2.
  • -
  • Once the Third Entity is established as a self-governing body, it SHOULD evolve toward a system whereby ZEC holders have a direct role in determining votes and internal governance of the Third Entity.
  • -
  • The Third Entity MAY apply for funding from the Zcash Development Fund, if deemed appropriate by its governing body. This would be subject to a majority vote by the ECC, ZF and Third Entity.
  • -
-

Prior to any transfer of funds from the Zcash Development Fund, the ECC, ZF, and Third Entity MUST specify, approve, and make public the final rules on applying for and receiving funding from the Zcash Development Fund, including the details of the decision-making process for approving or rejecting funding requests. These rules MUST apply equally to all Applicants, including the ECC, ZF, and Third Entity, and MUST include the following:

-
    -
  • Funding from the Zcash Development Fund MUST be available to not only the ECC, ZF, and Third Entity but also to other individuals, groups, or entities that could make technical and/or non-technical contributions to Zcash as described in the Rationale section of this proposal.
  • -
  • To receive funding from the Zcash Development Fund, all Applicants MUST follow the rules described in the Specification section of this proposal and in final detail by the ECC, ZF, and Third Entity.
  • -
  • As part of an application, each Applicant MUST produce a public overview of the activities and projected costs for which they are seeking funds.
  • -
  • Each funding decision MUST be preceded by a community review period of reasonable length to be determined by the ECC, ZF and Third Entity in which Zcash stakeholders and community members can familiarize themselves with the Applicant’s request and make suggestions, or raise objections.
  • -
  • In situations of overwhelming opposition from Zcash stakeholders and community members to requests from Applicants, the ECC, ZF, and Third Entity SHOULD NOT approve the request before striving to address stakeholders and community concerns, and modifying the request, if appropriate, to assuage concerns.
  • -
  • Each funding decision MUST be accompanied by an easily referenced joint public statement by the ECC, ZF, and Third Entity, which MUST include the final tally of the relevant vote, as well as the votes of the three involved entities. As part of this statement, each of the three entities MUST provide explicit justification for its respective vote.
  • -
  • The ZF MUST ensure that all Zcash Development Fund votes and the accompanying justifications described previously remain archived and easily accessible online by Zcash community members, stakeholders and the general public.
  • -
  • The ECC, ZF, and Third Entity MAY approve funding requests on a rolling basis, but all funding requests MUST be revisited and voted on at a minimum of every 6 months to receive renewed approval.
  • -
  • Recipients MUST publicize at minimum quarterly progress updates on their activities funded from the Zcash Development Fund. In the case of short-term assignments (less than 6 months), a single report upon completion of the project is sufficient. Standard reporting requirements MUST be specified by the ECC, ZF, and Third Entity prior to any approved requests from the Zcash Development Fund and additional requirements MAY be introduced as needed.
  • -
  • Depending on the nature of each request, funds MAY be disbursed in a single payment or incrementally, subject to objective milestones and/or other performance metrics.
  • -
-

Any decision to alter the governance of the Zcash Development Fund as described in this proposal and in final detail by the ECC, ZF, and Third Entity MUST involve the Zcash community at large, similar to the process outlined in the ZF’s August 6, 2019 statement 2. All transfers from the Zcash Development Fund MUST be in full accordance with the requirements described in this proposal.

-
-
-

Issues not addressed in this proposal/Out-of-Scope

-
    -
  • Details of the decision-making process for supporting or rejecting this or other relevant proposals by the ECC, ZF, and/or other Zcash stakeholders. We do maintain, however, that any decision by the ECC and/or the ZF on the issue described in the Motivation section below SHOULD be preceded by the procedures for measuring community sentiment as outlined in the ZF’s August 6, 2019 statement 2.
  • -
  • Additional methods for measuring community sentiment MAY include a way for ZEC holders to signal their support of specific proposals.
  • -
  • The matter of whether the ECC should reorganize itself into a non-profit or remain for-profit, as addressed by the ZF in their August 6, 2019 statement 2. The current proposal is neutral on this matter, and funding from the Development Fund would be available for non-profit and/or for-profit entities. We consider the governance rules of the Development Fund outlined in this Specification section adequate for transparency and accountability.
  • -
-
-

Motivation

-

The Zcash network is scheduled to undergo its first halving in October 2020, per current protocol specifications. At the time of the first halving, the codebase dictates that the Founder’s Reward, which consists of 20% of the ZEC from every block reward, will be terminated. Without codebase modification, for example in the upcoming NU4 Network Upgrade, 100% of block rewards would be claimed by miners after the first halving.

-

The two organizations presently leading development and maintenance of the Zcash network receive funds from the Founder’s Reward. These organizations, the ECC and ZF, have recently requested a source of funding after the first halving in order to continue operations for the foreseeable future. The source of funds could theoretically be from either a modification to the codebase dictating a Zcash Development Fund from block rewards or, alternatively, from external sources. The ECC has indicated though that it would “wind down or pivot” rather than accept funding from any sources that would give “special interests” control over the ECC 3.

-

Based on the ECC’s demands, the block reward appears to be the most agreeable source of resources for a Zcash Development Fund.

-

This proposal, originally published in the Zcash Community Forum on August 14, 2019 4 and formalized further in a blog post on August 23, 2019 5, outlines the funding mechanism and governance of such a Zcash Development Fund. Herein, we propose a feature of NU4 whereby 10% of the ZEC from every new block reward between the first halving and second halving would be directly deposited in a Zcash Development Fund.

-

For the period between the launch of the Zcash network in 2016 and the first halving, there has been a centralized 20% fee known as the Founder’s Reward taken from the block reward. Other active ZIP drafts advocate a Zcash Development Fund of 20% allocation from the block reward after the first halving. We believe that a cumulative eight years of centralized fees from the block reward at the identical rate of 20% would ultimately result in a narrow community that accepts the likelihood of a perpetual 20% fee on the Zcash network.

-

With a Zcash Development Fund that is only 10% of the block reward, a precedent will be set that a large centralized fund is not indefinite and will decrease faster than simply the rate of block reward halvings. Although this proposal specifically addresses the period between the first and second halving, this proposed feature may set a precedent whereby the percent fee from block rewards allocated to a Zcash Development Fund continually decreases every halving, e.g. 20% (FR) from 2016-2020, 10% from 2020-2024, 5% from 2024-2028, 2.5% from 2028-2032 (effectively quartering the ZEC allocated to a development fund every four years). We believe that this social contract could restore the community’s faith in the decentralization of Zcash as the network incentives align more closely with that of Bitcoin’s over time. Alternatively, it is not unreasonable for the Zcash governance system to elect a 0% allocation for the Zcash Development Fund upon the second halving. For a more detailed exploration regarding the selection of 10%, please review the blog post ‘Proposal for 10% Dev Fund in Zcash 2020 Network Upgrade’ 6.

-

Of note, we are not suggesting or implying that the funding from the Founder’s Reward and a Zcash Development Fund would be managed in a similar way or have similar directives. The Zcash Development Fund feature that we propose for NU4 does not allocate any funds to former angel investors, VCs or vested employees. Furthermore, the Zcash Development Fund would be subject to more explicit and transparent rules of governance, as outlined in the Specification section of this proposal.

-
-

Rationale

-

The rationale behind this proposal is as follows:

-
    -
  • To provide financial resources for research, development, and any other technical work connected to software upgrades/maintenance of the Zcash protocol, as well as non-technical initiatives including marketing, design, events, regulatory outreach, education, governance, and any other form of business that contribute to the success of the Zcash network.
  • -
  • To increase decentralization and network security of the Zcash network.
  • -
  • To increase decentralization through greater community involvement in Zcash governance and resource allocation.
  • -
  • To establish basic rules of governance and accountability regarding the deployment of funds in the Zcash Development Fund.
  • -
  • To encourage transparency and cooperation among Zcash stakeholders and strengthen the community’s governance capabilities moving forward.
  • -
-
-

Discussion

-

Recognized objections to this proposal include:

-
    -
  • This proposal is not in accordance with the current Zcash protocol, which is programmed to allocate 100% of the coinbase to miners upon the first halving in 2020. However, at least during the next few years of Zcash’s infancy, we believe it is advantageous to have a funded and dedicated development team.
  • -
  • The funding mechanism in this proposal is a Zcash Development Fund consisting of 10% of newly issued ZEC from block rewards after the first halving. This is in contrast to other proposals that allocate 20% of the mining rewards to the Zcash Development Fund – presumably a popular selection because the original Founder’s Reward was also set at 20%. For reasons we have explored in depth 6 and summarized in 7, we believe 10% instead of 20% is superior for network security, decentralization, uniting the Zcash community and renewing interest in ZEC.
  • -
  • Various parameters of governance in approving Applicant requests for funding from the Zcash Development Fund.
  • -
  • The inclusion of a Third Entity in governance. One notable objection is the possibility of collusion between Third Entity and either the ECC or ZF that would result in a “usurped” Zcash Development Fund. We believe that the process for a community elected Third Entity, however, will mature over time – giving the community and Zcash stakeholders that important third opinion in deciding the proper allocation of funds. As demonstrated by the resilience of the Bitcoin network and community, well-formed communities tend to resist any collusion with corporations and controlling entities that do not promote the direct success of the network. Moreover, the inclusion of a Third Entity has the advantage of offering a “tie-breaker” in the event of a deadlock vote between the ECC and ZF and/or a situation where one entity holds the other hostage, which is a possible scenario in a 2-of-2 multisig agreement.
  • -
  • This proposal does not have a clause dictating that a Recipient must abstain from voting. If a Recipient must abstain from voting in a 2-of-3 multisig governance system, then this could –as in the case of 2-of-2 multisig– result in an entity holding another hostage. For example, if the ECC refuses to fund the ZF until the ZF complies with the ECC’s demands, then the ECC has the power to deadlock any vote to fund the ZF, which requires the ECC and Third Entity to both vote approvingly.
  • -
-
-

Acknowledgements

-

Aspects of this proposal, particularly the Terminology and Specification sections, were adapted and expanded definitions and concepts put forth in Placeholder’s dev fund proposal from August 22, 2019 8.

-
-

References

- - - - - - - -
1Information 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"
- - - - - - - -
2Zcash Foundation Guidance on Dev Fund Proposals. Zcash Foundation blog, August 6, 2019.
- - - - - - - -
3ECC Initial Assessment of Community Proposals. Electric Coin Company blog, August 26, 2019.
- - - - - - - -
4Proposal for the Zcash 2020 Network Upgrade (topic on the Zcash community forum).
- - - - - - - -
5Blocktown Proposal for Zcash 2020 Network Upgrade. Blocktown Capital, August 23, 2019.
- - - - - - - -
6Proposal for 10% Dev Fund in Zcash 2020 Network Upgrade. Blocktown Capital, August 14, 2019.
- - - - - - - -
7Executive Summary: Blocktown Proposal for Zcash 2020 Network Upgrade. Blocktown Capital, August 15, 2019.
- - - - - - - -
8Dev Fund Proposal: 20% to a 2-of-3 multisig with community-involved governance (topic on the Zcash community forum).
- - - - - - - -
9The Zcash Network Upgrade Pipeline. Electric Coin Company blog, December 3, 2018.
-
-
- - \ No newline at end of file diff --git a/rendered/zip-1007.html b/rendered/zip-1007.html deleted file mode 100644 index 8132f74d9..000000000 --- a/rendered/zip-1007.html +++ /dev/null @@ -1,104 +0,0 @@ - - - - ZIP 1007: Enforce Development Fund Commitments with a Legal Charter - - - -
-
ZIP: 1007
-Title: Enforce Development Fund Commitments with a Legal Charter
-Owners: @lex-node (zcash forums)
-        @mistfpga (zcash forums) <steve@mistfpga.net>
-Status: Obsolete
-Category: Consensus Process
-Created: 2019-08-24
-License: CC BY-SA 4.0 <https://creativecommons.org/licenses/by-sa/4.0/>
-Discussions-To: <https://forum.zcashcommunity.com/t/dev-fund-supplemental-proposal-enforce-devfund-commitments-with-legal-charter/34709>
-

Terminology

-

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

-

For clarity this ZIP defines these terms:

-
    -
  • Covenant is defined as a legally binding agreement, upon which a specific aspect of development of the Zcash protocol and/or adoption is scheduled and agreed.
  • -
-
-

Abstract

-

A supplemental proposal to ensure feature selection and work is community-driven.

-

Hopefully it will be compatible with a number of other ZIPs and can be worked into them.

-
-

Out of Scope for this Proposal

-
    -
  • This proposal does not address the merits, motivations or terms of any particular Development Funding Proposal.
  • -
  • Requirements and Implementation.
  • -
-
-

Motivation and Requirements

-

This proposal is supplemental to any Development Funding Proposal that places or purports to place conditions on how the Electric Coin Company (ECC) and the Zcash Foundation (ZF) use development funds, or take other related off-chain actions such as requirements and Covenants.

-

For example, the proposal 2 provides that “[f]unds accruing to the Zcash Development Fund MUST be used only for ... technical work directly connected to the various software implementations of the Zcash protocol.” However, once development funding is approved and implemented via a Network Upgrade, there will be no enforcement mechanism to ensure that the ZF and ECC abide by this requirement.

-

This proposal aims to provide such an enforcement mechanism. If this proposal is adopted, then the ECC and/or ZF, as applicable MUST enter into a legal agreement that would entitle ZEC holders to enforce ECC’s/ZF’s performance of any Covenants. For the purposes of this proposal we will refer to the legal agreement as the “DevFund Charter” or “Charter” for short, but it MAY also be styled in other ways – e.g. as a Constitution, Bylaws, Fund Governance Agreement, etc.

-

The DevFund Charter SHOULD be used to the benefit of all ZEC users, but the DevFund Charter MAY provide that an enforcement action requires the support of the holders of a plurality, majority or supermajority of ZEC. ZEC held by the ZF, ECC and their officers, directors, employees and/or affiliates SHOULD be excluded from the denominator in calculating the requisite plurality, majority or supermajority of ZEC.

-

a "plurality" in a vote means the option that received more votes than any other single option, but it is unclear how this applies to "a plurality of ZEC". Taking into account experience from stake-weighted voting in other cryptocurrencies, the threshold of a simple majority (50%), or more, of all *issued* ZEC voting for any enforcement action would seem to be an extremely high bar.

-

A quorum of yet-to-be-decided number of representatives from a number of groups specified by the DevFund Charter MAY provide that an enforcement action requires the support of the assigned representatives of each. One such mechanism SHOULD be ZEC balance, however this would require a 66% majority or a 85% supermajority. (These numbers are not binding and are up for discussion)

-

It is assumed that the Electric Coin Company, Zcash Foundation, or party with a direct conflict of interest SHOULD identify their vote/signal - which MAY be rejected from the vote.

-

Legal enforcement MAY occur in a court of law, non-binding mediation or binding arbitration. The DevFund Charter MAY also provide rights to other Zcash community constituencies, such as specified miners or the “Third Entity” contemplated by 2.

-
-

Rationale

-

Because ZEC holders do not have specific legal rights against the ECC or ZF, but MAY wish to condition renewed on-chain development funding on the ECC’s or ZF’s agreement to use the development funds in certain ways, ZEC holders should have the legal right to enforce ECC’s/ZF’s compliance with those agreements.

-
-

Specification

-
    -
  • If a Development Funding Proposal receives sufficient community support and requires certain Covenants on the part of ECC or ZF, and there is also sufficient community support for using this enforcement mechanism as applied to that proposal, then one or more attorneys MUST be engaged to draft a Charter that reflects those Covenants, and the Charter MUST become legally effective and binding at the same time as the other aspects of the Development Funding Proposal are implemented on-chain (e.g., at the same time as activation of the corresponding Network Upgrade, if a Network Upgrade is is required to implement the Development Funding Proposal).
  • -
  • Each pending Development Funding Proposal SHOULD be amended to specifically describe any Covenants that the ECC, ZF or any other relevant person or entity would be required to agree to as part of such Development Funding Proposal.
  • -
-
-

Open Issues

-
    -
  • Whether a plurality, majority or supermajority of ZEC are required to approve an enforcement action against ECC or ZF;
  • -
  • Logistics and technical implementation regarding the Charter, such as on-chain signalling/voting for enforcement;
  • -
  • Remedies under the Charter, such as “specific performance” (getting a court to order ZF or ECC to comply with a Covenant);
  • -
  • Discontinuation or reduction of development funding (which MAY occur by having Covenants that the ZF or ECC will prepare a Network Upgrade that discontinues or reduces development funding if so requested by holders of the requisite plurality, majority or supermajority of ZEC), etc.
  • -
-
-

Raised Concerns

-
    -
  • “Code is Law; This is Just Law!” -
      -
    • Objection: Relying on off-chain legal mechanisms is contrary to the cypherpunk ethos and/or the mission/ethos of Zcash.
    • -
    • Answer: This is a values judgment that some people may reasonably hold. However, one should also consider that “don’t trust, verify” is also a cypherpunk principle and that the off-chain nature of some requirements means that a code-based solution is currently not possible; therefore, a legal enforcement mechanism, while imperfect, may be preferable to no enforcement mechanism.
    • -
    -
  • -
  • “Social Coordination Impracticality/Risk” -
      -
    • Objection: ZEC holders prize anonymity, but legal enforcement of breached Covenants will require social coordination (people must agree to enforce the action, and someone must actually get a lawyer and go to court). Therefore, this mechanism will not be valuable to ZEC holders and could lead them to compromise their anonymity and thus be worse than useless.
    • -
    • Answer: The community should further discuss how, in practice, ZEC holders might securely coordinate to bring an enforcement action against ECC and the ZF if it were needed. Additionally, it should be considered that the mere possibility of legal enforcement due to the clear terms of a Charter may dissuade ECC and ZF from violating Covenants and thus, paradoxically, having a Charter may also mean that no legal action ever becomes necessary. Additionally, the “class action” legal structure in some jurisdictions may mean that the ZEC holders' community could find a ‘champion’ in the form of a class-action attorney, without ZEC holders being required to personally become involved or ‘out themselves’ as ZEC holders (other than one willing ZEC holder as class representative).
    • -
    -
  • -
  • “This Will Just Waste Funding On Lawyers” -
      -
    • Objection: This Charter will be novel and bespoke, and lawyers may charge high fees to draft it and give assurances that it is enforceable. This wastes money that otherwise could be spent on Zcash development.
    • -
    • Answer: This is a valid concern. The Zcash community may be able to crowdsource an initial rough draft of the Charter from lawyers in the community or even non-lawyers who may be willing to do research and make an attempt at an initial draft. Lawyers could be involved primarily to issue-spot and formalize the initial draft. ECC and ZF may have law firms on retainer that could perform the work at favorable rates. Lawyers may be willing to work at discounted rates due to the unique opportunity and prestige of developing this innovative blockchain governance mechanism. Additionally, any legal fees may be small as a percentage of the overall value at stake, which may be considerable if a 5-20% development funding block reward is authorized.
    • -
    -
  • -
-
-

References

- - - - - - - -
1Information 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"
- - - - - - - -
2ZIP 1006: Development Fund of 10% to a 2-of-3 Multisig with Community-Involved Third Entity
-
-
- - \ No newline at end of file diff --git a/rendered/zip-1008.html b/rendered/zip-1008.html deleted file mode 100644 index 608f553c1..000000000 --- a/rendered/zip-1008.html +++ /dev/null @@ -1,96 +0,0 @@ - - - - ZIP 1008: Fund ECC for Two More Years - - - -
-
ZIP: 1008
-Title: Fund ECC for Two More Years
-Owners: @kek (zcash forums)
-        @mistfpga (zcash forums) <steve@mistfpga.net>
-Status: Obsolete
-Category: Consensus Process
-Created: 2019-09-02
-License: CC BY-SA 4.0 <https://creativecommons.org/licenses/by-sa/4.0/>
-Discussions-To: <https://forum.zcashcommunity.com/t/kek-s-proposal-fund-ecc-for-2-more-years/34778>
-

Terminology

-

The key words "MUST" and "MUST NOT" in this document are to be interpreted as described in BCP 14 2 when, and only when, they appear in all capitals.

-

For clarity this ZIP defines these terms:

-
    -
  • Spirit is defined as what is the intended outcome of the ZIP. 1
  • -
- - - - - - - -
1If there is contradiction between Spirit and any other part of the proposal that needs to be addressed, in the event it is not addressed Spirit is assumed to overrule all.
-
-

Out of Scope for this Proposal

-

Everything except moving the development fund end date.

-
-

Abstract

-

The spirit of this proposal is to keep to the current structure of the Electric Coin Company (ECC) receiving funding from the block distribution for two years' worth of blocks after the first halving in October 2020.

-
-

Motivation

-

To give more time to work out the full ramifications of any potential pivot / slow down, yet keep "all in on ZEC" for two more years with as little disruption as possible.

-
-

Requirements

-

Nothing about distribution recipients changes.

-

The current distribution of the Founders’ Reward is dependent on arrangements between the participants that will, if not explicitly renewed, expire at the first halving. There are currently direct and indirect recipients other than the ECC and Zcash Foundation. It is unclear whether funding of the ECC and Foundation is intended to continue at the current absolute ZEC rate, or at the same rate relative to the block subsidy which halves in October 2020. Further specification would be needed in order to fulfil and clarify the spirit of the proposal.

-
-

Specification

-
    -
  • The ECC's portion of block subsidy MUST be 20%, until a block height corresponding to two years after the first halving, i.e. until October 2022.
  • -
  • A to-be-specified fraction of ECC's portion SHOULD be used to fund the Zcash Foundation.
  • -
-

A previous version of this ZIP stated the following requirements: "The ECC's portion of block subsidy MUST be capped at their projected 1.1m USD costs a month." and "The ECC's portion of block subsidy MUST NOT be greater than 10% of total block subsidy of any one block." These requirements were mistakenly introduced in the process of ZIP editing; they do not reflect the intent of the original author @kek. They are also inconsistent with the summary that was posted in the Community Sentiment Collection Poll blog post at <https://www.zfnd.org/blog/community-sentiment-collection-poll/>, which stated an ECC percentage of 20%. Votes on the Community Sentiment Collection Poll, the Community Advisory Panel Helios poll, and/or the stake-weighted petition reported at <https://forum.zcashcommunity.com/t/staked-poll-on-zcash-dev-fund-debate/34846/71>, should be interpreted with care in light of this ambiguity. Also note that the 1.1m USD cap could not in any case be specified as a consensus rule since there is no on-chain oracle for the USD price.

-

Rationale

-

Provisions that referred to specific block heights have been revised since they were inconsistent with the change in block target spacing 4 that will occur with the Blossom Network Upgrade 3; and even if recalculated, fixed block heights would potentially be inconsistent with future changes in target block spacing.

-
-
-

Raised objections and issues so far

-
    -
  • This is just kicking the can down the road.
  • -
  • The Zcash Foundation has raised objections to a single point of failure in the ECC.
  • -
-
-

Implications to other users

-
    -
  • The knock-on impact of this ZIP to exchanges and wallet developers may be nontrivial.
  • -
  • The economics of doing this have not been calculated.
  • -
-
-

References

- - - - - - - -
2Information 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"
- - - - - - - -
3ZIP 206: Deployment of the Blossom Network Upgrade
- - - - - - - -
4ZIP 208: Shorter Block Target Spacing
-
-
- - \ No newline at end of file diff --git a/rendered/zip-1009.html b/rendered/zip-1009.html deleted file mode 100644 index f3bf58abf..000000000 --- a/rendered/zip-1009.html +++ /dev/null @@ -1,153 +0,0 @@ - - - - ZIP 1009: Five-Entity Strategic Council - - - -
-
ZIP: 1009
-Title: Five-Entity Strategic Council
-Owners: Avichal Garg <avichalgarg@electriccapital.com>
-Status: Obsolete
-Category: Consensus Process
-Created: 2019-08-28
-License: MIT
-Discussions-To: <https://forum.zcashcommunity.com/t/dev-fund-proposal-5-entity-strategic-council-approach/34801>
-

Terminology

-

Key terms

-
-
Developer Fund
-
20% of the mined ZEC in the four-year period from approximately October 2020 to October 2024, during which at most 5,250,000 ZEC will be minted.
-
Strategic Council
-
A five-person committee that determines how to allocate the Developer Fund. Held accountable to the community via regular elections.
-
Executor
-
An individual, group, company, or other organization that receives funding from the Strategic Council. They are responsible for excellent execution and held accountable by the Strategic Council.
-
-
-

Abstract

-

This proposal reserves 20% of newly minted coins in each block for a Developer Fund. A five-person Strategic Council would be elected by the community every two years. The Strategic Council would determine the high level strategy, goals, and metrics to evaluate progress for the ecosystem on a six-month cadence. The Strategic Council would be responsible for allocating funding to Executors for the subsequent six months and summarizing the performance of Executors in the prior six months. Executors would submit proposals to the Strategic Council on a six-month cadence, including project plans, funding plans, and how they will measure success on a scale from 1-10. At the end of six months, Executors will grade themselves and the Strategic Council will summarize what was accomplished with a target of 7/10 in every quarter on a roll-up basis (a simple average of all of the outstanding projects for that six months).

-
-

Out of Scope for this Proposal

-
    -
  • How to do 1 person = 1 vote (and perhaps we cannot or should not do this).
  • -
  • How to structure the Strategic Council legally, i.e. should it be a Swiss Foundation and what sorts of legally binding responsibilities do the Strategic Council members have?
  • -
-
-

Motivation and Requirements

-

This is an attempt to put on my startup CEO hat and address the strategic and execution challenges I believe have held back Zcash from realizing its full potential.

-

Principles & Observations Based on My Experiences (a.k.a. Biases?)

-

Because layer 1 protocols are network-effect driven, without a quickly growing network-effect in miners, developers, users, and liquidity, a layer 1 protocol will ultimately collapse.

-

The primary driver of success in a network-effect business is how quickly you grow the network effects.

-

To grow a network effect, you must have both the correct strategy and excellent execution. If your strategy is not correct, no matter how well you execute, you will fail. If your execution is not excellent, you will not be able to assess whether lack of progress is due to poor execution or poor strategy.

-

Thus, to build the network effects Zcash needs to succeed, we must answer five questions:

-
    -
  1. Who determines the strategy?
  2. -
  3. How do they decide on the strategy?
  4. -
  5. How are they held accountable to having the correct strategy?
  6. -
  7. Who executes?
  8. -
  9. How are Executors held accountable to excellent execution?
  10. -
-

1. Who determines the strategy?

-
    -
  • Volunteer-based approaches require the ability for individuals or entities to accumulate significant quantities of the underlying coin. Bitcoin did this through obscurity and Grin is accomplishing this through extremely high inflation in the early years. Zcash has moved beyond this phase and thus I do not believe a volunteer-based approach could be effective. Thus, a developer fund (or similar approach) is the only realistic option for Zcash today.
  • -
  • Independent, high-quality governance enables better decisions and higher quality execution.
  • -
  • We should ideally have the recipients of the funds be different entities than the governance body that allocates funds to avoid conflicts.
  • -
  • Too few people in a decision-making process and people can collude. Too many and nothing gets done.
  • -
  • Good governance and leadership is a significant time commitment and requires significant support/resources.
  • -
  • There are a variety of perspectives that should be represented, including miners, developers, regulators, and users.
  • -
-

2. How do they decide on the strategy?

-
    -
  • Flexibility in how funds are used is important. Strategies and markets change over time and we should be able to evolve. Thus, we should not constrain how funds are used up front.
  • -
  • There should be no constraint to using all of the funds in any given time frame.
  • -
  • Creating and fostering decentralized ecosystem of miners and developers is important for the long-term health of the ecosystem.
  • -
  • A regular and predictable cadence in planning and goal setting makes it easy for teams to build, ship, and recharge between intense periods of building.
  • -
  • Transparency in the strategy, decision making of fund recipients, and how funds are distributed is paramount.
  • -
-

3. How are they held accountable to having the correct strategy?

-
    -
  • No organization or individual should have a permanent seat on a decision-making body. Regular elections enforce good behavior.
  • -
  • Third-party audits of financial behavior enforce good behavior and create transparency.
  • -
  • Bad actors should be able to be removed from any decision-making body for egregious violations of trust or misbehavior.
  • -
-

4. Who executes?

-
    -
  • Anyone should be able to participate in the execution.
  • -
  • Over time the best executors should have reputation accrue and be able to receive more funds.
  • -
  • There is value in having Executors distributed across geographies and across entities.
  • -
  • There is value in identifying Executors who have long-term commitments to Zcash and will be available for long-term support and maintenance of their work.
  • -
-

5. How are Executors held accountable to excellent execution?

-
    -
  • Excellent execution comes from having verifiable hypotheses, backed up with data, and clear milestones.
  • -
  • Executors need to submit concrete plans, with clear goals and metrics, and be judged according to both whether or not the goals were reasonable and whether they accomplished those goals (ideally in a measurable way using metrics).
  • -
  • Execution is best measured by pre-defining success and failure criteria, prior to having been influenced by the challenges of the task at hand.
  • -
-
-

Specification

-

1. Who determines strategy?

-
    -
  • A five-person/entity board -- Five people is better than three to minimize collusion.
  • -
  • Strategic Council should get two-year term so we can pivot people in the middle if necessary. No permanent seats.
  • -
  • For the purposes of voting to determine seats (not having seats vote on issues): one of the five seats should be allocated for miners and signaled through nodes. One of the five should be weighted by ZEC holding so 1 ZEC = 1 vote. Three of the five should be 1 person = 1 vote.
  • -
  • Elections should be open such that any person or entity can run for a seat.
  • -
  • The board is a paid position from Dev Fund emissions. Compensation TBD.
  • -
-

2. How do they decide?

-
    -
  • 20% of block rewards are allocated for the Developer Fund.
  • -
  • There should not be any limit up front on where money can go. Perhaps one year it makes sense to invest entirely in protocol and another year it makes sense to invest in user adoption via content marketing, SEO, SEM, etc.
  • -
  • Every six months, the board has a responsibility to publish an update to the strategy, key metrics that are being tracked, and key metrics to hit as goals in the next six months. This will require feedback from the community but ultimately the board needs to decide on and own the strategy.
  • -
  • Every six months, the board runs a process whereby anyone can submit proposals for how they would best accomplish these strategic objectives and hit those metrics and milestones.
  • -
  • No more than 33% of funds can go to one entity for development purposes. This enforces broad decentralization and encourages the ecosystem to identify new participants.
  • -
-

How are they held accountable for having the correct strategy?

-
    -
  • Elections every two years from the community.
  • -
  • All decisions and finances are audited by a third-party audit firm.
  • -
  • There is an annual meeting of all stakeholders (perhaps at Zcon?) for feedback, Q and A of the board, and a walk through of what has been accomplished in the last six months and what the proposals are for the next six months for feedback. The other six-month cadence meeting for the Strategic Council to present its plans and receive feedback can be virtual.
  • -
-

4. Who executes?

-
    -
  • Individuals, teams, or companies from anywhere can submit a proposal that aligns with the strategy (or doesn’t), a budget for what they want to do, and their success criteria on a scale of 1-10 (see below).
  • -
  • Executing Entities can submit plans that may take longer than 6 months to complete as the reality of hiring and funding employees may dictate longer term financing commitment. The Strategic Committee should have discretion to allow for these sorts of investments but should require intermediate milestones and grading on the 6-month time horizon as well.
  • -
  • Companies that have sustainable business models and can support or subsidize engineers to work on Zcash or that have adjacent businesses that would benefit from investment in this technology should be encouraged to participate, i.e. the way Square is supporting Bitcoin we should have companies supporting Zcash.
  • -
  • Ideally the board also encourages non-technical execution such as education, video series, regulatory progress, etc.
  • -
-

5. How are they held accountable to excellent execution?

-
    -
  • At the end of six months all proposals are graded 1-10. Each team would pre-agree to what would would result in a 0, 3, 7, 10/10 and then they can move it up or down a little once results are due in 6 months. If they pre-agreed to some definition of results that is a 3 and then tried to give themselves an 8, it would look fishy and could impact future funding.
  • -
  • The Strategic Council should target an average score of 7/10 for that six months across all Executors. If we score too high, we are not being ambitious enough in our goals. If we score too low, we were trying to do too much or had a fundamental misunderstanding of our goals.
  • -
  • Over time the Strategic Council decides who gets funds so under-performers will be culled. Thus Executors are held accountable by the board and the board is held accountable by the community.
  • -
-
-

Issues & Further Discussion

-

Raised objections, issues, and open questions:

-
    -
  • How might we create a process to amending this process? We may want 4/5 of the Strategic Council to approve changes or 2/3 of ZEC holders to be able to amend the Strategic Council’s charter.
  • -
  • How do we recall or impeach the members of the Strategic Committee prior to the end of their term if necessary?
  • -
  • I’m sure there are many other points of ambiguity and improvements we could make. There may even be critical design flaws or failures in this system. Feedback is appreciated.
  • -
-
-

References / Background

- -

these should be made into inline references.

-
-

Change Log

-
    -
  • 2019-08-27 Initial draft - thanks to @jubos, @puntium, @zooko, @joshs, and Jack Gavigan for helping me more clearly articulating my ideas and helping get them formatted properly for a ZIP. These ideas are solely mine and were not influenced by any of these individuals.
  • -
  • 2019-08-28 Updated to be in ZIP format.
  • -
  • 2019-09-15 Finally turned in to a pull request on GitHub and incorporated feedback from @daira and @str4d.
  • -
-
-
- - \ No newline at end of file diff --git a/rendered/zip-1010.html b/rendered/zip-1010.html deleted file mode 100644 index 222d6b127..000000000 --- a/rendered/zip-1010.html +++ /dev/null @@ -1,201 +0,0 @@ - - - - ZIP 1010: Compromise Dev Fund Proposal With Diverse Funding Streams - - - -
-
ZIP: 1010
-Title: Compromise Dev Fund Proposal With Diverse Funding Streams
-Owners: Josh Cincinnati <josh@zfnd.org>
-Credits: Matt Luongo
-         Eran Tromer
-         Andrew Miller
-         mistfpga
-         lex-node
-         and many others
-Status: Obsolete
-Category: Consensus Process
-Created: 2019-08-31
-License: MIT
-Discussions-To: <https://forum.zcashcommunity.com/t/a-grand-compromise-synthesis-zip-proposal/34812>
-

Terminology

-

The key words "MUST", "MUST NOT", "SHOULD", and "SHOULD NOT" 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

-
-

Abstract

-

I try to put the best pieces of various proposals together. A 20% of the block reward for a 4-year development fund that disburses to a trust controlled by both the Electric Coin Company (ECC) and Zcash Foundation (ZF), but with stringent controls on how funds may be allocated. It sidesteps code complexity in implementation by off-loading disbursements to a legal trust; funds the ECC/ZF; ECC stays a for-profit with restrictions; funds external parties through ZF Grants; all while carving out a limited-scoped opportunity for extending governance to more groups than the ECC/ZF.

-
-

Motivation and Requirements

-

Zcash won't thrive without a dev fund. I wish this wasn't true (I really do), and for the longest time I was against the idea. But I've come to fear the alternative without one; I fear the privacy technology pioneered by Zcash may never reach its true potential — not just for our community, but for others interested in novel approaches to private money.

-

The Foundation, ECC, and broader community has offered many suggestions and guidelines for a potential dev fund, below is my attempt at synthesizing them into a compromise that's greater than the sum of its parts:

-
    -
  • The ECC and Zcash Foundation shouldn't get a blank check; accountability is a prerequisite for any disbursement, based on the Foundation's statement 3 and other proposals being suggested.
  • -
  • It's possible for the ECC to remain a for-profit, but with (legally enforced) restrictions that ensure accountability and add teeth to their claim that no early investors are enriched by a new dev fund / no new investors are beneficiaries.
  • -
  • A nontrivial portion of the funds should be directed to users/organisations outside of the ECC/Zcash Foundation, and the ECC/Zcash Foundation should be in the minority in deciding how these funds are disbursed (e.g. through some process with broader input beyond ECC/Zcash Foundation employees, like a more constrained version of Placeholder or Blocktower's "third party" proposals).
  • -
  • The actual code changes for the NU4 network upgrade should be minimal and the "governance complexity" should be offloaded to legal agreements, not engineering hours. The dev fund would be deposited into a single address for the fund (ideally shielded with a viewing key) controlled through a trust (originally Andrew Miller’s idea), disbursed quarterly based on the accountability requirements and shielded adoption metrics described below. Trustees will be mutually agreed upon by the ECC and Zcash Foundation, and the Zcash Foundation will bear the cost of operating the trust.
  • -
  • The gross amount of the dev fund should still be 20% of the block reward, and it should end in 4 years. (Unless we go through another process like this one to extend it, though I personally hope we don’t.)
  • -
-

for security reasons, it may be useful to refine the "single address" to a list of rolling addresses as described in section 7.8 of the current protocol specification. Other references to a "single address" in this document have not been changed.

-

Please note: a previous version of this proposal included a portion of the funds being tied to shielded adoption, based on ideas brought forward by Eran Tromer in 4. After many discussions I came to worry about the gameability of the metric and decided to drop it entirely.

-
-

Specification

-

Upon the NU4 network activation, 20% of the mining reward (post-Blossom / post-halvening = 0.625 ZEC per block) MUST go to a single shielded address with a viewing key widely distributed and known to the community and controlled by a trust established by the ECC and Zcash Foundation. If the trust and associated address aren't established by the NU4 activation deadline, then there MUST NOT be any change to the mining reward. Every quarter-year (105,000 blocks at the post-Blossom rate), until 4 years after NU4 activation (1,680,000 blocks at the post-Blossom rate), the trust SHOULD disburse funds the following way, requiring a public report with every disbursement:

-
    -
  • 30% of the fund to the ECC, if they meet the accountability requirements set by the trust/described below;
  • -
  • 30% of the fund to the Zcash Foundation, if they meet the accountability requirements set by the trust/described below;
  • -
  • 40% of the fund to the Zcash Foundation as a RESTRICTED donation 5 purely for disbursement through ZF Grants 6, with additional restrictions and stipulations described below.
  • -
-

When this proposal was written it was expected that NU4 activation would correspond exactly to the first (October 2020) halvening. Since that may not be the case, I have resolved a potential ambiguity in the original wording by specifying that the trust disburses funds for 4 years, rather than that it disburses funds until the second (October 2024) halvening.

-

Example disbursements by the trust for a hypothetical 105000-block period

-

0.625 ZEC * 105000 = 65625 ZEC accrued in the trust every quarter. If both the ECC and Zcash Foundation met the accountability requirements set by the trust, then disbursements would look like this:

-
    -
  • 19687.5 ZEC to the ECC for meeting accountability requirements.
  • -
  • 19687.5 ZEC to the Zcash Foundation for meeting accountability requirements.
  • -
  • 26250 ZEC to ZF Grants to be disbursed to external individuals and organizations (via the Zcash Foundation as a restricted donation, but determined by an independent body to both organizations).
  • -
-

This example assumes no change to target block spacing.

-
-

The trust's accountability requirements

-

Here I'm borrowing from the Foundation's guidance 3 but adding some stipulations to cement the Foundation's independence, prevent the Foundation from hoarding its endowment, and handle the ECC as a for-profit. Before disbursing funds each quarter, the trust MUST validate that both the ECC and Zcash Foundation:

-
    -
  • Published quarterly technical roadmap reports and financial reports, detailing spending levels/burn rate and cash/ZEC on hand;
  • -
  • (if the first disbursement in a calendar year) Published a yearly review of organization performance, along the lines of the Zcash Foundation's "State of the Foundation" report 7.
  • -
-

For the Zcash Foundation, the trust MUST further require:

-
    -
  • No board member may have an interest in the ECC (current board members with an interest would need to divest of their ECC holdings prior to the beginning of this dev fund or leave the board);
  • -
  • Excluding money restricted for ZF Grants, the Foundation's total assets MUST stay below $100mm (if its assets ever exceeded this amount from a disbursement, the trust could direct the funds toward an additional restricted ZF Grants donation).
  • -
-

Additionally, for the ECC, the trust MUST validate the following before each disbursement:

-
    -
  • (if the first disbursement in a fiscal year) The ECC published yearly audited financial statements at the same level of detail as a public company (to mirror the Foundation's Form 990 requirement as 501(c)(3));
  • -
  • No outside investment was received while they are obligatory recipients of this dev fund;
  • -
  • No portion of the dev fund went to dividends, profit-sharing, or share/equity buybacks while they are obligatory recipients of this dev fund;
  • -
  • No dilution of ECC's equity except in the case of options/RSUs for new/existing employees while they are obligatory recipients of this dev fund;
  • -
  • There's no change-of-control (majority control changes) at the ECC while they are obligatory recipients of this dev fund;
  • -
-

The ECC MUST share necessary information with the trust to ascertain no violations of the above, but the information itself (i.e. cap table and detailed financials) SHOULD remain private between the ECC and the trustees unless there is a violation that is not cured.

-
-

What happens in the case of a violation

-

The violating party has 30 days to attempt to cure the violation (if it's possible). If they cannot, future funds MUST be redirected to ZF Grants via a restricted donation to the Zcash Foundation. (That is, not usable by either the Zcash Foundation or ECC, more on that below.)

-
-

The ZF Grants portion

-

A portion of the dev fund goes to the Foundation but with the express (and restricted) purpose of being distributed via ZF Grants (a restriction that MUST be legally enforced by the trust). The Foundation would continue to administer ZF Grants and distribute funds, but it SHOULD NOT decide where those funds go and would not allowed to be recipients of these funds; instead, the trust MUST demand that the ZF Grants process include broader input in the manner described below. In the discussions around the various "third party" proposals, some have suggested a 3-of-5 approach where the ECC and Zcash Foundation are in the minority; I think that structure would work well for these funds. It's not the full dev fund so we are limiting the downside risk of selecting the "wrong" third parties, which also means we can give those third parties more voice (by making them outnumber the ECC/Zcash Foundation). The Foundation MAY also chose to fund ZF Grants beyond the restricted donations from the trust, but doing so would be at their discretion.

-

Thanks to the discussion on Matt Luongo's proposal there's a good blueprint for how this group would work. I'm borrowing some comments I made on Matt's proposal thread 8 and modifying them to apply to a ZF Grants-specific Grant Review Committee, rather than the Foundation's board.

-

The ZF Grant Review Committee would be compromised of five members, voted on in the following manner:

-
    -
  • 1 seat for the ECC. Though the appointed member may change, they retain power to choose the seat for 4 years.
  • -
  • 1 seat for the Zcash Foundation. Though the appointed member may change, they retain power to choose the seat for 4 years.
  • -
  • 2 seats voted on by ZEC holders directly, elected every year. There would be open elections held by the Foundation similar to the 2018 advisory process which resulted in Ian and Amber’s election, except using a ZEC coin-staked vote directly.
  • -
  • 1 seat held by a technical member, elected every year. This member would be selected by the combined group (2 coin-staked seats + ZF seat + ECC seat) with an express focus on ability to evaluate technical proposals.
  • -
-

The group would meet biweekly to make funding decisions, the results of which will be made public on ZF Grants. Taking a note from Eran Tromer's recent proposal, the group would have a goal of making at least two "Large Grants" every year. A "Large Grant" would have an expected scope of six months and 1/4th to 1/3rd of the total ZF Grants yearly budget, with the goal of getting more dedicated external teams involved.

-
-
-

Rationale

-

There are scores of great ideas on the forums, and I took the (subjective, mind you) best parts of each into a proposal that hopefully meets the standards of the ECC, the Zcash Foundation, and the broader community.

-

A word on the enigmatic "third party" floating around

-

With all due respect to the proposers behind some variant of a "2-of-3 multisig" decision-making process for all disbursement decisions: I think this is a bad idea. To quote a previous forum post of mine:

-
-

...2-of-3 multisig [is] better if we find the right third party. That in and of itself requires an additional process/mutual agreement between the three parties (which is much more difficult than a bilateral agreement), and as I’ve mentioned before in presentations in the past, 2-of-2 with known entities dedicated to Zcash is better than jumping straight to 2-of-3 with a third party hastily decided or staying with 1-of-1 entity trademarks and software development processes.

-

As for why 2-of-2 is still strictly better than 1-of-1: in the case of cryptocurrency governance, I believe that inaction in the case of disagreement is a better outcome than one party unilaterally exercising power.

-
-

More to the point, I worry that the "third party" in question is being idolized into some Platonic ideal, and in reality either the ECC or the Zcash Foundation would spend a great deal of their time currying favor in either the process or selection of the party in question in the limited time between now and that party's selection. Given that the Zcash Foundation is charged with representing community interests, I'm not sure why another community-focused representative would really make sense from the ECC's perspective — they'd be constantly outvoted if interests clashed, so from a balance of power perspective I'm not sure why the ECC would find that tenable. And I'm not sure the community would want the "third party" to be another profit-generating enterprise, like a VC or another startup, which would tip power another way.

-

The crux of this proposal still centers around the idea that the Zcash Foundation and ECC share responsibility for protocol development, which is now bolstered by the 2-of-2 agreement on the trademark. It assumes and expects that both continue developing consensus-compatible node software that interacts with the Zcash network. But it mandates accountability for disbursement of funds to the ECC/Zcash Foundation, and expands outside stakeholder input on funds that wouldn't be earmarked for the ECC/Zcash Foundation (similar to Placeholder's earlier version of their proposal and Matt Luongo's current proposal), while it doesn’t preclude the possibility of migrating to broader "2-of-3" later on future governance decisions.

-
-

Why a trust?

-

The main reason: reducing complexity creep in consensus code. Rather than try to incorporate some complex mechanism for dev fund disbursements on-chain, we can meet the NU4 with the simplest possible code-change and spend more time ironing out the details of the trust "off-chain." Since both the ECC and the Zcash Foundation are based in the US, using a trust with well-specified criteria for disbursements is a reasonable path. This also fits in nicely with lex-node's proposal 9 for legal covenants on funding.

-
-
-

Security and Privacy Considerations

-

The biggest issue is custody of the funds under the trust's control, but I suspect this can be managed with a partnership with a custody partner. There's also the issue that non-public information would need to be verified and validated by the trust, but I view this as a net positive for the community ("transparency for organizations, privacy for individuals").

-
-

Reference implementation

-

TBD, but it should be relatively simple to code in both zebra and zcashd.

-
-

Issues and further discussion

-
    -
  • What are the tax implications for setting up the trust?
  • -
  • Are the amounts reasonable? Should the dev fund be less than 20% in aggregate?
  • -
  • Should this or other proposals seek to change the ECC and Zcash Foundation's board/makeup, or should we keep those organizations running as they are and sandbox a new process to a specific disbursement of the dev fund? (This proposal assumes the latter via ZF Grants.)
  • -
-
-

References

- - - - - - - -
1Information 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"
- - - - - - - -
2ZIP 200: Network Upgrade Mechanism
- - - - - - - -
3Zcash Foundation Guidance on Dev Fund Proposals. Zcash Foundation blog, August 6, 2019.
- - - - - - - -
4Comment on a post “How to hire ECC” in the Zcash Community Forum. Eran Tromer, August 11, 2019.
- - - - - - - -
5“What Are Restricted Funds?” Foundation Group, last modified December 7, 2018.
- - - - - - - -
6ZF Grants — Funding for Zcash ecosystem projects
- - - - - - - -
7The State of the Zcash Foundation in 2019. Zcash Foundation blog, January 31, 2019.
- - - - - - - -
8Comment on a post “Decentralizing the Dev Fee” in the Zcash Community Forum. Josh Cincinnati, October 27, 2019.
- - - - - - - -
9ZIP 1007: Enforce Development Fund Commitments with a Legal Charter
-
-
- - \ No newline at end of file diff --git a/rendered/zip-1011.html b/rendered/zip-1011.html deleted file mode 100644 index e62e1debf..000000000 --- a/rendered/zip-1011.html +++ /dev/null @@ -1,178 +0,0 @@ - - - - ZIP 1011: Decentralize the Dev Fee - - - - -
-
ZIP: 1011
-Title: Decentralize the Dev Fee
-Owners: Matt Luongo <matt@thesis.co>
-Status: Obsolete
-Category: Consensus Process
-Created: 2019-09-27
-License: MIT
-Discussions-To: <https://forum.zcashcommunity.com/t/decentralizing-the-dev-fee/35252>
-Pull-Request: <https://github.com/zcash/zips/pull/278>
-

Abstract

-

This proposal describes a structure for Zcash governance, including funding and managing new Zcash development, decentralizing those development efforts, and resolving governance hangups between the Zcash Foundation and the Electric Coin Company.

-

These goals are accomplished via a 20% dev fee, enacted in NU4 and continuing for one halving period. This fee will fund a diverse group of development teams to ensure Zcash maintains best-in-class research and engineering talent while growing a robust ecosystem, funding the Zcash Foundation with 25% of the dev fee, and a newly established principal developer role with 35% of the dev fee.

-
-

Motivation

-

Who am I?

-

My name is Matt Luongo. I'm an entrepreneur who's been full-time in the crypto space since 2014, co-founding Fold, a Bitcoin payments company, and more recently Keep, a private computation startup built on Ethereum. At Keep, we've done some work around Zcash, and our parent company, Thesis, is considering investing more heavily in Zcash development for our latest project.

-

I'm deeply interested in privacy tech. For me, privacy is about consent –consent to share my habits, beliefs, and preferences– and I see privacy as the inevitable next frontier in our pursuit of an economy that respects individual choice.

-

My perspective is as the founder of a for-profit company focused on building self-sovereign technology who wants to develop on Zcash. We work in this space ideologically, but our work isn't free; attracting and growing talent requires funding.

-

If you're interested in more on my background, I've introduced myself more properly on the forum.

-
-

What's this about?

-

Since Zcon1, I've been looking to fund work to build an Ethereum / Zcash bridge. I've spoken to the ECC, the Zcash Foundation, and a number of early Zcash community members on how best to move forward with this project, and in the process I've learned a lot about how the community works and dev governance has been structured thus far.

-

Inevitably, I've become interested in the community's proposals for a new dev fee, and thought about how the right structure might support work like ours.

-

I believe the Zcash community has an opportunity to deploy a new incentive structure that will attract companies like ours to build and improve Zcash, leading to a more resilient network, stronger technology, and wider usage.

-
-

The Zcash narrative

-

We're all here to build a robust, private, decentralized currency. But in the dev fee proposals I've seen so far, the idea of a Zcash narrative that distinguishes it from the competition is absent.

-

Of the slew of ZIPs addressing Zcash's future, there's only been one strong narrative case — the idea that Zcash exists purely as a hedge against Bitcoin's long-term privacy failure. Put simply, Zcash is "Bitcoin, but private".

-

Zcash should aim higher. Bitcoin is the only coin that has successfully made a store of value argument, which I like to call "worse is better". Don't upgrade the network –the argument goes– stability is more important than solving today's problems. Bitcoin is chasing the Lindy effect, where worse is better, and the network becomes stronger every day it survives. That's great for Bitcoin. For the rest of us, though, better is better. Zcash should be better.

-

Zcash is known for having the best tech in the space, built by one of the best teams in the space. We should lean in to that reputation, nurturing the best research and engineering talent to take Zcash to the next level, and leveraging a Zcash dev fee as a differentiator to build the world's best private medium of exchange.

-
-

Principles of cryptocurrency governance

-

To understand Zcash governance, it's worth reviewing "default" cryptocurrency governance. Most proof-of-work chains today have three major governing roles:

-
    -
  1. Miners validate and secure the chain. They do some work to earn a reward. Miners are the first owners of newly minted coins, and are an integral part of network upgrades.
  2. -
  3. Users buy, hold, and spend the currency. In networks like Bitcoin, they also run full nodes, strengthening network resilience by decentralizing validation.
  4. -
  5. Developers maintain clients to power and interact with the network. They typically propose network upgrades.
  6. -
-

On a chain like Bitcoin, any of these roles can veto a network upgrade.

-
    -
  1. Miners can veto activating a new fork by refusing to build off blocks using new network rules, orphaning a minority effort. They can also attack any fork attempt that doesn't change
  2. -
  3. Users can veto a fork by refusing to update their full nodes, rejecting blocks as invalid — as demonstrated in the UASF movement successfully countering the SegWit2x attempt to force a Bitcoin hardfork. Users can also vote with their dollars, acting as a fork resolution of last resort via market pressure.
  4. -
  5. Developers can refuse to update client codebases to follow a fork. While this might not seem like a strong veto, in practice that means any fork will need at least one additional development team, or the agreement of existing client software developers.
  6. -
-

These roles together form a balance of power that makes contentious forks difficult — any change that a large swath of users disapproves of could split the chain.

-
-

The state of play

-

In Zcash, the addition of the Electric Coin Company (ECC) and the Zcash Foundation skew this balance.

-

Both organizations are comprised of Zcash founders, developers, researchers, and privacy proponents who have driven this ecosystem forward and represent its values. Nevertheless, their mode of operation today skews a healthy balance of power in Zcash governance.

-

The mechanisms of that skew are the Zcash trademark, held jointly by the Foundation and the ECC, and primary client software development, now split between the ECC and the Foundation.

-

In a disagreement between miners, users, and developers, the Foundation and ECC have the option of enforcing the Zcash trademark, effectively allowing them to choose a winning fork against the will of users, miners, and other developers.

-

In addition, the Foundation's sole maintenance of the zebrad client allows them to "soft veto" a network upgrade.

-

Unfortunately, the Foundation and the ECC aren't organized as arms-length entities today.

-

This situation poses a number of problems for new and existing Zcash users, as well as both entities.

-
    -
  • The threat of two entangled entities overriding (or being forced to override) the will of users undermines self-sovereignty.
  • -
  • The ECC and Foundation are both put at legal risk. As entangled entities, they're remarkably similar to a single entity when trying to minimize regulatory risk.
  • -
-
-

The "crowding out" problem

-

The Zcash ecosystem, as it exists today, leaves little incentive for outside developers to participate.

-

Zcash development has a high learning curve.

-
    -
  • The reference client is a fork of the Bitcoin reference implementation, building on a decade of poorly written legacy code.
  • -
  • What Zcash brings to the table involves a greater understanding of applied cryptography than most projects. SNARKs are often still referred to as "moon math", after all.
  • -
  • As the recent network-level attack demonstrates, full-stack privacy is hard.
  • -
-

Most outside developers need to see a clear path to longer-term funding before they can commit to the cost of that curve.

-

Even those developers who already have the expertise to work on this system are frustrated by the lack of longer-term funding. For evidence, look at Parity's exit from Zcash after zebrad development, or Summa's struggles to work on Zcash.

-

Sustainably attracting talent to Zcash is critical to maintain innovation and build resilience.

-
-
-

Requirements

-

The first requirement is a balanced governance structure. Developers should be rewarded, without rewarding governance capture. What's best for the chain and ZEC holders should always come before commercial interests.

-

The second, and secondary, requirement is funding Zcash development. While the chain shouldn't be run by a commercial entity, it will need to be supported by them.

-

The third requirement is the support of a more resilient ecosystem by:

-
    -
  1. Ending the "crowding out" problem by paying development teams to work on and for Zcash.
  2. -
  3. Building a dev fee management structure that's resilient to the loss, capture, or compromise of the Zcash Foundation.
  4. -
  5. Ensuring the ecosystem can survive the loss, capture, or compromise of the ECC by encouraging developer diversity and strategic input.
  6. -
-

Finally, avoid introducing unnecessary additional entities into the governance process.

-
-

Non-requirements

-

General on-chain governance is outside the scope of this proposal. On-chain governance is an exciting idea -- what if we had an impartial arbiter funding development? My experience with on-chain governance to date, however, leads me to believe it's still a risky direction. Zcash should focus on what it's good at –privacy– and leave proving on-chain governance models to other projects.

-

While this proposal attempts to outline a long-term structure for Zcash funding and governance, specifying the structure beyond the next 4 years is out of scope. Much will have changed in 4 years. Perhaps this structure will be sufficient; perhaps we'll be battling the Third Crypto War, and need to go back to the drawing table.

-
-

Specification

-

The below proposal is an effort to cleanly resolve the problems with Zcash's current governance, while

-
    -
  • maintaining a balance of power between stakeholders;
  • -
  • removing single points of failure / control;
  • -
  • growing development and usage of Zcash;
  • -
  • and supporting the best interests of miners, users, and developers today.
  • -
-

Decentralizing development

-

A few proposals have suggested the introduction of a mysterious "third entity" to resolve disagreements between the Foundation and the ECC.

-

I prefer a different approach, refocusing the role of the Foundation and making room for the ECC to work with a robust developer ecosystem.

-

In this proposal, the Foundation shall support community development through running the forum and events, gathering community sentiment, managing short-term development grants, research and development, and conducting the diligence behind the assignment and disbursement of a development fee. This development fee shall be funded by 20% of the block reward, with as much as half of the fee burned in case of extraordinary growth in the price of ZEC.

-

The Foundation shall receive 25% of the dev fee. If the volume-weighted average price of ZEC over the month means the foundation would receive greater than $500k that month, the Foundation shall set aside enough ZEC such that their max monthly budget is

-
\(\mathsf{MaxBenefit}(\mathsf{RewardDollarAmount}) = \mathsf{min}\left(500000, 500000 * \sqrt{\frac{\mathsf{RewardDollarAmount}}{500000}}\right)\)
-

The excess ZEC should be purpose-restricted to the Foundation grants program, ensuring the funds are earmarked to grow outside community talent and involvement.

-

Capping the monthly expenses of the Foundation will limit growth, while encouraging fiscal discipline.

-

The remaining 75% of the dev fee shall be distributed between development teams working to maintain clients.

-
    -
  • Up to 35% of the total fee shall be reserved for the role of the "principal developer", a developer with assured long-term alignment with the project.
  • -
  • The remaining 40% of the fee, called the "outside development fee", shall be distributed between at least two development teams, chosen semi-annually by the Foundation, coinciding with network upgrades.
  • -
-

Prior to each network upgrade, the Foundation shall recommend a list of addresses and a total number of ZEC per block each address is meant to receive from the dev fee. The recommendation will be "ratified" by the miners as the network upgrade activates.

-
-

The role of dev fee recipients

-

Dev fee recipients are distinguished from grant recipients in the scope and timelines of their work, as well as the specificity of direction. The intent is to allow teams to focus on a core competency, while encouraging research and adjacent work.

-

Dev fee recipients are chosen semi-annually by the Foundation based on their ability to move Zcash forward. Recipients will typically be development teams, though "full stack" teams that can communicate well with the community, expand Zcash usage, and widely share their work should be advantaged.

-

Recipients shall submit quarterly plans to the community for their efforts, as well as monthly progress updates.

-

All work funded by the dev fee will be open source, under licenses compatible with the existing Zcash clients.

-

Though the Foundation shall periodically judge the efficacy of dev fee recipients, deciding on and driving roadmaps for Zcash is the role of dev fee recipients, in partnership with the community. This role is neatly balanced by users running full nodes and miners, either of which can veto a network upgrade.

-

While dev fee recipients are not required to work exclusively on Zcash, considering the nature of their work, recipients must guarantee they aren't obliged to the interests of competing projects.

-
-

The role of the principal developer

-

The role of the principal developer is as a "first among equals" amongst the dev fee recipients.

-

The principal developer shall make a number of guarantees.

-
    -
  1. Zcash shall be their exclusive focus, submitting financials periodically to the Foundation as assurance.
  2. -
  3. They shall maintain a well-run board and employ a qualified CFO.
  4. -
  5. In addition to the existing open-source requirements, they shall agree to assign any patents relevant to Zcash to the Foundation.
  6. -
-

In exchange, the principal developer is granted an indefinite minimum dev fee allocation of 20%, with a maximum allocation of 35% of the total fee, as recommended annually by the Foundation.

-

The principal developer will have a wide remit to pursue longer-term research relevant to Zcash, though it will submit the same plans required of other recipients. The principal developer will only be recommended for removal by the Foundation in extraordinary circumstances, including reneging on the above guarantees or extreme negligence.

-
-

Minimum viable Foundation

-

To manage the dev fee and fulfill its community and diligence duties, the Foundation shall maintain a board of 5 independent members. Rather than the structure in the current bylaws, the board will consist of

-
    -
  • 1 seat voted on periodically by ZEC holders directly.
  • -
  • 1 seat representing a newly created research advisory board, whose primary role will be technical diligence of potential recipients of the dev fee.
  • -
  • 1 seat for a member of the investment community.
  • -
  • 2 seats elected by the board, as the board is currently selected according to the bylaws. The board's discretion here means these could be selected via a community election, or via the remaining 3 seats' direct vote.
  • -
-

The Foundation requires a professional board. Board member selection should heavily favor candidates with existing formal public or private sector board experience.

-

Board seats should rotate periodically, while maintaining long enough terms and overlap for consistent governance.

-

Each board member should bring a unique network and set of skills to bear to increase the impact of the Foundation.

-

No board members shall have an ongoing commercial interest in any recipients of the dev fee.

-

Considering their expertise, the Foundation shall deliver a transition plan, including a board election schedule and report on the feasibility of a future coin vote process to determine a board seat.

-
-

The ECC as the principal developer

-

I propose that the ECC be considered as the initial principal developer, receiving an indefinite dev fee allocation in exchange for their exclusive focus on Zcash research and development, and assigning all patents and marks relevant to Zcash to the Foundation.

-

I believe this arrangement is best for the Zcash ecosystem, and with proper management of funds, should satisfy the ongoing needs of the ECC.

-
-

The dev call

-

The Foundation shall organize a bi-weekly call for all dev fee recipients and other third party developers. The call will be live-streamed for community participation, though the speaking participants will be invite only. At a minimum, a single representative from each dev fee recipient should attend.

-

The Foundation shall also maintain a simple chat solution for development of the protocol. While the chat logs should be publicly viewable, it need not be open to public participation.

-
-

Moving forward

-

I believe this proposal can form the basis for a new way forward for Zcash — a robust, decentralized ecosystem with fair governance. I also hope it can bring together the stakeholders in this discussion, and allow us to get back to why we're all here — to protect the world's financial privacy.

-

I look forward to feedback on GitHub and the Zcash forum.

-
-
-

Disclosures

-

In the interest of transparency, I'd like to make a few professional disclosures.

-

I'm the largest shareholder of Thesis, the parent company and studio behind Fold and Keep. Thesis is a for-profit company that might benefit from this proposal as a dev fee recipient. While today I maintain exclusive control of Thesis, the company has taken outside investment in the past.

-

As far as my financial interest in Zcash, I've held a small amount of ZEC since shortly after launch. I'm in the process of building my personal ZEC position, as well as a position at Thesis.

-
-

Acknowledgements

-

Thanks to my friends and colleagues Carolyn, Laura, Josh, James, Corbin, and Antonio for early review of the text this proposal.

-

Thanks to my fellow dev fund ZIP authors, Avichal Garg at Electric Capital, Antoinette Marie, Josh Cincinnati, ED at the Zcash Foundation, Jacob Phillips at Autonomous Partners, Andrew Miller, Chris Burniske, Eran Tromer, and the fellows at Blocktown, each of whose ideas influenced this proposal. And of course, thanks to Sonya Mann and the Foundation for coordinating discussions around these different proposals.

-

Outside ongoing discussions in the forum and with other ZIP authors, I've spoken with a number of prominent community members while developing this proposal, though none were provided early access to the text of the proposal. I appreciated the thoughtful discussions with Josh Cincinnati, Zooko Wilcox, Josh Swihart, Ian Miers, and others.

-
-
- - \ No newline at end of file diff --git a/rendered/zip-1012.html b/rendered/zip-1012.html deleted file mode 100644 index 638ca48f7..000000000 --- a/rendered/zip-1012.html +++ /dev/null @@ -1,169 +0,0 @@ - - - - ZIP 1012: Dev Fund to ECC + ZF + Major Grants - - - -
-
ZIP: 1012
-Title: Dev Fund to ECC + ZF + Major Grants
-Owners: Eran Tromer <eran@tromer.org>
-Status: Obsolete
-Category: Consensus Process
-Created: 2019-11-10
-License: MIT
-Discussions-To: <https://forum.zcashcommunity.com/t/dev-fund-proposal-dev-fund-to-ecc-zfnd-major-grants/35364>
-Pull-Request: <https://github.com/zcash/zips/pull/291>
-

Abstract

-

This proposal describes a structure for a the Zcash Development Fund, to be enacted in Network Upgrade 4 and last for 4 years. This Dev Fund would consist of 20% of the block rewards, split into 3 slices:

-
    -
  • 35% for the Electric Coin Company;
  • -
  • 25% for Zcash Foundation (for internal work and grants);
  • -
  • 40% for additional "Major Grants" for large-scale long-term projects (decided by the Zcash Foundation, with extra community input and scrutiny).
  • -
-

Funding is capped at $700k/month per slice. Governance and accountability are based on existing entities and legal mechanisms, and increasingly decentralized governance is encouraged.

-
-

Motivation

-

Starting at Zcash's first halving in October 2020, by default 100% of the block rewards will be allocated to miners, and no further funds will be automatically allocated to research, development and outreach. Consequently, no substantial new funding may be available to existing teams dedicated to Zcash: the Electric Coin Company (ECC), the Zcash Foundation (ZF), and the many entities funded by the ZF grant program.

-

There is a need to strike a balance between incentivizing the security of the consensus protocol (i.e., mining) versus other crucial aspects of the Zcash security and functionality, such as development and outreach.

-

Furthermore, there is a need to balance the sustenance of ongoing work by the current teams dedicated to Zcash, with encouraging decentralization and growth of independent development teams.

-

Difference from Matt Luongo's proposal

-

This proposal is based on Matt Luongo's Decentralizing the Dev Fee proposal, which has similar motivations. The major changes are as follows:

-
    -
  • The Dev Fund slice intended for external recipients (beyond ECC, ZF and existing ZF grants) may be used to fund ECC if no competitive alternatives present themselves, to mitigate unwarranted loss of existing capabilities.
  • -
  • For simplicity, the above slice is combined with the Foundation's existing grant system; but is accompanied by explicit requirements to achieve its goals, independent advisory input, and a Restricted Funds mechanism to enforce these requirements.
  • -
  • The "easing function" coin value cap is removed, in favor of capping each slice at $700k/month funding target. Any excess is kept in a reserve, from which it can be withdrawn only to maintain the funding target in the future.
  • -
  • Strengthened the transparency and accountability requirements, and harmonized them across ECC, ZF and major grantees.
  • -
  • Removed ZF's supervisory role in determining the "principal developer", fixing it to be ECC (changing this would be sufficiently dramatic to merit a fork).
  • -
  • Small differences in prescribed changes to the ZF board.
  • -
  • Call for, and incentivize, development of decentralized voting and governance.
  • -
  • Clarity and brevity.
  • -
-
-
-

Requirements

-

The Dev Fund should encourage decentralization of the work and funding, by supporting new teams dedicated to Zcash.

-

The Dev Fund should maintain the existing teams and capabilities in the Zcash ecosystem, unless and until concrete opportunities arise to create even greater value for the Zcash ecosystem.

-

There should not be any single entity which is a single point of failure, i.e., whose capture or failure will effectively prevent effective use of the funds.

-

Major funding decisions should be based, to the extent feasible, on inputs from domain experts and pertinent stakeholders.

-

The Dev Fund mechanism should not modify the monetary emission curve (and in particular, should not irrevocably burn coins).

-

In case the value of ZEC jumps, the Dev Fund recipients should not be allowed to wastefully use excessive amounts of funds. Conversely, given market volatility and eventual halvings, it is desirable to create rainy-day reserves.

-

The Dev Fund mechanism should not reduce users' financial privacy or security. In particular, it should not cause them to expose their coin holdings, or to maintain access to secret keys for much longer than they would otherwise. (This rules out some forms of voting, and of disbursing coins to past/future miners).

-

The new Dev Fund system should be simple to understand and realistic to implement. In particular, it should not assume the creation of new mechanisms (e.g., election systems) or entities (for governance or development) for its execution; but it should strive to support and use these once they are built.

-

Comply with legal, regulatory and taxation constraints in pertinent jurisdictions.

-
-

Non-requirements

-

General on-chain governance is outside the scope of this proposal.

-

Rigorous voting mechanism (whether coin-weighted, holding-time-weighted or one-person-one-vote) are outside the scope of this proposal, though there is prescribed room for integrating them once available.

-
-

Specification

-

Dev Fund allocation

-

Starting at the first Zcash halving in 2020, until the second halving in 2024, 20% of the block rewards will be allocated to a "Dev Fund" that consists of the following three slices:

-
    -
  • 35% for the Electric Coin Company (denoted ECC slice);
  • -
  • 25% for the Zcash Foundation, for general use (denoted ZF-GU slice);
  • -
  • 40% for additional "Major Grants" for large-scale long-term projects (denoted ZF-MG slice).
  • -
-

Details below. The fund flow will be implemented at the consensus-rule layer, by sending the corresponding ZEC to the designated address in each block. This Dev Fund will end at the second halving (unless extended/modified by a future ZIP).

-

ECC slice (Electric Coin Company)

-

This slice of the Dev Fund will flow to ECC.

-

ECC must undertake a firm obligation to use the Dev Fund only in support of the Zcash cryptocurrency and its community.

-

In particular, ECC must commit to not distribute the Dev Fund proceeds to its partners ("shareholders"), other than:

-
    -
  1. In fair-market-value compensation for specific new work.
  2. -
  3. For covering pass-through tax obligations to partners caused by ECC's receipt of the Dev Fund.
  4. -
-

(ECC is encouraged to transition to a corporate structure that would avoid the latter taxes.)

-

This obligation must be made irrevocable, e.g., within ECC's corporate governance structure (i.e., its Operating Agreement) or contractual obligations.

-
-

ZF-GU slice (Zcash Foundation, for general use)

-

This slice of the Dev Fund will flow to ZF, to be used at its discretion for any purpose within its mandate to support Zcash and financial privacy, including: development, education, support community communication on-line and via events, gathering community sentiment, and external awarding grants for all of the above.

-

ZF may award grants as profit-sharing contracts, in which case any resulting profits will be added to the ZF-GU slice (to fund its ongoing operations and any future grants).

-
-

ZF-MG slice (Zcash Foundation, for major grants)

-

This slice of the Dev Fund is intended to fund independent teams entering the Zcash ecosystem, to perform major ongoing development (or other work) for the public good of Zcash ecosystem, to the extent that such teams are available and effective.

-

The funds will be received and administered by ZF. ZF will disburse them as "Major Grants", within the framework of ZF's grant program but subject to the following additional constraints:

-
    -
  1. These funds may be only be used to issue Major Grants to external parties that are independent of ZF. They may not be used by ZF for its internal operations and direct expenses.
  2. -
  3. Major Grants should support well-specified work proposed by the grantee, at reasonable market-rate costs. They can be of any duration, or ongoing without a duration limit, but have semiannual review points for continuation of funding.
  4. -
  5. Major Grants may be issued to ECC only if no other parties are available and capable of performing the specified work with similar effectiveness and cost. (The intent is that eventually ECC will not receive Major Grants.)
  6. -
  7. Priority will be given to Major Grants that bolster new teams with substantial (current or prospective) continual existence, and set them up for long-term success, subject to the usual grant award considerations (impact, ability, risks, team, cost-effectiveness, etc.). Priority will be given Major Grants that support ecosystem growth by mentorship, coaching, technical resources, creating entrepreneurial opportunities, etc.
  8. -
  9. Major Grants should specifically further the Zcash cryptocurrency and its ecosystem; this is more restrictive than ZF's general mission of furthering financial privacy.
  10. -
  11. Major Grants awarding is subject to individual approval by ZF's Board of Directors, by a majority excluding any members with a conflict of interest.
  12. -
  13. ZF shall seek advisory input on its choice of Major Grant awards, by all effective and reasonable means (e.g., on-line discussion forums, the community Advisory Board, on-chain voting by holders and miners, and proactive consultation with experts). The ZF Board of Directors shall strive to follow this advisory input (within the confines of the Foundation's charter and duties).
  14. -
  15. ZF shall strive to create an independent grant committee to evaluate and publicly recommend Major Grant proposals, based on the committee's expertise and the above inputs.
  16. -
-

ZF shall recognize the ZF-MG slice of the Dev Fund as a Restricted Fund donation under the above constraints (suitably formalized), and keep separate accounting of its balance and usage under its Transparency and Accountability obligations defined below.

-

From grant proposers' side, proposals for such grants will be submitted through ZF usual grant process, allowing for public discussion and public funding. It is intended that small one-time grants will be funded by drawing on the ZF-GU slice (where they also compete with other ZF activities), whereas large long-duration will be funded from the dedicated ZF-MG slice; though this is at ZF's discretion.

-

ZF shall strive to define target metrics and key performance indicators, and utilize these in its funding decisions.

-
Direct-grant option
-

It may be deemed better, operationally or legally, if the Major Grant funds are not accepted and disbursed by ZF, but rather directly assigned to the grantees. Thus, the following mechanism may be used in perpetuity, if agreed upon by both ECC and ZF before NU4 activation:

-

Prior to each Network Upgrade, the Foundation shall publish a list of grantees' addresses and the total number of Dev Fund ZEC per block they should receive. ECC and ZF shall implement this list in any implementations of the Zcash consensus rules they maintain. This decision will then be, effectively, ratified by the miners as the network upgrade activates.

-
-
-

Funding Target and Volatility Reserve

-

Each Dev Fund slice has a Funding Target, initially US $700,000 for each slice. At the end of each calendar month, the fair market value of the Dev Fund ZEC received during that month will be computed, and the excess over the Funding Target will be put into a dedicated Volatility Reserve account by the funds' recipient.

-

Funds may be withdrawn from the Volatility Reserve account only by that same party, in months where the aforementioned monthly ZEC value falls short of the Funding Target, and only to the extent needed to cover that shortfall.

-

The Volatility Reserve may be kept as ZEC, or sold and held as fiat currency or investments (whose profits will remain in the Volatility Reserve).

-

The Funding Target may be changed only by unanimous agreement of ZF, ECC and the majority vote of a voting mechanism weighted by ZEC coin holding. (This is meant to encourage the creation of such a voting mechanism. Moreover, in case of excessive accumulation of reserves, the community can condition an increase of the Funding Target on the redirection of some of the reserves to a different entity, miners or an airdrop).

-

Dev Fund ZEC that has been received, not placed in the Volatility Reserve, and has not yet been used or disbursed, will be kept by the corresponding party (as ZEC, or sold and invested) for later use under the terms of the corresponding slice.

-

Irrevocable obligations to the above must be made by the recipients (e.g., using their Operating Agreements or by receiving the slice as Restricted Funds).

-
-
-

Transparency and Accountability

-

Obligations

-

ECC, ZF and Major Grant recipients (during and leading to their award period) shall all accept the following obligations:

-

Ongoing public reporting requirements:

-
    -
  • Quarterly reports, detailing future plans, execution on previous plans, and finances (balances, and spending broken down by major categories).
  • -
  • Monthly developer calls, or a brief report, on recent and forthcoming tasks. (Developer calls may be shared.)
  • -
  • Annual detailed review of the organization performance and future plans.
  • -
  • Annual audited financial report (IRS Form 990, or substantially similar information).
  • -
-

These reports may be either organization-wide, or restricted to the income, expenses and work associated with the receipt of Dev Fund.

-

It is expected that ECC, ZF and Major Grant recipient will be focused primarily (in their attention and resources) on Zcash. Thus, they must promptly disclose:

-
    -
  • Any major activity they perform (even if not supported by the Dev Fund) that is not in the interest of the general Zcash ecosystem.
  • -
  • Any conflict of interest with the general success of the Zcash ecosystem.
  • -
-

ECC, ZF and grant recipients must promptly disclose any security of privacy risks that may affect users of Zcash (by responsible disclosure under confidence to the pertinent developers, where applicable).

-

ECC's reports, and ZF's annual report on its non-grant operations, should be at least as detailed as grant proposals/reports submitted by other funded parties, and satisfy similar levels of public scrutiny.

-

All substantial software whose development was funded by the Dev Fund should be released under an Open Source license (as defined by the Open Source Initiative), preferably the MIT license.

-
-

Enforcement

-

For grant recipients, these conditions should be included in their contract with ZF, such that substantial violation, not promptly remedied, will cause forfeiture of their grant funds and their return to ZF.

-

ECC and ZF will contractually commit to each other to fulfill these conditions, and the prescribed use of funds, such that substantial violation, not promptly remedied, will permit the other party to issue a modified version of Zcash node software that removes the violating party's Dev Fund slice, and use the Zcash trademark for this modified version. The slice's funds will be reassigned to ZF-MG (whose integrity is legally protected by the Restricted Fund treatment).

-
-
-

Future Community Governance

-

Decentralized community governance is used in this proposal in the following places:

-
    -
  1. As advisory input to the ZF-MG slice (Zcash Foundation, for major grants).
  2. -
  3. For changing the Funding Target and Volatility Reserve (which is an incentive for ECC and ZF to create the voting mechanism).
  4. -
  5. In ZF's future board composition (see below).
  6. -
-

It is highly desirable to develop robust means of decentralized community voting and governance, and to integrate them into all of the above processes, by the end of 2021. ECC and ZF should place high priority on such development and its deployment, in their activities and grant selection.

-
-

ZF Board Composition

-

ZF should formally integrate robust means of decentralized community voting into its Board of Director elections, in a way that is consistent with ZF's mission and values. ZF should lead the process for determining and implementing this, legally and technically, by the end of 2021.

-

Members of ZF's Board of Directors must not hold equity in ECC or have current business or employment relationships with ECC.

-

Grace period: members of the board who hold ECC equity (but do not have other current relationships to ECC) may dispose of their equity, or quit the Board, by 1 March 2021. (The grace period is to allow for orderly replacement, and also to allow time for ECC corporate reorganization related to Dev Fund receipt, which may affect how disposition of equity would be executed.)

-
-
-

Disclosures

-

The author is

-
    -
  • a coauthor of the Zerocash academic paper underlying Zcash;
  • -
  • a technical adviser to the Zcash Foundation;
  • -
  • a founding scientist, a shareholder, and formerly a technical adviser to the Electric Coin Company;
  • -
  • an academic researcher and adviser to various other organizations.
  • -
-

This proposal is his private opinion and does not represent any of the above.

-
-

Acknowledgements

-

This proposed is most closely based on the Matt Luongo Decentralizing the Dev Fee proposal, with substantial changes and mixing in elements from @aristarchus's 20% split between the ECC and the Foundation proposal, Josh Cincinnati's A Grand Compromise/Synthesis ZIP Proposal proposal and extensive discussions in the Zcash Community Forum. The author is grateful to all of the above for their excellent ideas and many insightful discussions, and to Howard Loo and forum users @aristarchus and @dontbeevil for valuable initial comments on this proposal.

-
-
- - \ No newline at end of file diff --git a/rendered/zip-1013.html b/rendered/zip-1013.html deleted file mode 100644 index e37c01835..000000000 --- a/rendered/zip-1013.html +++ /dev/null @@ -1,82 +0,0 @@ - - - - ZIP 1013: Keep It Simple, Zcashers: 10% to ECC, 10% to ZF - - - -
-
ZIP: 1013
-Title: Keep It Simple, Zcashers: 10% to ECC, 10% to ZF
-Owners: Gordon Mohr (@gojomo on relevant forums)
-Status: Obsolete
-Category: Consensus Process
-Created: 2019-11-14
-License: Public Domain
-Discussions-To: <https://forum.zcashcommunity.com/t/zip-keep-it-simple-zcashers-kisz-10-to-ecc-10-to-zfnd/35425>
-Pull-Request: <https://github.com/zcash/zips/pull/293>
-

Terminology

-

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

-

The terms below are to be interpreted as follows:

-
-
ECC
-
Electric Coin Company, a US-based limited-liability corporation.
-
ZF
-
Zcash Foundation, a US-based non-profit corporation.
-
Halvening
-
a regularly-scheduled discontinuity where the rate of ZEC issuance halves, expected first in roughly October 2020 then next in roughly October 2024.
-
-
-

Abstract

-

This ZIP proposes:

-

After the 1st Zcash Halvening, when the "Founders’ Reward" system- bootstrapping protocol-based development funding expires, continue to direct 20% of new ZEC issuance to development-related activities for ongoing research, development, innovation, and maintenance of Zcash.

-

Assign half of such funds to the ECC, and half to the ZF. Continue this allocation until the 2nd Halvening.

-
-

Motivation

-

There have been many proposals for potential allocations of Zcash block rewards (ZEC inflation) after the 1st Halvening. Many cluster around similar broad parameters:

-
    -
  • 20% of block rewards for continuing development efforts;
  • -
  • provided to some combination of the Electric Coin Company (ECC), Zcash Foundation (ZF), and other named or to-be-determined entities;
  • -
  • conditioned on certain new allocation formulas or management practices, often involving novel entities, personnel, and feedback/deliberation processes.
  • -
-

However, no existing ZIPs explicitly propose the most simple variation on this theme - one that maintains maximal continuity with prior practice. This 'Keep It Simple, Zcashers' ZIP aims to fill that gap.

-
-

Requirements

-

This proposal intends to be easy to describe, understand, and implement.

-
-

Non-requirements

-

This proposal does not seek to propose any particular course of action past the 2nd Halvening.

-
-

Specification

-

To implement this ZIP, the Zcash protocol and compatible software MUST:

-
    -
  • maintain a 20% allotment of new ZEC issuance to development activities through to the 2nd Halvening event (expected around October 2024);
  • -
  • formalize a 50-50 relative allocation between the ECC and ZF;
  • -
  • deliver these ZEC to addresses provided by the recipients, in a manner analogous to the original "Founders’ Reward" consensus-encoded block rewards, or any other technically- and/or legally- preferred method agreed to by the ECC & ZF.
  • -
-

This proposal specifically refrains from adding any new conditions or procedural formalities, technical or legal, on the delivery of development funds.

-

There is only the expectation that these recipients SHOULD continue the stated missions, practices of transparency, and responsiveness to community input that they have demonstrated thus far.

-
-

Discussion

-

This proposal primarily differs from similar proposals in two ways: (1) it places no new comditions/processes on the disbursement of ZEC development funds; (2) it specifies a fixed, 50-50 division-of-funds between the ECC and ZF.

-

These differences are motivated by a desire for simplicity and continuity. This allocation can be implemented technically without novel institutions, processes, or legal agreements.

-

Rather than relying on lists-of-conditions with underspecified enforcement or dispute-resolution mechanisms, the adequate performance of fund recipients is expected due to:

-
    -
  • aligned incentives, especially the fact that the value of all funds received over 4 years depends completely on the continued health & growth of the Zcash ecosystem;
  • -
  • proven records of dedication to the Zcash project, and effective efforts on related projects, by receipient entities & personnel – even in the absence of formalized funding conditions.
  • -
-

From original "Founders’ Reward"-era development-funds, roughly 15% has been directed to the ZF. (Or, about 3 points of the full 20 points of bootstrap- funds.) However, from its later start, the ZF has recently grown its technical, grantmaking, and organizational capabilities, and wide sentiment in the Zcash community, ECC, and ZF desires the ZF grow to a role of equivalent or greater importance as the ECC for long-term Zcash evolution. Thus this proposal specifies a 50:50 split of future development funds, rather than continuing any prior proportions.

-
-

References

- - - - - - - -
1Information 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"
-
-
- - \ No newline at end of file diff --git a/rendered/zip-1014.html b/rendered/zip-1014.html deleted file mode 100644 index 570b3d49b..000000000 --- a/rendered/zip-1014.html +++ /dev/null @@ -1,255 +0,0 @@ - - - - ZIP 1014: Establishing a Dev Fund for ECC, ZF, and Major Grants - - - -
-
ZIP: 1014
-Title: Establishing a Dev Fund for ECC, ZF, and Major Grants
-Owners: Andrew Miller <socrates1024@gmail.com>
-        Zooko Wilcox <zooko@electriccoin.co>
-Original-Authors: Eran Tromer
-Credits: Matt Luongo
-         @aristarchus
-         @dontbeevil
-         Daira-Emma Hopwood
-         George Tankersley
-         Josh Cincinnati
-         Andrew Miller
-Status: Active
-Category: Consensus Process
-Created: 2019-11-10
-License: MIT
-Discussions-To: <https://forum.zcashcommunity.com/t/community-sentiment-polling-results-nu4-and-draft-zip-1014/35560>
-Pull-Request: <https://github.com/zcash/zips/pull/308>
-

Terminology

-

The key words "MUST", "MUST NOT", "SHALL", "SHALL 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 6 and the Zcash Trademark Donation and License Agreement (4 or successor agreement).

-

The terms "block subsidy" and "halving" in this document are to be interpreted as described in sections 3.10 and 7.8 of the Zcash Protocol Specification. 2

-

"Electric Coin Company", also called "ECC", refers to the Zerocoin Electric Coin Company, LLC.

-

"Bootstrap Project", also called "BP", refers to the 501(c)(3) nonprofit corporation of that name.

-

"Zcash Foundation", also called "ZF", refers to the 501(c)(3) nonprofit corporation of that name.

-

"Section 501(c)(3)" refers to that section of the U.S. Internal Revenue Code (Title 26 of the U.S. Code). 12

-

"Community Advisory Panel" refers to the panel of community members assembled by the Zcash Foundation and described at 11.

-

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

-
-

Abstract

-

This proposal describes a structure for the Zcash Development Fund, to be enacted in Network Upgrade 4 and last for 4 years. This Dev Fund would consist of 20% of the block subsidies, split into 3 slices:

-
    -
  • 35% for the Bootstrap Project (the parent of the Electric Coin Company);
  • -
  • 25% for Zcash Foundation (for internal work and grants);
  • -
  • 40% for additional "Major Grants" for large-scale long-term projects (administered by the Zcash Foundation, with extra community input and scrutiny).
  • -
-

Governance and accountability are based on existing entities and legal mechanisms, and increasingly decentralized governance is encouraged.

-
-

Motivation

-

Starting at Zcash's first halving in October 2020, by default 100% of the block subsidies will be allocated to miners, and no further funds will be automatically allocated to any other entities. Consequently, no substantial new funding may be available to existing teams dedicated to furthering charitable, educational, or scientific purposes, such as research, development, and outreach: the Electric Coin Company (ECC), the Zcash Foundation (ZF), and the many entities funded by the ZF grant program.

-

There is a need to strike a balance between incentivizing the security of the consensus protocol (i.e., mining) versus crucial charitable, educational, and/or scientific aspects, such as research, development and outreach.

-

Furthermore, there is a need to balance the sustenance of ongoing work by the current teams dedicated to Zcash, with encouraging decentralization and growth of independent development teams.

-

For these reasons, the Zcash Community desires to allocate and contribute a slice of the block subsidies otherwise allocated to miners as a donation to support charitable, educational, and scientific activities within the meaning of Section 501(c)(3).

-
-

Requirements

-

The Dev Fund should encourage decentralization of the work and funding, by supporting new teams dedicated to Zcash.

-

The Dev Fund should maintain the existing teams and capabilities in the Zcash ecosystem, unless and until concrete opportunities arise to create even greater value for the Zcash ecosystem.

-

There should not be any single entity which is a single point of failure, i.e., whose capture or failure will effectively prevent effective use of the funds.

-

Major funding decisions should be based, to the extent feasible, on inputs from domain experts and pertinent stakeholders.

-

The Dev Fund mechanism should not modify the monetary emission curve (and in particular, should not irrevocably burn coins).

-

In case the value of ZEC jumps, the Dev Fund recipients should not wastefully use excessive amounts of funds. Conversely, given market volatility and eventual halvings, it is desirable to create rainy-day reserves.

-

The Dev Fund mechanism should not reduce users' financial privacy or security. In particular, it should not cause them to expose their coin holdings, nor cause them to maintain access to secret keys for much longer than they would otherwise. (This rules out some forms of voting, and of disbursing coins to past/future miners.)

-

The new Dev Fund system should be simple to understand and realistic to implement. In particular, it should not assume the creation of new mechanisms (e.g., election systems) or entities (for governance or development) for its execution; but it should strive to support and use these once they are built.

-

Comply with legal, regulatory, and taxation constraints in pertinent jurisdictions.

-
-

Non-requirements

-

General on-chain governance is outside the scope of this proposal.

-

Rigorous voting mechanisms (whether coin-weighted, holding-time-weighted or one-person-one-vote) are outside the scope of this proposal, though there is prescribed room for integrating them once available.

-
-

Specification

-

Consensus changes implied by this specification are applicable to the Zcash Mainnet. Similar (but not necessarily identical) consensus changes SHOULD be applied to the Zcash Testnet for testing purposes.

-

Dev Fund allocation

-

Starting at the first Zcash halving in 2020, until the second halving in 2024, 20% of the block subsidy of each block SHALL be allocated to a "Dev Fund" that consists of the following three slices:

-
    -
  • 35% for the Bootstrap Project (denoted BP slice);
  • -
  • 25% for the Zcash Foundation, for general use (denoted ZF slice);
  • -
  • 40% for additional "Major Grants" for large-scale long-term projects (denoted MG slice).
  • -
-

The slices are described in more detail below. The fund flow will be implemented at the consensus-rule layer, by sending the corresponding ZEC to the designated address(es) for each block. This Dev Fund will end at the second halving (unless extended/modified by a future ZIP).

-

BP slice (Bootstrap Project)

-

This slice of the Dev Fund will flow as charitable contributions from the Zcash Community to the Bootstrap Project, the newly formed parent organization to the Electric Coin Company. The Bootstrap Project is organized for exempt educational, charitable, and scientific purposes in compliance with Section 501(c)(3), including but not limited to furthering education, information, resources, advocacy, support, community, and research relating to cryptocurrency and privacy, including Zcash. This slice will be used at the discretion of the Bootstrap Project for any purpose within its mandate to support financial privacy and the Zcash platform as permitted under Section 501(c)(3). The BP slice will be treated as a charitable contribution from the Community to support these educational, charitable, and scientific purposes.

-
-

ZF slice (Zcash Foundation's general use)

-

This slice of the Dev Fund will flow as charitable contributions from the Zcash Community to ZF, to be used at its discretion for any purpose within its mandate to support financial privacy and the Zcash platform, including: development, education, supporting community communication online and via events, gathering community sentiment, and awarding external grants for all of the above, subject to the requirements of Section 501(c)(3). The ZF slice will be treated as a charitable contribution from the Community to support these educational, charitable, and scientific purposes.

-
-

MG slice (Major Grants)

-

This slice of the Dev Fund is intended to fund independent teams entering the Zcash ecosystem, to perform major ongoing development (or other work) for the public good of the Zcash ecosystem, to the extent that such teams are available and effective.

-

The funds SHALL be received and administered by ZF. ZF MUST disburse them for "Major Grants" and expenses reasonably related to the administration of Major Grants, but subject to the following additional constraints:

-
    -
  1. These funds MUST only be used to issue Major Grants to external parties that are independent of ZF, and to pay for expenses reasonably related to the administration of Major Grants. They MUST NOT be used by ZF for its internal operations and direct expenses not related to administration of Major Grants. Additionally, BP, ECC, and ZF are ineligible to receive Major Grants.
  2. -
  3. Major Grants SHOULD support well-specified work proposed by the grantee, at reasonable market-rate costs. They can be of any duration or ongoing without a duration limit. Grants of indefinite duration SHOULD have semiannual review points for continuation of funding.
  4. -
  5. Priority SHOULD be given to Major Grants that bolster teams with substantial (current or prospective) continual existence, and set them up for long-term success, subject to the usual grant award considerations (impact, ability, risks, team, cost-effectiveness, etc.). Priority SHOULD be given to Major Grants that support ecosystem growth, for example through mentorship, coaching, technical resources, creating entrepreneurial opportunities, etc. If one proposal substantially duplicates another's plans, priority SHOULD be given to the originator of the plans.
  6. -
  7. Major Grants SHOULD be restricted to furthering the Zcash cryptocurrency and its ecosystem (which is more specific than furthering financial privacy in general) as permitted under Section 501(c)(3).
  8. -
  9. Major Grants awards are subject to approval by a five-seat Major Grant Review Committee. The Major Grant Review Committee SHALL be selected by the ZF's Community Advisory Panel or successor process.
  10. -
  11. The Major Grant Review Committee's funding decisions will be final, requiring no approval from the ZF Board, but are subject to veto if the Foundation judges them to violate U.S. law or the ZF's reporting requirements and other (current or future) obligations under U.S. IRS 501(c)(3).
  12. -
  13. Major Grant Review Committee members SHALL have a one-year term and MAY sit for reelection. The Major Grant Review Committee is subject to the same conflict of interest policy that governs the ZF Board of Directors (i.e. they MUST recuse themselves when voting on proposals where they have a financial interest). At most one person with association with the BP/ECC, and at most one person with association with the ZF, are allowed to sit on the Major Grant Review Committee. "Association" here means: having a financial interest, full-time employment, being an officer, being a director, or having an immediate family relationship with any of the above. The ZF SHALL continue to operate the Community Advisory Panel and SHOULD work toward making it more representative and independent (more on that below).
  14. -
  15. From 1st January 2022, a portion of the MG Slice shall be allocated to a Discretionary Budget, which may be disbursed for expenses reasonably related to the administration of Major Grants. The amount of funds allocated to the Discretionary Budget SHALL be decided by the ZF's Community Advisory Panel or successor process. Any disbursement of funds from the Discretionary Budget MUST be approved by the Major Grant Review Committee. Expenses related to the administration of Major Grants include, without limitation the following: -
      -
    • Paying third party vendors for services related to domain name registration, or the design, website hosting and administration of websites for the Major Grant Review Committee.
    • -
    • Paying independent consultants to develop requests for proposals that align with the Major Grants program.
    • -
    • Paying independent consultants for expert review of grant applications.
    • -
    • Paying for sales and marketing services to promote the Major Grants program.
    • -
    • Paying third party consultants to undertake activities that support the purpose of the Major Grants program.
    • -
    • Reimbursement to members of the Major Grant Review Committee for reasonable travel expenses, including transportation, hotel and meals allowance.
    • -
    -

    The Major Grant Review Committee's decisions relating to the allocation and disbursement of funds from the Discretionary Budget will be final, requiring no approval from the ZF Board, but are subject to veto if the Foundation judges them to violate U.S. law or the ZF's reporting requirements and other (current or future) obligations under U.S. IRS 501(c)(3).

    -
  16. -
-

ZF SHALL recognize the MG slice of the Dev Fund as a Restricted Fund donation under the above constraints (suitably formalized), and keep separate accounting of its balance and usage under its Transparency and Accountability obligations defined below.

-

ZF SHALL strive to define target metrics and key performance indicators, and the Major Grant Review Committee SHOULD utilize these in its funding decisions.

-
Direct-grant option
-

It may be deemed better, operationally or legally, if the Major Grant funds are not accepted and disbursed by ZF, but rather directly assigned to the grantees. Thus, the following mechanism MAY be used in perpetuity for some or all grantees, if agreed upon by both ECC and ZF before Network Upgrade 4 (Canopy) activation:

-

Prior to each network upgrade, the Foundation SHALL publish a list of grantees' addresses and the total number of Dev Fund ZEC per block they should receive. ECC and ZF SHALL implement this list in any implementations of the Zcash consensus rules they maintain. This decision will then be, effectively, ratified by the miners as the network upgrade activates.

-
-
-
-

Transparency and Accountability

-

Obligations

-

BP, ECC, ZF, and Major Grant recipients (during and leading to their award period) SHALL all accept the obligations in this section.

-

Ongoing public reporting requirements:

-
    -
  • Quarterly reports, detailing future plans, execution on previous plans, and finances (balances, and spending broken down by major categories).
  • -
  • Monthly developer calls, or a brief report, on recent and forthcoming tasks. (Developer calls may be shared.)
  • -
  • Annual detailed review of the organization performance and future plans.
  • -
  • Annual financial report (IRS Form 990, or substantially similar information).
  • -
-

These reports may be either organization-wide, or restricted to the income, expenses, and work associated with the receipt of Dev Fund. As BP is the parent organization of ECC it is expected they may publish joint reports.

-

It is expected that ECC, ZF, and Major Grant recipients will be focused primarily (in their attention and resources) on Zcash. Thus, they MUST promptly disclose:

-
    -
  • Any major activity they perform (even if not supported by the Dev Fund) that is not in the interest of the general Zcash ecosystem.
  • -
  • Any conflict of interest with the general success of the Zcash ecosystem.
  • -
-

BP, ECC, ZF, and grant recipients MUST promptly disclose any security or privacy risks that may affect users of Zcash (by responsible disclosure under confidence to the pertinent developers, where applicable).

-

BP's reports, ECC's reports, and ZF's annual report on its non-grant operations, SHOULD be at least as detailed as grant proposals/reports submitted by other funded parties, and satisfy similar levels of public scrutiny.

-

All substantial software whose development was funded by the Dev Fund SHOULD be released under an Open Source license (as defined by the Open Source Initiative 5), preferably the MIT license.

-
-

Enforcement

-

For grant recipients, these conditions SHOULD be included in their contract with ZF, such that substantial violation, not promptly remedied, will cause forfeiture of their grant funds and their return to ZF.

-

BP, ECC, and ZF MUST contractually commit to each other to fulfill these conditions, and the prescribed use of funds, such that substantial violation, not promptly remedied, will permit the other party to issue a modified version of Zcash node software that removes the violating party's Dev Fund slice, and use the Zcash trademark for this modified version. The slice's funds will be reassigned to MG (whose integrity is legally protected by the Restricted Fund treatment).

-
-
-

Future Community Governance

-

Decentralized community governance is used in this proposal via the Community Panel as input into the Major Grant Review Committee which governs the MG slice (Major Grants).

-

It is highly desirable to develop robust means of decentralized community voting and governance –either by expanding the Community Advisory Panel or a successor mechanism– and to integrate them into this process by the end of 2021. BP, ECC, and ZF SHOULD place high priority on such development and its deployment, in their activities and grant selection.

-
-

ZF Board Composition

-

Members of ZF's Board of Directors MUST NOT hold equity in ECC or have current business or employment relationships with ECC, except as provided for by the grace period described below.

-

Grace period: members of the ZF board who hold ECC equity (but do not have other current relationships to ECC) may dispose of their equity, or quit the Board, by 1 November 2021. (The grace period is to allow for orderly replacement, and also to allow time for ECC corporate reorganization related to Dev Fund receipt, which may affect how disposition of equity would be executed.)

-

The Zcash Foundation SHOULD endeavor to use the Community Advisory Panel (or successor mechanism) as advisory input for future board elections.

-
-
-

Acknowledgements

-

This proposal is a limited modification of Eran Tromer's ZIP 1012 10 by the Zcash Foundation, the ECC, further modified by feedback from the community and the results of the latest Helios poll.

-

Eran's proposal is most closely based on the Matt Luongo 'Decentralize the Dev Fee' proposal (ZIP 1011) 9. Relative to ZIP 1011 there are substantial changes and mixing in of elements from @aristarchus's '20% Split Evenly Between the ECC and the Zcash Foundation' (ZIP 1003) 7, Josh Cincinnati's 'Compromise Dev Fund Proposal With Diverse Funding Streams' (ZIP 1010) 8, and extensive discussions in the Zcash Community Forum.

-

The authors are grateful to all of the above for their excellent ideas and any insightful discussions, and to forum users @aristarchus and @dontbeevil for valuable initial comments on ZIP 1012.

-
-

References

- - - - - - - -
1Information 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"
- - - - - - - -
2Zcash Protocol Specification, Version 2021.2.16 or later
- - - - - - - -
3Zcash Protocol Specification, Version 2021.2.16. Section 3.12: Mainnet and Testnet
- - - - - - - -
4Zcash Trademark Donation and License Agreement
- - - - - - - -
5The Open Source Definition
- - - - - - - -
6ZIP 200: Network Upgrade Mechanism
- - - - - - - -
7ZIP 1003: 20% Split Evenly Between the ECC and the Zcash Foundation, and a Voting System Mandate
- - - - - - - -
8ZIP 1010: Compromise Dev Fund Proposal With Diverse Funding Streams
- - - - - - - -
9ZIP 1011: Decentralize the Dev Fee
- - - - - - - -
10ZIP 1012: Dev Fund to ECC + ZF + Major Grants
- - - - - - - -
11ZF Community Advisory Panel
- - - - - - - -
12U.S. Code, Title 26, Section 501(c)(3)
-
-
- - \ No newline at end of file diff --git a/rendered/zip-1015.html b/rendered/zip-1015.html deleted file mode 100644 index c5f3123b8..000000000 --- a/rendered/zip-1015.html +++ /dev/null @@ -1,224 +0,0 @@ - - - - ZIP 1015: Block Reward Allocation for Non-Direct Development Funding - - - -
-
ZIP: 1015
-Title: Block Reward Allocation for Non-Direct Development Funding
-Owners: Jason McGee <aquietinvestor@gmail.com>
-        @Peacemonger (Zcash Forum)
-        Kris Nuttycombe <kris@nutty.land>
-Credits: @GGuy (Zcash Forum)
-         Daira-Emma Hopwood
-         Jack Grigg
-         Skylar Saveland
-Status: Proposed
-Category: Consensus
-Created: 2024-08-26
-License: MIT
-Pull-Request: <https://github.com/zcash/zips/pull/881>
-

Terminology

-

The key words "MUST", "SHALL", "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.

-

"Zcash Community Advisory Panel", also called "ZCAP", refers to the panel of community members assembled by the Zcash Foundation and described at 5.

-

"Zcash Community Grants", also called "ZCG", refers to the committee selected by the Zcash Community Advisory Panel or a successor process (e.g. as established by FPF) to decide on the funding of grants intended to fund the Zcash ecosystem.

-

"Financial Privacy Foundation", also called "FPF", refers to the Cayman Islands-incorporated non-profit foundation company limited by guarantee of that name.

-

"Autonomous Entities" refers to committees, DAOs, teams or other groups to which FPF provides operations, administrative, and financial management support.

-
-

Abstract

-

This ZIP proposes the allocation of a percentage of the Zcash block subsidy, post-November 2024 halving, split between Zcash Community Grants (ZCG) and an in-protocol "lockbox." The "lockbox" is a separate pool of issued funds tracked by the protocol, as described in ZIP 2001: Lockbox Funding Streams 4. No disbursement mechanism is currently defined for this "lockbox"; the Zcash community will need to decide upon and specify a suitable decentralized mechanism for permitting withdrawals from this lockbox in a future ZIP in order to make these funds available for funding grants to ecosystem participants.

-

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.

-

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:

-
    -
  1. Regulatory Risks: The current model involves direct funding of US-based organizations, which can potentially attract regulatory scrutiny from entities such as the SEC, posing legal risks to the Zcash ecosystem.
  2. -
  3. Funding Inefficiencies: The current model directly funds organizations rather than specific projects, leading to a potential mismatch between those organizations' development priorities and the priorities of the community. Furthermore, if organizations are guaranteed funds regardless of performance, there is little incentive to achieve key performance indicators (KPIs) or align with community sentiment. A future system that allocates resources directly to projects rather than organizations may help reduce inefficiencies and better align development efforts with community priorities.
  4. -
  5. Centralization Concerns: The current model centralizes decision-making power within a few organizations, contradicting the decentralized ethos of blockchain technology. Traditional organizational structures with boards and executives introduce single points of failure and limit community involvement in funding decisions.
  6. -
  7. Community Involvement: The current system provides minimal formal input from the community regarding what projects should be funded, leading to a misalignment between funded projects and community priorities.
  8. -
  9. Moving Towards a Non-Direct Funding Model: There is strong community support for a non-direct Dev Fund funding model. Allocating funds to a Deferred Dev Fund Lockbox incentivizes the development of a decentralized mechanism for the disbursement of the locked funds.
  10. -
  11. Limited Runway: ZCG does not have the financial runway that ECC/BP and ZF have. As such, allocating ongoing funding to ZCG will help ensure the Zcash ecosystem has an active grants program.
  12. -
  13. Promoting Decentralization: Allocating a portion of the Dev Fund to Zcash Community Grants ensures small teams continue to receive funding to contribute to Zcash. Allowing the Dev Fund to expire, or putting 100% into a lockbox, would disproportionately impact grant recipients. This hybrid approach promotes decentralization and the growth of independent development teams.
  14. -
  15. Mitigating Regulatory Risks: The Financial Privacy Foundation (FPF) is a non-profit organization incorporated and based in the Cayman Islands. By minimizing direct funding of US-based organizations, this proposal helps to reduce potential regulatory scrutiny and legal risks.
  16. -
-

By addressing these issues, this proposal aims to ensure sustainable, efficient, and decentralized funding for essential activities within the Zcash ecosystem.

-
-

Requirements

-
    -
  1. In-Protocol Lockbox: The alternatives presented in this ZIP depend upon the Lockbox Funding Streams proposal 4.
  2. -
  3. Regulatory Considerations: The allocation of funds should minimize regulatory risks by avoiding direct funding of specific organizations. The design should enable and encourage compliance with applicable laws and regulations to support the long-term sustainability of the funding model.
  4. -
-
-

Non-requirements

-

The following considerations are explicitly deferred to future ZIPs and are not covered by this proposal:

-
    -
  1. Disbursement Mechanism: The exact method for disbursing the accumulated funds from the lockbox is not defined in this ZIP. The design, implementation, and governance of the disbursement mechanism will be addressed in a future ZIP. This includes specifics on how funds will be allocated, the voting or decision-making process, and the structure of the decentralized mechanism (such as a DAO).
  2. -
  3. Regulatory Compliance Details: The proposal outlines the potential to reduce regulatory risks by avoiding direct funding of US-based organizations, but it does not detail specific regulatory compliance strategies. Future ZIPs will need to address how the disbursement mechanism complies with applicable laws and regulations.
  4. -
  5. Impact Assessment: The long-term impact of reallocating a portion of the block subsidy to the lockbox on the Zcash ecosystem, including its effect on miners, developers, and the broader community, is not analyzed in this ZIP. Subsequent proposals will need to evaluate the outcomes and make necessary adjustments based on real-world feedback and data.
  6. -
-
-

Specification

-

Development Funding Recipients

-

Lockbox

-

The "lockbox" is a pool of issued funds tracked by the protocol, as described in ZIP 2001: Lockbox Funding Streams 4. No disbursement mechanism is currently defined for this "lockbox"; the Zcash community will need to decide upon and specify a suitable decentralized mechanism for permitting withdrawals from this lockbox in a future ZIP in order to make these funds available for funding grants to ecosystem participants.

-
-

Zcash Community Grants (ZCG)

-

The stream allocated to Zcash Community Grants (ZCG) is intended to fund independent teams entering the Zcash ecosystem, to perform major ongoing development (or other work) for the public good of the Zcash ecosystem, to the extent that such teams are available and effective. The ZCG Committee is given the discretion to allocate funds not only to major grants, but also to a diverse range of projects that advance the usability, security, privacy, and adoption of Zcash, including community programs, dedicated resources, and other projects of varying sizes.

-

The funds SHALL be received and administered by the Financial Privacy Foundation (FPF). FPF MUST disburse them for grants and expenses reasonably related to the administration of the ZCG program, but subject to the following additional constraints:

-
    -
  1. These funds MUST be used exclusively for issuing Zcash Community Grants to external parties that are independent of the FPF or to Autonomous Entities operating under the FPF umbrella. Additionally, they MAY be used to cover expenses reasonably related to the administration of Zcash Community Grants. These funds MUST NOT be used by FPF for its internal operations or for any direct expenses unrelated to the administration of Zcash Community Grants.
  2. -
  3. ZCG SHOULD support well-specified work proposed by the grantee, at reasonable market-rate costs. They can be of any duration or ongoing without a duration limit. Grants of indefinite duration SHOULD be reviewed periodically (on a schedule that the Zcash Community Grants Committee considers appropriate for the value and complexity of the grant) for continuation of funding.
  4. -
  5. Priority SHOULD be given to major grants that bolster teams with substantial (current or prospective) continual existence, and set them up for long-term success, subject to the usual grant award considerations (impact, ability, risks, team, cost-effectiveness, etc.). Priority SHOULD be given to major grants that support ecosystem growth, for example through mentorship, coaching, technical resources, creating entrepreneurial opportunities, etc. If one proposal substantially duplicates another’s plans, priority SHOULD be given to the originator of the plans.
  6. -
  7. The ZCG committee SHOULD be restricted to funding projects that further the Zcash cryptocurrency and its ecosystem (which is more specific than furthering financial privacy in general) as permitted by any relevant jurisdictional requirements.
  8. -
  9. ZCG awards are subject to approval by a five-seat ZCG Committee. The ZCG Committee SHALL be selected by the ZF’s Community Advisory Panel or a successor process (e.g. as established by FPF). Elections SHALL be staggered to ensure continuity within the Committee.
  10. -
  11. The ZCG Committee's funding decisions will be final, requiring no approval from the FPF Board, but are subject to veto if FPF judges them to violate Cayman law or the FPF's reporting requirements and other (current or future) obligations under the Cayman Islands' Companies Act (2023 Revision) and Foundation Companies Law, 2017.
  12. -
  13. ZCG Committee members SHALL have a one-year term and MAY sit for reelection. The ZCG Committee is subject to the same conflict of interest policy that governs the FPF Board of Directors (i.e. they MUST recuse themselves when voting on proposals where they have a financial interest). At most one person with association with the BP/ECC, at most one person with association with the ZF, and at most one person with association with FPF are allowed to sit on the ZCG Committee. “Association” here means: having a financial interest, full-time employment, being an officer, being a director, or having an immediate family relationship with any of the above.
  14. -
  15. A portion of the ZCG Slice shall be allocated to a Discretionary Budget, which may be disbursed for expenses reasonably related to the administration of the ZCG program. The amount of funds allocated to the Discretionary Budget SHALL be decided by the ZF’s Community Advisory Panel or successor process. Any disbursement of funds from the Discretionary Budget MUST be approved by the ZCG Committee. Expenses related to the administration of the ZCG program include, without limitation the following: -
      -
    • Paying for operational management and administration services that support the purpose of the Zcash Community Grants program, including administration services provided by FPF.
    • -
    • Paying third party vendors for services related to domain name registration, or the design, website hosting and administration of websites for the ZCG Committee.
    • -
    • Paying independent consultants to develop requests for proposals that align with the ZCG program.
    • -
    • Paying independent consultants for expert review of grant applications.
    • -
    • Paying for sales and marketing services to promote the ZCG program.
    • -
    • Paying third party consultants to undertake activities that support the purpose of the ZCG program.
    • -
    • Reimbursement to members of the ZCG Committee for reasonable travel expenses, including transportation, hotel and meals allowance.
    • -
    -
  16. -
  17. A portion of the Discretionary Budget MAY be allocated to provide reasonable compensation to members of the ZCG Committee. Committee member compensation SHALL be limited to the hours needed to successfully perform their positions and MUST align with the scope and responsibilities of their roles. The allocation and distribution of compensation to committee members SHALL be administered by the FPF. The compensation rate and hours for committee members SHALL be determined by the ZF’s Community Advisory Panel or successor process.
  18. -
  19. The ZCG Committee’s decisions relating to the allocation and disbursement of funds from the Discretionary Budget will be final, requiring no approval from the FPF Board, but are subject to veto if the FPF judges them to violate laws or FPF reporting requirements and other (current or future) obligations under Cayman Islands law.
  20. -
-

FPF SHALL be contractually required to recognize the ZCG slice of the Dev Fund as a Restricted Fund donation under the above constraints (suitably formalized), and keep separate accounting of its balance and usage under its Transparency and Accountability obligations defined below.

-

ZCG SHALL strive to define target metrics and key performance indicators, and the ZCG Committee SHOULD utilize these in its funding decisions.

-
Furthering Decentralization
-

FPF SHALL conduct periodic reviews of the organizational structure, performance, and effectiveness of the ZCG program and committee, taking into consideration the input and recommendations of the ZCG Committee. As part of these periodic reviews, FPF MUST commit to exploring the possibility of transitioning ZCG into an independent organization if it is economically viable and it aligns with the interests of the Zcash ecosystem and prevailing community sentiment.

-

In any transition toward independence, priority SHALL be given to maintaining or enhancing the decentralization of the Zcash ecosystem. The newly formed independent organization MUST ensure that decision-making processes remain community-driven, transparent, and responsive to the evolving needs of the Zcash community and ecosystem. In order to promote geographic decentralization, the new organization SHOULD keep its domicile outside of the United States.

-
-
Transparency and Accountability
-

FPF MUST accept the following obligations in this section on behalf of ZCG:

-
    -
  • Publication of a ZCG Dashboard, providing a snapshot of ZCG’s current financials and any disbursements made to grantees.
  • -
  • Bi-weekly meeting minutes documenting the decisions made by the ZCG committee on grants.
  • -
  • Quarterly reports, detailing future plans, execution on previous plans, and finances (balances, and spending broken down by major categories).
  • -
  • Annual detailed review of the organization performance and future plans.
  • -
  • Annual financial report (IRS Form 990, or substantially similar information).
  • -
-

BP, ECC, ZF, FPF, ZCG and grant recipients MUST promptly disclose any security or privacy risks that may affect users of Zcash (by responsible disclosure under confidence to the pertinent developers, where applicable).

-

All substantial software whose development was funded by the Dev Fund SHOULD be released under an Open Source license (as defined by the Open Source Initiative 2), preferably the MIT license.

-
-
Enforcement
-

FPF MUST contractually commit to fulfill these obligations on behalf of ZCG, and the prescribed use of funds, such that substantial violation, not promptly remedied, will result in a modified version of Zcash node software that removes ZCG’s Dev Fund slice and allocates it to the Deferred Dev Fund lockbox.

-
-
-
-

Funding Streams

-
    -
  • 12% of the block subsidy is to be distributed to the lockbox.
  • -
  • 8% of the block subsidy is to be distributed to the Financial Privacy Foundation (FPF), for the express use of the Zcash Community Grants Committee (ZCG) to fund independent teams in the Zcash ecosystem.
  • -
-

As of the activation of this ZIP, the complete set of funding streams for Mainnet will be:

- - - - - - - - - - - - - - - - - - - - - - - - - - -
StreamNumeratorDenominatorStart heightEnd height
FS_FPF_ZCG810027264003146400
FS_DEFERRED1210027264003146400
-

The set of funding streams for Testnet will be:

- - - - - - - - - - - - - - - - - - - - - - - - - - -
StreamNumeratorDenominatorStart heightEnd height
FS_FPF_ZCG810029760003396000
FS_DEFERRED1210029760003396000
-
-
-

References

- - - - - - - -
1Information 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"
- - - - - - - -
2The Open Source Definition
- - - - - - - -
3ZIP 1014: Dev Fund Proposal and Governance
- - - - - - - -
4ZIP 2001: Lockbox Funding Streams
- - - - - - - -
5Zcash Community Advisory Panel
-
-
- - \ No newline at end of file diff --git a/rendered/zip-2001.html b/rendered/zip-2001.html deleted file mode 100644 index 8e0ecfd19..000000000 --- a/rendered/zip-2001.html +++ /dev/null @@ -1,353 +0,0 @@ - - - - ZIP 2001: Lockbox Funding Streams - - - - -
-
ZIP: 2001
-Title: Lockbox Funding Streams
-Owners: Kris Nuttycombe <kris@nutty.land>
-Credits: Daira-Emma Hopwood <daira-emma@electriccoin.co>
-         Jack Grigg <jack@electriccoin.co>
-Status: Proposed
-Category: Consensus
-Created: 2024-07-02
-License: MIT
-Pull-Request: <https://github.com/zcash/zips/pull/>
-

Terminology

-

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

-
-

Abstract

-

This ZIP specifies a change to the Zcash consensus protocol to define a pool of issued Zcash value to be used to fund future development efforts within the Zcash ecosystem.

-

This ZIP builds upon the funding stream mechanism defined in ZIP 207 11. It defines a new "DEFERRED_POOL" funding stream type such that portions of the block reward sent to a stream of this type are deposited directly into the deferred funding pool instead of being sent to a recipient address. Other ways of adding to the pool, such as allowing for direct deposits or fee value currently allocated to miners may be defined in the future.

-
-

Motivation

-

In accordance with ZIP 1014, 16 the Zcash block reward is allocated with 80% going to miners, and the remaining 20% distributed among the Major Grants Fund (8%), Electric Coin Company (ECC) (7%), and the Zcash Foundation (ZF) (5%). This funding structure supports various essential activities such as protocol development, security, marketing, and legal expenses. However, this model will expire in November 2024, leading to the entire block reward being allocated to miners if no changes are made.

-

Several draft ZIPs under consideration for replacing the existing direct allocation of block rewards suggest that part of the block reward be directed to a reserve, the distribution of which is to be determined via a future ZIP. This ZIP is intended to provide a common mechanism that can be used to implement these various proposals.

-
-

Requirements

-

The Zcash protocol will maintain a new Deferred chain pool value balance - \(\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.

-

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

-

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.

-
-

In the section Funding streams 12, instead of:

-
-

Each funding stream has an associated sequence of recipient addresses, each of which MUST be either a transparent P2SH address or a Sapling address.

-
-

it will be modified to read:

-
-

Each element of - \(\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}\!\) - .

-
-

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 - \(\mathsf{ChainValuePoolBalance^{Deferred}}\) - chain value pool balance, in addition to the Sprout, Sapling, and Orchard chain value pool balances.

-

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}\_\mathsf{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}\) - 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})\!\) - .

-

Note: - \(\mathsf{totalDeferredOutput}(\mathsf{h})\) - is necessarily zero for heights - \(\mathsf{h}\) - prior to NU6 activation.

-
-

In the section Consensus rules 13, instead of:

-
-
    -
  • The coinbase transaction in each block MUST contain at least one output per active funding stream that pays the stream's value in the prescribed way to the stream's recipient address for the block's height.
  • -
-
-

it will be modified to read:

-
-
    -
  • 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 - \(\mathsf{DEFERRED}\_\mathsf{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.
  • -
  • - \(\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].

-

The effect of the definition of - \(\mathsf{ChainValuePoolBalance^{Deferred}}\) - above is that payments to the - \(\mathsf{DEFERRED}\_\mathsf{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:

-
-

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:

-
-

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 - \(\mathsf{height}\) - is given by - \(\mathsf{ChainValuePoolBalance^{Deferred}}(\mathsf{height}) := \sum_{\mathsf{h} = 0}^{\mathsf{height}} \mathsf{totalDeferredOutput}(\mathsf{h})\!\) - .

-

Non-normative notes:

-
    -
  • - \(\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 - \(\mathsf{height}\) - is given by the function:

-
-
\(\begin{array}{ll} -\mathsf{IssuedSupply}(\mathsf{height}) := &\!\!\!\!\mathsf{ChainValuePoolBalance^{Transparent}}(\mathsf{height}) \\ -&+\,\; \mathsf{ChainValuePoolBalance^{Sprout}}(\mathsf{height}) \\ -&+\,\; \mathsf{ChainValuePoolBalance^{Sapling}}(\mathsf{height}) \\ -&+\,\; \mathsf{ChainValuePoolBalance^{Orchard}}(\mathsf{height}) \\ -&+\,\; \mathsf{ChainValuePoolBalance^{Deferred}}(\mathsf{height}) -\end{array}\)
-

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}}\!\) - , 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 - \(\mathsf{height}\) - :

-
    -
  • define the "total output value" of its coinbase transaction to be the total value 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 - \(\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 is that the last paragraph will be replaced by:

-
-

[Pre-NU6] The total output value of a coinbase transaction MUST NOT be greater than its total input value.

-

[NU6 onward] The total output value of a coinbase transaction MUST be equal to its total input value.

-
-

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

- - - - - - - -
1Information 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"
- - - - - - - -
2Zcash Protocol Specification, Version 2024.5.1 [NU6]. Section 1.2: High-level Overview <protocol/protocol.pdf#overview>
- - - - - - - -
3Zcash Protocol Specification, Version 2024.5.1 [NU6]. Section 3.4: Transactions and Treestates <protocol/protocol.pdf#transactions>
- - - - - - - -
4Zcash Protocol Specification, Version 2024.5.1 [NU6]. Section 3.11: Coinbase Transactions and Issuance <protocol/protocol.pdf#coinbasetransactions>
- - - - - - - -
5Zcash Protocol Specification, Version 2024.5.1 [NU6]. Section 4.17: Chain Value Pool Balances <protocol/protocol.pdf#chainvaluepoolbalances>
- - - - - - - -
6Zcash Protocol Specification, Version 2024.5.1 [NU6]. Section 5.6.1.1: Transparent Addresses <protocol/protocol.pdf#transparentaddrencoding>
- - - - - - - -
7Zcash Protocol Specification, Version 2024.5.1 [NU6]. Section 5.6.3.1: Sapling Payment Addresses <protocol/protocol.pdf#saplingpaymentaddrencoding>
- - - - - - - -
8Zcash Protocol Specification, Version 2024.5.1 [NU6]. Section 7.1.2: Transaction Consensus Rules <protocol/protocol.pdf#txnconsensus>
- - - - - - - -
9Zcash Protocol Specification, Version 2024.5.1 [NU6]. Section 7.8: Calculation of Block Subsidy, Funding Streams, and Founders’ Reward <protocol/protocol.pdf#subsidies>
- - - - - - - -
10Zcash Protocol Specification, Version 2024.5.1 [NU6]. Section 7.10: Payment of Funding Streams <protocol/protocol.pdf#fundingstreams>
- - - - - - - -
11ZIP 207: Funding Streams <zip-0207.rst>
- - - - - - - -
12ZIP 207: Funding Streams. Section: Funding streams <zip-0207.rst#funding-streams>
- - - - - - - -
13ZIP 207: Funding Streams. Section: Consensus rules <zip-0207.rst#consensus-rules>
- - - - - - - -
14ZIP 207: Funding Streams. Section: Deployment <zip-0207.rst#deployment>
- - - - - - - -
15ZIP 253: Deployment of the NU6 Network Upgrade <zip-0253.rst>
- - - - - - - -
16ZIP 1014: Establishing a Dev Fund for ECC, ZF, and Major Grants <zip-1014.rst>
- - - - - - - -
17ZIP 1015: Block Reward Allocation for Non-Direct Development Funding <zip-1015.rst>
- - - - - - - -
18ZIP 2001: Lockbox Funding Streams <zip-2001.rst>
-
-
- - \ No newline at end of file diff --git a/rendered/zip-guide-markdown.html b/rendered/zip-guide-markdown.html deleted file mode 100644 index e1b2b2809..000000000 --- a/rendered/zip-guide-markdown.html +++ /dev/null @@ -1,254 +0,0 @@ - - - - ZIP guide-markdown: {Something Short and To the Point} - - - - - -
ZIP: Unassigned {numbers are assigned by ZIP editors}
-Title: {Something Short and To the Point}
-Owners: First Owner <email>
-        ...
-Credits: First Credited
-         ...
-Status: Draft
-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.

-

{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.

-

The terms below are to be interpreted as follows:

-
-
{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

-

{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.

-

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

-

{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

-
    -
  • 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.

-

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.
  • -
-

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.
-

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.

-

To link to another section of the same ZIP, use

-
`Section title`_
-

in reStructuredText, or

-
[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

- - - diff --git a/rendered/zip-guide.html b/rendered/zip-guide.html deleted file mode 100644 index ccc02ec80..000000000 --- a/rendered/zip-guide.html +++ /dev/null @@ -1,191 +0,0 @@ - - - - ZIP guide: {Something Short and To the Point} - - - - -
-
ZIP: Unassigned {numbers are assigned by ZIP editors}
-Title: {Something Short and To the Point}
-Owners: First Owner <email>
-        ...
-Credits: First Credited
-         ...
-Status: Draft
-Category: {Consensus | Standards Track | Network | RPC | Wallet | Informational | Process}
-Created: yyyy-mm-dd
-License: {usually MIT}
-Pull-Request: <https://github.com/zcash/zips/pull/253>
-

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 5.

-

The term "full validator" in this document is to be interpreted as defined in the Zcash protocol specification 4.

-

The terms below are to be interpreted as follows:

-
-
{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. 2 3.}

-
-

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.

-

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

-

{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 5 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?
  • -
-

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.

-

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.
  • -
-
-

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\!\) - , 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

- - -
-

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" 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.

-

To link to another section of the same ZIP, use "`Section title`_" in reStructuredText, or "[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

- - - - - - - -
1Information 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"
- - - - - - - -
2Zcash Protocol Specification, Version 2022.3.8 or later
- - - - - - - -
3Zcash Protocol Specification, Version 2022.3.8. Section 1: Introduction
- - - - - - - -
4Zcash Protocol Specification, Version 2022.3.8. Section 3.3: The Block Chain
- - - - - - - -
5Zcash Protocol Specification, Version 2022.3.8. Section 3.12: Mainnet and Testnet
- - - - - - - -
6KaTeX - The fastest math typesetting library for the web
- - - - - - - -
7ZIP 0: ZIP Process
- - - - - - - -
8The Hunting of the Snark. Lewis Carroll, with illustrations by Henry Holiday. MacMillan and Co. London. March 29, 1876.
-
-
- - \ No newline at end of file diff --git a/rendered/CNAME b/static/CNAME similarity index 100% rename from rendered/CNAME rename to static/CNAME diff --git a/rendered/assets/fonts/Roboto-Bold-webfont.woff b/static/assets/fonts/Roboto-Bold-webfont.woff similarity index 100% rename from rendered/assets/fonts/Roboto-Bold-webfont.woff rename to static/assets/fonts/Roboto-Bold-webfont.woff diff --git a/rendered/assets/fonts/Roboto-Light-webfont.woff b/static/assets/fonts/Roboto-Light-webfont.woff similarity index 100% rename from rendered/assets/fonts/Roboto-Light-webfont.woff rename to static/assets/fonts/Roboto-Light-webfont.woff diff --git a/rendered/assets/fonts/Roboto-Medium-webfont.woff b/static/assets/fonts/Roboto-Medium-webfont.woff similarity index 100% rename from rendered/assets/fonts/Roboto-Medium-webfont.woff rename to static/assets/fonts/Roboto-Medium-webfont.woff diff --git a/rendered/assets/fonts/Roboto-Regular-webfont.woff b/static/assets/fonts/Roboto-Regular-webfont.woff similarity index 100% rename from rendered/assets/fonts/Roboto-Regular-webfont.woff rename to static/assets/fonts/Roboto-Regular-webfont.woff diff --git a/rendered/assets/images/section-anchor.copyright b/static/assets/images/section-anchor.copyright similarity index 100% rename from rendered/assets/images/section-anchor.copyright rename to static/assets/images/section-anchor.copyright diff --git a/rendered/assets/images/section-anchor.png b/static/assets/images/section-anchor.png similarity index 100% rename from rendered/assets/images/section-anchor.png rename to static/assets/images/section-anchor.png diff --git a/rendered/assets/images/section-anchor.svg b/static/assets/images/section-anchor.svg similarity index 100% rename from rendered/assets/images/section-anchor.svg rename to static/assets/images/section-anchor.svg diff --git a/rendered/assets/images/zip-0032-orchard-internal-key-derivation.png b/static/assets/images/zip-0032-orchard-internal-key-derivation.png similarity index 100% rename from rendered/assets/images/zip-0032-orchard-internal-key-derivation.png rename to static/assets/images/zip-0032-orchard-internal-key-derivation.png diff --git a/rendered/assets/images/zip-0032-sapling-internal-key-derivation.png b/static/assets/images/zip-0032-sapling-internal-key-derivation.png similarity index 100% rename from rendered/assets/images/zip-0032-sapling-internal-key-derivation.png rename to static/assets/images/zip-0032-sapling-internal-key-derivation.png diff --git a/rendered/assets/images/zip-0068-encoding.png b/static/assets/images/zip-0068-encoding.png similarity index 100% rename from rendered/assets/images/zip-0068-encoding.png rename to static/assets/images/zip-0068-encoding.png diff --git a/static/assets/images/zip-0227-asset-identifier-relation-orchard-zsa.png b/static/assets/images/zip-0227-asset-identifier-relation-orchard-zsa.png new file mode 100644 index 000000000..aa12e678f Binary files /dev/null and b/static/assets/images/zip-0227-asset-identifier-relation-orchard-zsa.png differ diff --git a/rendered/assets/images/zip-0227-asset-identifier-relation.png b/static/assets/images/zip-0227-asset-identifier-relation.png similarity index 100% rename from rendered/assets/images/zip-0227-asset-identifier-relation.png rename to static/assets/images/zip-0227-asset-identifier-relation.png diff --git a/rendered/assets/images/zip-0227-key-components-zsa.png b/static/assets/images/zip-0227-key-components-zsa.png similarity index 100% rename from rendered/assets/images/zip-0227-key-components-zsa.png rename to static/assets/images/zip-0227-key-components-zsa.png diff --git a/static/assets/images/zip-0234-balance.png b/static/assets/images/zip-0234-balance.png new file mode 100644 index 000000000..131600add Binary files /dev/null and b/static/assets/images/zip-0234-balance.png differ diff --git a/static/assets/images/zip-0234-block_subsidy.png b/static/assets/images/zip-0234-block_subsidy.png new file mode 100644 index 000000000..cfc26c66a Binary files /dev/null and b/static/assets/images/zip-0234-block_subsidy.png differ diff --git a/rendered/assets/images/zip-0307-arch.png b/static/assets/images/zip-0307-arch.png similarity index 100% rename from rendered/assets/images/zip-0307-arch.png rename to static/assets/images/zip-0307-arch.png diff --git a/rendered/assets/images/zip-0316-f3.png b/static/assets/images/zip-0316-f3.png similarity index 100% rename from rendered/assets/images/zip-0316-f3.png rename to static/assets/images/zip-0316-f3.png diff --git a/rendered/assets/images/zip-0316-f4.png b/static/assets/images/zip-0316-f4.png similarity index 100% rename from rendered/assets/images/zip-0316-f4.png rename to static/assets/images/zip-0316-f4.png diff --git a/rendered/css/style.css b/static/css/style.css similarity index 59% rename from rendered/css/style.css rename to static/css/style.css index 77af4d69f..8ffef858c 100644 --- a/rendered/css/style.css +++ b/static/css/style.css @@ -1,6 +1,6 @@ @media (prefers-color-scheme: light) { body { - background: #ffffff; + background-color: #ffffff; color: #212529; } span.reserved { @@ -25,40 +25,84 @@ background-color: #a0a0ff; color: #111519; } + div.note + p { + background-color: #a0a0ff; + color: #111519; + } aside.note::before { background-color: #5858ff; color: #000000; } + div.note::after { + background-color: #5858ff; + color: #000000; + } aside.warning { background-color: #ffb090; color: #111519; font-weight: 500; } + div.warning + p { + background-color: #ffb090; + color: #111519; + font-weight: 500; + } aside.warning::before { background-color: #ff7050; font-weight: 600; } + div.warning::after { + background-color: #ff7050; + font-weight: 600; + } aside > p > a, a:visited { color: #0077a1; } + div.note + p > a, a:visited { + color: #0077a1; + } + div.warning + p > a, a:visited { + color: #0077a1; + } aside > p > a:hover { color: #00455c; } + div.note + p > a:hover { + color: #00455c; + } + div.warning + p > a:hover { + color: #00455c; + } blockquote { - background-color: #e0e0e0 + background-color: #e0e0e0; + } + code.mermaid { + background-color: #ffffff; + color: #ffffff; + } + code.mermaid > svg { + background-color: #f0f0f0; + border: 1.5em solid #f0f0f0; } } @media (prefers-color-scheme: dark) { + span.lightmode { + display: none; + } + span.darkmode { + display: inline !important; + } + body { - background: #111111; + background-color: #111111; color: #eeeeee; } img { - background: #bbbbbb; + background-color: #bbbbbb; } img.section-anchor { - background: #111111; + background-color: #111111; } span.reserved { color: #a0a0a0; @@ -82,29 +126,81 @@ background-color: #6060e0; color: #ffffff; } + div.note + p { + background-color: #6060e0; + color: #ffffff; + } aside.note::before { background-color: #3030e0; } + div.note::after { + background-color: #3030e0; + } aside.warning { background-color: #e08060; color: #ffffff; font-weight: 700; } + div.warning + p { + background-color: #e08060; + color: #ffffff; + font-weight: 700; + } aside.warning::before { background-color: #e05030; font-weight: 800; } + div.warning::after { + background-color: #e05030; + font-weight: 800; + } aside > p > a, a:visited { color: #50e7f4; } + div.note + p > a, a:visited { + color: #50e7f4; + } + div.warning + p > a, a:visited { + color: #50e7f4; + } aside > p > a:hover { color: #90ffff; } + div.note + p > a:hover { + color: #90ffff; + } + div.warning + p > a:hover { + color: #90ffff; + } blockquote { - background-color: #202020 + background-color: #202020; + } + code.mermaid { + background-color: #111111; + color: #111111; + } + code.mermaid > svg { + background-color: #d0d0d0; + border: 1.5em solid #d0d0d0; } } +code.mermaid { + display: block; + width: calc( 100% - 4em - 0.5rem ); +} + +code.mermaid > svg { + overflow-x: visible !important; +} + +pre:has(.mermaid) { + border: none !important; + margin: 0 !important; + padding-left: 1rem !important; + padding-bottom: 1.5rem !important; +} + aside { display: flex; flex-direction: column; @@ -115,24 +211,80 @@ aside { padding-bottom: 0; margin-bottom: 1.5rem; } -aside::before { +div.note + p { + padding-top: 4.4rem; + padding-left: 0.15rem; + padding-right: 0.15rem; + padding-bottom: 1.4rem; + margin-top: -2.25rem; + margin-bottom: 1.5rem; +} +div.warning + p { + padding-top: 4.4rem; + padding-left: 0.15rem; + padding-right: 0.15rem; + padding-bottom: 1.4rem; + margin-top: -2.25rem; + margin-bottom: 1.5rem; +} +aside.note::before { font-size: 130%; padding-top: 0.2rem; padding-left: 1rem; padding-right: 0.2rem; padding-bottom: 0.3rem; margin-bottom: 1.2rem; + content: "Note"; } -aside.note::before { +div.note::after { + width: 96.7%; + display: inline-block; + font-size: 130%; + padding-top: 0.2rem; + padding-left: 1rem; + padding-right: 1rem; + padding-bottom: 0.3rem; + margin-top: 0.2rem; + margin-left: 0.2rem; + margin-right: 0.2rem; + margin-bottom: -0.4rem; content: "Note"; } aside.warning::before { + font-size: 130%; + padding-top: 0.2rem; + padding-left: 1rem; + padding-right: 0.2rem; + padding-bottom: 0.3rem; + margin-bottom: 1.2rem; + content: "Warning"; +} +div.warning::after { + width: 97.8%; + display: inline-block; + font-size: 130%; + padding-top: 0.2rem; + padding-left: 1rem; + padding-right: 0.2rem; + padding-bottom: 0.3rem; + margin-top: 0.2rem; + margin-left: 0.2rem; + margin-right: 0.2rem; + margin-bottom: -0.4rem; content: "Warning"; } aside > p { padding-left: 1rem; padding-right: 1rem; } +div.note + p { + padding-left: 1rem; + padding-right: 1rem; +} +div.warning + p { + padding-left: 1rem; + padding-right: 1rem; +} @font-face { font-family: robotolight; @@ -247,6 +399,10 @@ blockquote { overflow-x: auto; } +blockquote > p:has(.math) { + line-height: calc( 1rem + 1.8ex ); +} + p { margin-top: 0; margin-bottom: calc( 1rem + 1ex ); @@ -266,6 +422,21 @@ li ol { margin-top: 0.25ex; } +/* +Default nested-ordered-list numbering for Markdown ZIPs (which have no way +to set `
    ` from source): ordered list levels are numeric, then +alphabetic, then lower-roman (e.g. 1. a. i.). The `:not([type])` qualifier +preserves explicit type attributes emitted by the RST renderer or inline HTML, +which can be semantically significant. +*/ +li ol:not([type]) { + list-style-type: lower-alpha; +} + +li ol:not([type]) li ol:not([type]) { + list-style-type: lower-roman; +} + li ul { margin-top: 0.25ex; } @@ -289,28 +460,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; + margin: 2rem 1rem 2rem 1rem; text-align: center; - padding: 0; - font-size: 0.97rem; + padding: 1rem; } a, a:visited { @@ -337,13 +498,77 @@ 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; font-weight: normal; @@ -354,7 +579,6 @@ hr { margin: 1.875rem 0; } - table { border-collapse: collapse; border: 0 none transparent; @@ -392,22 +616,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/update_check.sh b/update_check.sh new file mode 100755 index 000000000..591a586c2 --- /dev/null +++ b/update_check.sh @@ -0,0 +1,102 @@ +#!/bin/bash + +set -euo pipefail + +HASH=sha384 + +# Calculate the SHA-384 Subresource Integrity (SRI) digest of the given file. +# See and . +sridigest() { + echo "$HASH-$(${HASH}sum -b "$1" |sed 's|\([^ ]*\).*|\1|' |xxd -p -r |base64)" +} + +download() { + # --fail: Fail with error code 22 and with no output for HTTP transfers returning response codes at 400 or greater. + curl --fail --silent -o "$1" -- "$2" +} + +# Relevant lines are those in `render.sh` containing '="https://..."...>'. +# Each dependency must be on a separate line. If a URL should not be checked as a dependency, +# break it up like this: 'https''://' . +# +# We check that: +# * each relevant line contains (in this order) '="" integrity="" crossorigin="anonymous"'; +# * is versioned (contains '@.../'); +# * the contents of match those of the corresponding unversioned URL without '@...'; +# * is a correctly prefixed and base64-encoded $HASH SRI digest of the contents. +# +# There are a number of ways these checks could be insufficient; they don't replace review of `render.sh`. + +mkdir -p temp + +problems=$(grep -o '="https://[^"]*"[^>]*>' render.sh | while read line; do + # Output problems to stdout, and warnings to temp/.warnings.txt + + url=$(echo "$line" |sed 's|="\(https://[^"]*\)".*|\1|') + current_url=$(echo "$url" |sed -n 's|\([^@]\)@[^/]*\(/.*\)|\1\2|p') + filename=$(basename "$url") + referenced="temp/${filename}_referenced" + current="temp/${filename}_current" + + rm -f "$referenced" "$current" + # We do this first so that the loop over temp/* below can print the SRI digest (if the file can be downloaded). + download "$referenced" "$url" + + if [ -z "$current_url" ]; then + echo "::error:: $url is not versioned." + elif [ ! -f "$referenced" ]; then + echo "::error:: $url could not be downloaded." + else + download "$current" "$current_url" + + maybe_delete=0 + if [ ! -f "$current" ]; then + echo "::warning:: $current_url could not be downloaded." >>temp/.warnings.txt + elif ! diff -q --binary "$referenced" "$current" >/dev/null; then + echo "::warning:: $url is not the current version (it does not match $current_url)." >>temp/.warnings.txt + else + maybe_delete=1 + fi + + # Check the SRI digest regardless of whether it is the current version. + given=$(echo "$line" |sed -n 's|="https://[^"]*" integrity="\([^"]*\)" crossorigin="anonymous".*|\1|p') + if [ -z "$given" ]; then + echo "::error:: Did not find 'integrity="..." crossorigin="anonymous"' in: $line" + else + calculated=$(sridigest "$referenced") + if [ "$given" != "$calculated" ]; then + echo "::error:: Given SRI digest '$given' for $url does not match calculated digest '$calculated'." + elif [ $maybe_delete -eq 1 ]; then + rm -f "$referenced" "$current" + fi + fi + fi +done) +warnings=$( + Daira-Emma Hopwood + Status: Draft + Category: Consensus + Created: 2025-08-13 + License: MIT + Discussions-To: + Pull-Request: + + +# Terminology + +The key word "MUST" and "OPTIONAL" 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 term "transparent protocol" in this document refers to the +payment protocol derived from Bitcoin that provides no privacy. + +The term "Sprout shielded protocol" in this document refers to the shielded +payment protocol present at Zcash launch. [^protocol] + +The term "Sapling shielded protocol" in this document refers to the shielded +payment protocol introduced in the Sapling network upgrade. [^zip-0205] + +The term "Orchard shielded protocol" in this document refers to the shielded +payment protocol introduced in the NU5 network upgrade. [^zip-0252] + +The term "transparent chain value pool balance" in this document is to be +interpreted as described in § 4.17 ‘Chain Value Pool Balances’. +[^protocol-chainvaluepoolbalances] + + +# Abstract + +This proposal disables the ability to add new value to the transparent chain +value pool balance. This takes a step toward being able to remove the +transparent protocol, thus reducing the overall complexity and attack surface +of Zcash and increasing user privacy without causing the loss of users' funds. + + +# Motivation + +There are three separate major motivations for this ZIP: + +- Since Zcash is a private blockchain, user expectations of privacy are better + protected by deprecating the transparent pool, which is not private. + +- At the launch of the Zcash network, two payment protocols were supported: + the Sprout shielded protocol, which was relatively closely based on + the original Zerocash proposal [^zerocash], and the transparent protocol + derived from Bitcoin. + + The Sprout shielded protocol was later obsoleted by the Sapling and then + Orchard shielded protocols, which introduced significant efficiency and + functionality improvements for shielded transactions. The transparent protocol + has stayed largely the same. + + Removing the ability to add to the transparent chain value pool balance is a + first step toward reducing complexity and potential risk in the overall Zcash + protocol, and reducing potential user confusion about the level of privacy they + obtain from Zcash. + +- The transparent scripting system is too complicated to implement in a zk-SNARK + circuit, which precludes likely approaches to scaling Zcash [^tachyon]. + +This proposal disables adding new value to the transparent chain value pool, +thus requiring funds to be moved over time into the Sapling or Orchard shielded +pools. + +The implication of this is that when coinbase outputs (miner subsidy, fees, and +funding stream outputs) are shielded, they cannot later be unshielded, which +will have the effect of increasing the total proportion of funds held in shielded +pools relative to the transparent pool. + + +# Specification + +Define the *total transparent input value* of a transaction as follows: + +- if it is a coinbase transaction, its total input value as defined in § 7.1.2 + ‘Transaction Consensus Rules’ [^protocol-txnconsensus]; +- otherwise, the total value of its transparent inputs. + +Consensus rule: The total value of transparent outputs in a transaction MUST be +less than or equal to its total transparent input value. + +Note: The facility to send to transparent addresses, and/or to give out transparent +addresses on which funds can be received, has always been OPTIONAL for a particular +Zcash wallet implementation. + + +# Rationale + +The implication of this is that when coinbase outputs (miner subsidy, fees, and +funding stream outputs) are shielded, they cannot later be unshielded, which +will have the effect of increasing the total proportion of funds held in shielded +pools relative to the transparent pool. + +The code changes needed are very small and simple, and their security is easy to +analyse. + +This ZIP is similar to ZIP 211 [^zip-0211] in that it disallows new funds to be +added to the transparent chain value pool balance as ZIP 211 disallowed new funds +to be added to the Sprout chain value pool balance. The consensus rule does not +take the same form because there is no field corresponding to `vpub_old` for the +transparent protocol. + +Rejected alternatives: + +- Disallow all transparent outputs (this implies the proposed rule). +- Allow at most a single transparent output per transaction in addition to + the proposed rule. + +These were rejected as they seem too impractical at the time of this writing. +In particular, exchanges that need to use the transparent pool for regulatory +reasons would likely need to delist Zcash, and the ecosystem of decentralized +exchanges that support Zcash is insufficiently established to replace the role +that centralized exchanges play today. + + +# Security and Privacy Considerations + +The security motivations for making this change are described in the Motivation section. +Privacy concerns that led to the current design are discussed in the Rationale section. + +Since all clients MUST change their behaviour at the same time from this proposal's activation +height, there is no additional client distinguisher. + + +# Deployment + +This ZIP is not currently proposed to activate in a specific network upgrade. + + +# Reference Implementation + +TODO + + +# 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"](https://www.rfc-editor.org/info/bcp14) + +[^zip-0200]: [ZIP 200: Network Upgrade Mechanism](zip-0200.rst) + +[^protocol]: [Zcash Protocol Specification, Version 2025.6.2 [NU6.1] or later](protocol/protocol.pdf) + +[^protocol-chainvaluepoolbalances]: [Zcash Protocol Specification, Version 2025.6.2 [NU6.1]. Section 4.17: Chain Value Pool Balances](protocol/protocol.pdf#chainvaluepoolbalances) + +[^protocol-txnconsensus]: [Zcash Protocol Specification, Version 2025.6.2 [NU6.1]. Section 7.1.2: Transaction Consensus Rules](protocol/protocol.pdf#txnconsensus) + +[^zip-0205]: [ZIP 205: Deployment of the Sapling Network Upgrade](zip-0205.rst) + +[^zip-0211]: [ZIP 211: Disabling Addition of New Value to the Sprout Chain Value Pool](zip-0211.rst) + +[^zip-0252]: [ZIP 252: Deployment of the NU5 Network Upgrade](zip-0252.rst) + +[^zerocash]: [Zerocash: Decentralized Anonymous Payments from Bitcoin (extended version)](https://eprint.iacr.org/2014/349) + +[^tachyon]: [Tachyon: Scaling Zcash with Oblivious Synchronization](https://seanbowe.com/blog/tachyon-scaling-zcash-oblivious-synchronization/) diff --git a/zips/draft-arya-deploy-nu7.md b/zips/draft-arya-deploy-nu7.md new file mode 100644 index 000000000..d2857dbe6 --- /dev/null +++ b/zips/draft-arya-deploy-nu7.md @@ -0,0 +1,84 @@ + + ZIP: XXX + Title: Deployment of the NU7 Network Upgrade + Owners: Arya + Status: Draft + Category: Consensus / Network + Created: 2024-10-31 + License: MIT + Discussions-To: + + +# 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 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 + +This proposal defines the deployment of the NU7 network upgrade. + + +# Specification + +## NU7 deployment + +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 following network upgrade constants [^zip-0200] are defined for the +NU7 upgrade: + +CONSENSUS_BRANCH_ID +: `0x77190AD8` + +ACTIVATION_HEIGHT (NU7) +: Testnet: TBD +: Mainnet: TBD + +MIN_NETWORK_PROTOCOL_VERSION (NU7) +: Testnet: `170150` +: Mainnet: `170160` + +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 + +[^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 2025.6.2 [NU6.1] or later](protocol/protocol.pdf) + +[^protocol-networks]: [Zcash Protocol Specification, Version 2025.6.2 [NU6.1]. Section 3.12: Mainnet and Testnet](protocol/protocol.pdf#networks) + +[^zip-0200]: [ZIP 200: Network Upgrade Mechanism](zip-0200.rst) + +[^zip-0201]: [ZIP 201: Network Peer Management for Overwinter](zip-0201.rst) diff --git a/zips/draft-ecc-authenticated-reply-addrs.md b/zips/draft-ecc-authenticated-reply-addrs.md new file mode 100644 index 000000000..48ceb5b15 --- /dev/null +++ b/zips/draft-ecc-authenticated-reply-addrs.md @@ -0,0 +1,134 @@ + ZIP: ??? + Title: Authenticated Reply Addresses + Owners: Jack Grigg + Kris Nuttycombe + Daira-Emma Hopwood + Status: Draft + Category: Standards / Wallet + Created: 2023-11-12 + License: MIT + Discussions-To: + Pull-Request: + + +# Terminology + +The key words "MUST" and "SHOULD" in this document is to be interpreted as described in +BCP 14 [#BCP14] when, and only when, they appear in all capitals. + + +# Abstract + +TODO + + +# Motivation + +TODO + + +# Specification + +## Authenticated reply address encoding + +- Versioning (which could instead be represented by the ZIP 302 TLV type). +- The reply address. + - This uses a binary encoding of a ZIP 316 Unified Address. + - TODO: decide on specifics - https://github.com/zcash/librustzcash/pull/711#issuecomment-1377783264 + - This might be the same address for all inputs, or it might only cover a subset of them + (in a collaborative multi-sender transaction). +- A non-empty list of tuples: + - $\mathsf{receiver_type}$: The receiver type for which this proof is made. This receiver + MUST match one of the receiver types in the reply address. + - $\mathsf{addr_proof}_\mathsf{pool_type}$: An address proof for that pool type. + +## Creating + +## Verifying + +- Verify that the transaction is valid (in particular, that all proofs and signatures are valid). +- Decrypt the transaction output to obtain the memo field. +- Decode the authenticated reply address. + - This MUST validate the inner encodings of e.g. ZIP 316 for UAs (as applicable). +- Verify each address proof. + +## Sapling address proof + +### Encoding + +- $\mathsf{index}$: An index into $\mathsf{tx.shieldedSpends}$. +- $\mathsf{nullifier_{addr}}$: A nullifier for a ZIP 304 fake note. [#zip-0304] +- $\mathsf{zkproof_{addr}}$: A Sapling spend proof. + +### Creating + +Taking as input: +- The Sapling expanded spending key. +- $\alpha$: The randomness used to construct the spend description. +- $\mathsf{index}$: An index into $\mathsf{tx.shieldedSpends}$. + +The Sapling address proof is created as follows: + +- Extract the Sapling receiver from the reply address. +- Compute $(\mathsf{nf}, zkproof) = Zip304CreateProof(sapling_receiver, expanded_sk, alpha)$. +- Return $(\mathsf{index}, \mathsf{nf}, zkproof)$ + +### Verifying + +- Extract the Sapling receiver from the reply address. +- Look up the spend description at $\mathsf{tx.shieldedSpends}[\mathsf{index}]$. +- Extract $\mathsf{rk}$ from the spend description. +- Call $Zip304VerifyProof(sapling_receiver, \mathsf{nullifier_{addr}}, \mathsf{rk}, \mathsf{zkproof_{addr}})$, and return an error if it fails. + +# Rationale + +We do not generate and include a full ZIP 304 signature in the Sapling address proof; we +only rely on its proof-of-address helper function. This is for two reasons: +- The ZIP 304 `spendAuthSig` proves knowledge of the spend authorizing key, but we already + obtain that from the `spendAuthSig` on the Sapling spend description, so there is no + additional security benefit from including it, and omitting it decreases the encoding + size. +- We do not need to encode `rk` because it is already present in the transaction. + +The individual address proofs commit to the entire reply address. For example, if the +reply address contains a Sapling and Orchard receiver, but the transaction only spends +Sapling notes, the sender is still confirming that the Orchard receiver is also an allowed +reply address receiver. + +However, to have proper cross-linking, we need to ensure that all receivers in the UA have +proofs of spend authority, to prevent a sender from including a receiver that they do not +control (as a form of impersonation attack). There are a few ways this could be resolved: +- Always require the transaction to spend notes for all receivers. + - Pro: This could be done with dummy notes for the pools that the sender doesn't want to + spend from. + - Con: This would prevent the sender from pre-emptively adding receivers for upcoming + shielded pools that are not yet activated. + - Con: For UAs with transparent receivers, this would be incompatible with shielded-only + transactions. +- Have an optional proof of spend authority in the address proof. + - This is omitted when a spent note is present for that receiver type (as the spent note + serves this purpose). + - This is pretty much the exact opposite of ZIP 311 (where we require proofs of spend + authority, and have optional proof-of-address). + +In any case, doing this for UAs that include Orchard receivers will result in more data +than can be stored in a single memo field, so this is blocked on some kind of multi-part +memo encoding. + + +# Security and Privacy Considerations + +The verification process for authenticated reply addresses requires that the full +transaction is validated, because it outsources proof-of-spend-authority to the spend +proofs and signatures. As a consequence, wallets that scan transactions via a light client +protocol MUST NOT show the reply address as authenticated until the full transaction has +been downloaded and validated. + +# Reference implementation + +TBD + + +# 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" diff --git a/zips/draft-ecc-onchain-accountable-voting.md b/zips/draft-ecc-onchain-accountable-voting.md new file mode 100644 index 000000000..5ee94d61a --- /dev/null +++ b/zips/draft-ecc-onchain-accountable-voting.md @@ -0,0 +1,173 @@ + ZIP: XXX + Title: On-chain Accountable Voting + Owners: Daira-Emma Hopwood + Status: Draft + Credits: Josh Swihart + Kris Nuttycombe + Jack Grigg + Category: Consensus / Process + Created: 2025-02-21 + License: MIT + Pull-Request: + + +# Terminology + +The key words "MUST", "REQUIRED", "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 terms "Mainnet" and "Testnet" in this document are to be interpreted as defined in the Zcash protocol specification [^protocol-networks]. + +TODO: Consider defining "Proposal", "Decision", "Approval", "Rejection", etc. + + +# Abstract + +This proposal specifies a mechanism for on-chain accountable voting that is available for use by Zcash governance and funding proposals. + + +# Motivation + +Several proposals that have been made for the future of Zcash governance, including the Zcash Governance Bloc [^draft-ecc-zbloc] and Loan-Directed Retroactive Grants [^forum-loan-directed-retroactive-grants], require similar mechanisms. In particular they require some form of on-chain accountable voting. + +The details of these mechanisms matter for security and robust oversight. Separating the concerns of governance and funding policy on the one hand, and the mechanisms used to enact this policy on the other, frees initial policy proposals (and proposers) from having to specify unnecessary detail, while ensuring that implementability and security concerns are nonetheless thoroughly considered. + +Using a shared vocabulary and repertoire of implementation mechanisms can also facilitate comparison of governance and funding proposals, by focussing attention on their higher-level differences. + +It is possible that these mechanisms may also have wider usefulness in the Zcash ecosystem beyond governance and development funding. + + +# Requirements + +* This specification should avoid, as far as possible, over-constraining how decisions about governance and funding are made, if and when they use this mechanism. +* The mechanism is resistant to compromise of some of the parties' keys, up to a given threshold. +* No single party's non-cooperation or loss of keys is able to cause further decisions to be blocked indefinitely. + + +# Non-requirements + +The on-chain accountable voting mechanism does not need to directly support coinholder voting. If that is required, it should be performed via a separate protocol. The results of that protocol might then feed into votes cast in on-chain accountable voting, as suggested by the Zcash Governance Bloc [^draft-ecc-zbloc] proposal, for example. + + +# Specification + +A Proposal to be decided using On-chain Accountable Voting is represented as a Proposal Transaction, which references a human-readable Description of what is to happen on its Approval. The Proposal Transaction MAY also lock up funds that are to be granted on Approval [TODO]. + +The scope of possible Proposals is left to be specified by the high-level policy that uses this mechanism. + +A Decision is represented by spending the Approval Output or Rejection Output of the Proposal, as described in [Decisions]. This can signal either an Approval, recording the fact that the Approval Threshold has been met, or a Rejection, recording the fact that sufficient voting units have been cast against the Proposal that its Approval Threshold *cannot* be met. + +More concretely, if there are $V$ voting units overall and $A = \mathsf{ceiling}(V \cdot \mathsf{threshold})$ of them are required for approval, then $V - A + 1$ voting units suffice for Rejection. + +A Proposal also has a Deadline Height. It is Implicitly Rejected if no Approval or Rejection occurs on the consensus chain *at or before* the Deadline Height (that is, the Deadline Height is inclusive). + +Honestly constructed Proposals SHOULD take into account any planned change in the block target spacing when setting the Deadline Height (see [Block Target Spacing changes]). + +## Proposal Transactions + +A transaction is considered to be a Proposal Transaction if and only if it includes exactly one Specification Output, exactly one Approval Output, and exactly one Rejection Output, as specified below. + +### Description Output + +A Proposal Transaction MUST reference a human-readable Description of what is being voted on. This is represented by a Description Output encrypted to the zero $\mathsf{ovk}$, in the same way as for shielded coinbase transactions [^zip-0213]. The plaintext memo of the Description Output MUST use the following format: + +* the string $\texttt{“b2-256:”}$ +* a hex-encoded BLAKE2b-256 hash of the contents of the file specifying the proposal +* the string $\texttt{“:”}$ +* a stable URL to the contents of that file. + +The URL MUST be encoded as US-ASCII, but MAY use %-encoding to specify UTF-8 characters as described in [^uri-utf8]. + +For example, to refer to the contents of ZIP 1015 at time of writing: + + "b2-256:bacb0d5430968e4ce77246523d0e6f29c442f8fce0f3656462fdf5a5c4b8c656:" || + "https://raw.githubusercontent.com/zcash/zips/38e4501a2c3bf90f6057872db497295a0a76eb35/zips/zip-1015.rst" + +Since a memo field can be a maximum of 512 bytes, this currently allows a maximum of 440 bytes for the URL, which should be enough. If and when memo bundles [^zip-0231] are supported, this will increase the allowed size, and potentially allow the text of the proposal to be encoded directly in the memo. + +The contents of the file at the given URL MUST NOT be automatically downloaded unless that is requested by an explicit user action. + +## Approval and Rejection Outputs + +Let DeadlineHeight be the last block height at which a Decision can be made for this Proposal. + +An Approval Output is a P2SH output with a script of the following form: + +* TBD + +A Rejection Output is a P2SH output with a script of the following form: + +* TBD + +## Decisions + +Approval of a Proposal Transaction is signalled by spending its Approval Output in a transaction mined at or before the Deadline Height. + +Rejection of a Proposal Transaction is signalled by spending its Rejection Output in a transaction mined at or before the Deadline Height. + +A spend of an Approval or Rejection Output that occurs in a transaction mined strictly after the Proposal's Deadline Height has no effect. + +A spend of an Approval or Rejection Output is performative [^wikipedia-performative-utterance] in the sense that, even if it does not directly transfer funds, it records that the decision has been made. + +A holder of voting units SHOULD NOT sign transactions that spend both the Approval Output and the Rejection Output of a given Proposal Transaction. However, if this does occur, then it is interpreted as follows: + +* If Approval and Rejection occur in the same transaction, then the proposal is rejected. +* Otherwise, the outcome is determined by which of the Approval and Rejection outputs is spent first (i.e. in the earlier transaction). + +As stated earlier, a Proposal is Implicitly Rejected if no Approval or Rejection occurs on the consensus chain at or before the Deadline Height. + +### Finality of Decisions + +Zcash's current consensus layer provides only eventual consistency. A Decision SHOULD be considered "final" when it has 100 confirmations. (In the case where the Decision transaction also directly transfers funds to a recipient, this does not constrain the recipient's ability to spend the funds.) + +An Implicit Rejection SHOULD be considered final if a transaction in a block at the Deadline Height would have 100 confirmations. + +If and when a mechanism for "assured finality" [^tfl-book-assured-finality] of transactions is adopted by the Zcash network, it is expected to be possible to redefine "finality" of Decisions accordingly. + +## Testnet-specific considerations + +Proposal Transactions on Testnet MUST only be used to test this mechanism, and have no significance for Zcash governance. + + +# Rationale + +## Block Target Spacing changes + +The block target spacing of the Zcash network is currently 75 seconds, but is not necessarily fixed. For example, the current value was established at activation of the Blossom network upgrade, halving the previous value of 150 seconds. This potentially has implications for the use of block heights to specify deadlines, but in practice we believe that block heights will suffice: + +* If the block target spacing decreases, then this can only bring a deadline closer. This is not a problem because the Proposal can always be resubmitted if it expires sooner than intended. +* Changes that increase the block target spacing are usually signalled well in advance. It is therefore very unlikely that a deadline will unintentionally be extended. In any case, it is always possible to explicitly Reject any proposal for which the deadline is unintentionally extended. + + +# Reference implementation + +TBD + + +# Acknowledgements + +Thank you to Josh Swihart and Kris Nuttycombe for discussions about [^draft-ecc-zbloc] and [^zip-1016] that led to the idea for this ZIP. + + +# 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"](https://www.rfc-editor.org/info/bcp14) + +[^protocol]: [Zcash Protocol Specification, Version 2024.5.1 or later](protocol/protocol.pdf) + +[^protocol-networks]: [Zcash Protocol Specification, Version 2024.5.1. Section 3.12: Mainnet and Testnet](protocol/protocol.pdf#networks) + +[^zip-0213]: [ZIP 213: Shielded Coinbase](zip-0213.rst) + +[^zip-0231]: [ZIP 231: Memo Bundles](zip-0231.rst) + +[^draft-ecc-zbloc]: [draft-ecc-zbloc: Zcash Governance Bloc](draft-ecc-zbloc.md) + +[^zip-1016]: [ZIP 1016: Community and Coinholder Funding Model](zip-1016.md) + +[^forum-loan-directed-retroactive-grants]: [Zcash forum: Loan-Directed Retroactive Grants](https://forum.zcashcommunity.com/t/loan-directed-retroactive-grants/48230) + +[^tfl-book-assured-finality]: [Zcash Trailing Finality Layer. Section 2: Terminology — Assured Finality](https://electric-coin-company.github.io/tfl-book/terminology.html#definition-assured-finality) + +[^uri-utf8]: [RFC 3986: Uniform Resource Identifier (URI). Section 2.5: Identifying Data](https://www.rfc-editor.org/rfc/rfc3986.html#section-2.5) + +[^wikipedia-performative-utterance]: [Wikipedia: Performative utterance](https://en.wikipedia.org/wiki/Performative_utterance) diff --git a/zips/draft-noamchom67-manufacturing-consent.rst b/zips/draft-noamchom67-manufacturing-consent.rst deleted file mode 100644 index bbbb9e359..000000000 --- a/zips/draft-noamchom67-manufacturing-consent.rst +++ /dev/null @@ -1,497 +0,0 @@ -:: - - ZIP: #### - Title: Manufacturing Consent; Re-Establishing a Dev Fund for ECC, ZF, ZCG, Qedit, FPF, and ZecHub - Owner: Noam Chom - Credits: The ZIP-1014 Authors - Status: Withdrawn - Category: Consensus Process - Created: 2024-06-25 - License: MIT - Discussions-To: - Pull-Request: TBD - - -Terminology -=========== - -The key words "MUST", "MUST NOT", "SHALL", "SHALL 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]_ and the Zcash Trademark Donation and License -Agreement ([#trademark]_ or successor agreement). - -The terms "block subsidy" and "halving" in this document are to be interpreted -as described in sections 3.10 and 7.8 of the Zcash Protocol Specification. -[#protocol]_ - -"Electric Coin Company", also called "ECC", refers to the Zerocoin Electric -Coin Company, LLC. - -"Bootstrap Project", also called "BP", refers to the 501(c)(3) nonprofit -corporation of that name. - -"Zcash Foundation", also called "ZF", refers to the 501(c)(3) nonprofit -corporation of that name. - -"Section 501(c)(3)" refers to that section of the U.S. Internal Revenue -Code (Title 26 of the U.S. Code). [#section501c3]_ - -"Community Advisory Panel" refers to the panel of community members assembled -by the Zcash Foundation and described at [#zf-community]_. - -"Zcash Community Grants", also called "ZCG", refers to grants program -(formerly known as ZOMG) that funds independent teams entering the Zcash ecosystem, -to perform major ongoing development (or other work) -for the public good of the Zcash ecosystem. - - -"Financial Privacy Foundation", also called "FPF" refers to the start-up non-profit -organization incorporated and based in the Cayman Islands. - - -"Qedit" refers to the company founded in 2016 by a world-class team of -accomplished tech entrepreneurs, researchers, and developers; -QEDIT has emerged as a global leader in the field of Zero-Knowledge Proofs. - - -"ZecHub" refers to the team of content creators who have supported Zcash -through a series of ZCG approved grants. - - -The terms "Testnet" and "Mainnet" are to be interpreted as described in -section 3.12 of the Zcash Protocol Specification [#protocol-networks]_. - -The term "ZSA" is to be interpreted as "Zcash Shielded Assets" the protocol -feature enhancement (and subsequent application layer, legal, maintenance -efforts, et al) on-going by Qedit, et al. - - -✳️ is used to denote elements of the process part of the ZIP that are still -to-be-determined. - - -Abstract -======== - -This proposal describes a structure for the Zcash Development Fund, to be -enacted in Network Upgrade 6 and last for 4 years. This Dev Fund would consist -of 15% of the block subsidies, as the following allocations: - -* 5% for the Zcash Foundation (for internal work and grants); -* 4% for the Bootstrap Project (the parent of the Electric Coin Company) for the 1st year only; -* 4% for Zcash Community Grants for continuation of their current activities as-is; -* 2% for Qedit in support of their ZSA activities, and other Zcash protocol support; - -Following the first year, when ECC will no longer receive their 4% allocation, -those block subsidies will be distributed as 1% to ZCG, 1% to ZecHub, 1% to FPF, -and 1% to ZF. - -Governance and accountability are based on existing entities and legal mechanisms, -and increasingly decentralized governance is encouraged. This proposal mandates -the ecosystem to design and deploy a "non-direct funding model" as generally -recommended in Josh Swihart's proposal. [#draft-swihart]_ - -Upon creation/ activation of a "non-direct funding model" this ZIP should be -reconsidered (potentially terminated) by the Zcash ecosystem, to determine -if its ongoing direct block subsidies are preferred for continuation. -Discussions/ solications/ sentiment gathering from the Zcash -ecosystem should be initiated ~6 months in advance of the presumed -activation of a "non-direct funding model", such that the Zcash ecosystem -preference can be expediently realized. - -Block subsidies will be administered through two organizations: - -1. Zcash Foundation (✳️ for ECC, ZCG) -2. Financial Privacy Foundation (✳️ for Qedit, ZecHub) - -✳️ **ZF and FPF adminstration of block subsidy details, costs, et al are currently under debate** -[#zf-fpf-admin-details]_ - - -Motivation -========== - -As of Zcash's second halving in November 2024, by default 100% of the block -subsidies will be allocated to miners, and no further funds will be automatically -allocated to any other entities. Consequently, no new funding -may be available to existing teams dedicated to furthering charitable, -educational, or scientific purposes, such as research, development, and outreach: -the Electric Coin Company (ECC), the Zcash Foundation (ZF), the ZCG, and the many -entities funded by the ZF and ZCG grant programs. - -There is a need to strike a balance between incentivizing the security of the -consensus protocol (i.e., mining) versus crucial charitable, educational, and/or -scientific aspects, such as research, development and outreach. - -Furthermore, there is a need to balance the sustenance of ongoing work by the -current teams dedicated to Zcash, with encouraging decentralization and growth -of independent development teams. - -For these reasons, the Zcash Community desires to allocate and -contribute a portion of the block subsidies otherwise allocated to -miners as a donation to support charitable, educational, and -scientific activities within the meaning of Section 501(c)(3). - -This proposal also introduces the benefit of a non-USA based entity (FPF) as -the administrator for block subsidies to two organizations that are also -non-USA based (Qedit and ZecHub). USA based regulatory risk continues to -(negatively) impact the Zcash project, which has been predominantly based in the USA. - - -Requirements -============ - -The Dev Fund should encourage decentralization of the work and funding, by -supporting new teams dedicated to Zcash. - -The Dev Fund should maintain the existing teams and capabilities in the Zcash -ecosystem, unless and until concrete opportunities arise to create even greater -value for the Zcash ecosystem. - -There should not be any single entity which is a single point of failure, i.e., -whose capture or failure will effectively prevent effective use of the funds. - -Major funding decisions should be based, to the extent feasible, on inputs from -domain experts and pertinent stakeholders. - -The Dev Fund mechanism should not modify the monetary emission curve (and in -particular, should not irrevocably burn coins). - -In case the value of ZEC jumps, the Dev Fund recipients should not wastefully -use excessive amounts of funds. Conversely, given market volatility and eventual -halvings, it is desirable to create rainy-day reserves. - -The Dev Fund mechanism should not reduce users' financial privacy or security. -In particular, it should not cause them to expose their coin holdings, nor -cause them to maintain access to secret keys for much longer than they would -otherwise. (This rules out some forms of voting, and of disbursing coins to -past/future miners.) - -The Dev Fund system should be simple to understand and realistic to -implement. In particular, it should not assume the creation of new mechanisms -(e.g., election systems) or entities (for governance or development) for its -execution; but it should strive to support and use these once they are built. - -Dev Fund recipients should comply with legal, regulatory, and taxation -constraints in their pertinent jurisdiction(s). - - -Non-requirements -================ - -General on-chain governance is outside the scope of this proposal. - -Rigorous voting mechanisms (whether coin-weighted, holding-time-weighted or -one-person-one-vote) are outside the scope of this proposal, however this -proposal does mandate the undertaking of the project to build a "non-direct -funding model" as generally described in [#draft-swihart]_. - -Specification -============= - -Consensus changes implied by this specification are applicable to the -Zcash Mainnet. Similar (but not necessarily identical) consensus changes -SHOULD be applied to the Zcash Testnet for testing purposes. - - -Dev Fund allocation -------------------- - -Starting at the second Zcash halving in 2024, until the third halving in 2028, -15% of the block subsidy of each block SHALL be allocated to a "Dev Fund" that -consists of the following allocations: - -* 5% for the Zcash Foundation (for internal work and grants); -* 4% for the Bootstrap Project (the parent of the Electric Coin Company) for the 1st year only; -* 4% for Zcash Community Grants for continuation of their current activities as-is; -* 2% for Qedit in support of their ZSA activities, and other Zcash protocol support; - -Following the first year, when ECC will no longer receive their 4% allocation, -those block subsidies will be distributed as 1% to ZCG, 1% to ZecHub, 1% to FPF, -and 1% to ZF. - -This proposal mandates the ecosystem to design and deploy a "non-direct funding model" -as generally recommended in Josh Swihart's proposal [#draft-swihart]_. - -"Dev Fund" block subsidies will be administered through two organizations: - -1. Zcash Foundation (✳️ for ECC, ZCG) -2. Financial Privacy Foundation (✳️ for Qedit, ZecHub) - -✳️ **ZF and FPF adminstration of block subsidy details, costs, et al are currently under debate** -[#zf-fpf-admin-details]_ - -The allocations are described in more detail below. The fund flow will be implemented -at the consensus-rule layer, by sending the corresponding ZEC to the designated -address(es) for each block. This Dev Fund will end at the third halving (unless -extended/modified by a future ZIP). - - -BP allocation (Bootstrap Project) -~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ - -✳️ These funds SHALL be received and administered by ZF. - -This allocation of the Dev Fund will flow as charitable contributions from -the Zcash Community to the Bootstrap Project, the newly formed parent -organization to the Electric Coin Company. The Bootstrap Project is organized -for exempt educational, charitable, and scientific purposes in -compliance with Section 501(c)(3), including but not -limited to furthering education, information, resources, advocacy, -support, community, and research relating to cryptocurrency and -privacy, including Zcash. This allocation will be used at the discretion of -the Bootstrap Project for any purpose within its mandate to support financial -privacy and the Zcash platform as permitted under Section 501(c)(3). The -BP allocation will be treated as a charitable contribution from the -Community to support these educational, charitable, and scientific -purposes. - - -ZF allocation (Zcash Foundation's general use) -~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ - -This allocation of the Dev Fund will flow as charitable contributions from -the Zcash Community to ZF, to be used at its discretion for any -purpose within its mandate to support financial privacy and the Zcash -platform, including: development, education, supporting community -communication online and via events, gathering community sentiment, -and awarding external grants for all of the above, subject to the -requirements of Section 501(c)(3). The ZF allocation will be -treated as a charitable contribution from the Community to support -these educational, charitable, and scientific purposes. - - -Zcash Community Grants (ZCG) -~~~~~~~~~~~~~~~~~~~~~~~~~~~~ - -This allocation of the Dev Fund is intended to fund independent teams entering the -Zcash ecosystem, to perform major and minor ongoing development (or other work) for the -public good of the Zcash ecosystem, to the extent that such teams are available -and effective. - -✳️ These funds SHALL be received and administered by ZF (or FPF, pending TBD outcomes -of FPF proposal: [#zf-fpf-admin-details]_). -ZF MUST disburse them for "Major Grants" and expenses reasonably related to -the administration of Major Grants, but subject to the following additional constraints: - -1. These funds MUST only be used to issue Major Grants to external parties - that are independent of ZF, and to pay for expenses reasonably related to - the administration of Major Grants. They MUST NOT be used by ZF for its - internal operations and direct expenses not related to administration of - Major Grants. Additionally, BP, ECC, and ZF are ineligible to receive - Major Grants. - -2. Major Grants SHOULD support well-specified work proposed by the grantee, - at reasonable market-rate costs. They can be of any duration or ongoing - without a duration limit. Grants of indefinite duration SHOULD have - semiannual review points for continuation of funding. - -3. Priority SHOULD be given to Major Grants that bolster teams with - substantial (current or prospective) continual existence, and set them up - for long-term success, subject to the usual grant award considerations - (impact, ability, risks, team, cost-effectiveness, etc.). Priority SHOULD be - given to Major Grants that support ecosystem growth, for example through - mentorship, coaching, technical resources, creating entrepreneurial - opportunities, etc. If one proposal substantially duplicates another's - plans, priority SHOULD be given to the originator of the plans. - -4. Major Grants SHOULD be restricted to furthering the Zcash cryptocurrency and - its ecosystem (which is more specific than furthering financial privacy in - general) as permitted under Section 501(c)(3). - -5. Major Grants awards are subject to approval by a five-seat Major Grant - Review Committee. The Major Grant Review Committee SHALL be selected by the - ZF's Community Advisory Panel or successor process. - -6. The Major Grant Review Committee's funding decisions will be final, requiring - no approval from the ZF Board, but are subject to veto if the Foundation - judges them to violate U.S. law or the ZF's reporting requirements and other - (current or future) obligations under U.S. IRS 501(c)(3). - -7. Major Grant Review Committee members SHALL have a one-year term and MAY sit - for reelection. The Major Grant Review Committee is subject to the same - conflict of interest policy that governs the ZF Board of Directors (i.e. they - MUST recuse themselves when voting on proposals where they have a financial - interest). At most one person with association with the BP/ECC, and at most - one person with association with the ZF, are allowed to sit on the Major - Grant Review Committee. "Association" here means: having a financial - interest, full-time employment, being an officer, being a director, or having - an immediate family relationship with any of the above. The ZF SHALL continue - to operate the Community Advisory Panel and SHOULD work toward making it more - representative and independent (more on that below). - -8. From 1st January 2022, a portion of the MG allocation shall be allocated to a - Discretionary Budget, which may be disbursed for expenses reasonably related - to the administration of Major Grants. The amount of funds allocated to the - Discretionary Budget SHALL be decided by the ZF's Community Advisory Panel or - successor process. Any disbursement of funds from the Discretionary Budget - MUST be approved by the Major Grant Review Committee. Expenses related to the - administration of Major Grants include, without limitation the following: - - * Paying third party vendors for services related to domain name registration, or - the design, website hosting and administration of websites for the Major Grant - Review Committee. - * Paying independent consultants to develop requests for proposals that align - with the Major Grants program. - * Paying independent consultants for expert review of grant applications. - * Paying for sales and marketing services to promote the Major Grants - program. - * Paying third party consultants to undertake activities that support the - purpose of the Major Grants program. - * Reimbursement to members of the Major Grant Review Committee for reasonable - travel expenses, including transportation, hotel and meals allowance. - - The Major Grant Review Committee's decisions relating to the allocation and - disbursement of funds from the Discretionary Budget will be final, requiring - no approval from the ZF Board, but are subject to veto if the Foundation - judges them to violate U.S. law or the ZF's reporting requirements and other - (current or future) obligations under U.S. IRS 501(c)(3). - -ZF SHALL recognize the MG allocation of the Dev Fund as a Restricted Fund -donation under the above constraints (suitably formalized), and keep separate -accounting of its balance and usage under its `Transparency and Accountability`_ -obligations defined below. - -ZF SHALL strive to define target metrics and key performance indicators, -and the Major Grant Review Committee SHOULD utilize these in its funding -decisions. - - -Qedit -~~~~~ - -✳️ These funds SHALL be received and administered by FPF. - -This allocation of the Dev Fund will flow as charitable contributions from -the Zcash Community to Qedit, for the purposes of supporting their ongoing -activities related to Zcash Shielded Assets, and related protocol/ application/ -legal/ and other efforts. - -ZecHub -~~~~~~ - -✳️ These funds SHALL be received and administered by FPF. - -This allocation of the Dev Fund will flow as charitable contributions from -the Zcash Community to ZecHub, for the purposes of continuing their -ongoing content contributions, community organizing, et al within the -Zcash ecosystem. - - -Transparency and Accountability -------------------------------- - -Obligations -~~~~~~~~~~~ - -BP, ECC, ZF, ZCG, Qedit, FPF and ZecHub are recommended to accept the obligations in this section. - -Ongoing public reporting requirements: - -* Quarterly reports, detailing future plans, execution on previous plans, and - finances (balances, and spending broken down by major categories). -* Monthly developer calls, or a brief report, on recent and forthcoming tasks. - (Developer calls may be shared.) -* Annual detailed review of the organization performance and future plans. -* Annual financial report (IRS Form 990, or substantially similar information). - -These reports may be either organization-wide, or restricted to the income, -expenses, and work associated with the receipt of Dev Fund. -As BP is the parent organization of ECC it is expected they may publish -joint reports. - -It is expected that ECC, ZF, and ZCG will be focused -primarily (in their attention and resources) on Zcash. Thus, they MUST -promptly disclose: - -* Any major activity they perform (even if not supported by the Dev Fund) that - is not in the interest of the general Zcash ecosystem. -* Any conflict of interest with the general success of the Zcash ecosystem. - -BP, ECC, ZF, and grant recipients MUST promptly disclose any security or privacy -risks that may affect users of Zcash (by responsible disclosure under -confidence to the pertinent developers, where applicable). - -BP's reports, ECC's reports, and ZF's annual report on its non-grant operations, -SHOULD be at least as detailed as grant proposals/reports submitted by other -funded parties, and satisfy similar levels of public scrutiny. - -All substantial software whose development was funded by the Dev Fund SHOULD -be released under an Open Source license (as defined by the Open Source -Initiative [#osd]_), preferably the MIT license. - - -Enforcement -~~~~~~~~~~~ - -For grant recipients, these conditions SHOULD be included in their contract -with ZF, such that substantial violation, not promptly remedied, will cause -forfeiture of their grant funds and their return to ZF. - -BP, ECC, and ZF MUST contractually commit to each other to fulfill these -conditions, and the prescribed use of funds, such that substantial violation, -not promptly remedied, will permit the other party to issue a modified version -of Zcash node software that removes the violating party's Dev Fund allocation, and -use the Zcash trademark for this modified version. The allocation's funds will be -reassigned to MG (whose integrity is legally protected by the Restricted -Fund treatment). - - -Future Community Governance ---------------------------- - -It is highly desirable to develop robust means of decentralized community -voting and governance –either by expanding the Zcash Community Advisory Panel or a -successor mechanism– and to integrate them into this process by the end of -2025. BP, ECC, ZCG, and ZF SHOULD place high priority on such development and its -deployment, in their activities and grant selection. - - -ZF Board Composition --------------------- - -Members of ZF's Board of Directors MUST NOT hold equity in ECC or have current -business or employment relationships with ECC, except as provided for by the -grace period described below. - -Grace period: members of the ZF board who hold ECC equity (but do not have other -current relationships to ECC) may dispose of their equity, or quit the Board, -by 21 November 2024. (The grace period is to allow for orderly replacement, and -also to allow time for ECC corporate reorganization related to Dev Fund -receipt, which may affect how disposition of equity would be executed.) - -The Zcash Foundation SHOULD endeavor to use the Community Advisory Panel (or -successor mechanism) as advisory input for future board elections. - - -Acknowledgements -================ - -This proposal is a modification of ZIP 1014 [#zip-1014]_ -and a modification from the original "Manufacturing Consent" proposal -as described in the Zcash Forum, in response to observable Zcash -community sentiment. - -The author is grateful to everyone in the Zcash ecosystem. - - -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 2021.2.16 or later `_ -.. [#protocol-networks] `Zcash Protocol Specification, Version 2021.2.16. Section 3.12: Mainnet and Testnet `_ -.. [#trademark] `Zcash Trademark Donation and License Agreement `_ -.. [#osd] `The Open Source Definition `_ -.. [#zip-0200] `ZIP 200: Network Upgrade Mechanism `_ -.. [#zip-1003] `ZIP 1003: 20% Split Evenly Between the ECC and the Zcash Foundation, and a Voting System Mandate `_ -.. [#zip-1010] `ZIP 1010: Compromise Dev Fund Proposal With Diverse Funding Streams `_ -.. [#zip-1011] `ZIP 1011: Decentralize the Dev Fee `_ -.. [#zip-1014] `ZIP 1012: Dev Fund to ECC + ZF + Major Grants `_ -.. [#zf-community] `ZF Community Advisory Panel `_ -.. [#section501c3] `U.S. Code, Title 26, Section 501(c)(3) `_ -.. [#draft-swihart] `Zcash Funding Bloc : A Dev Fund Proposal from Josh at ECC `_ -.. [#zf-fpf-admin-details] `Proposal: ZCG under FPF `_ diff --git a/zips/draft-nuttycom-funding-allocation.rst b/zips/draft-nuttycom-funding-allocation.rst deleted file mode 100644 index 81cd398f2..000000000 --- a/zips/draft-nuttycom-funding-allocation.rst +++ /dev/null @@ -1,611 +0,0 @@ -:: - - ZIP: Unassigned - Title: Block Reward Allocation for Non-Direct Development Funding - Owners: Kris Nuttycombe - Jason McGee - Original-Authors: Skylar Saveland - Credits: Daira-Emma Hopwood - Jack Grigg - @Peacemonger (Zcash Forum) - Status: Withdrawn - Category: Consensus - Created: 2024-07-03 - License: MIT - Pull-Request: - -Terminology -=========== - -The key words "MUST", "REQUIRED", "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. - -Abstract -======== - -This ZIP proposes several options for the allocation of a percentage of the -Zcash block subsidy, post-November 2024 halving, to an in-protocol "lockbox." -The "lockbox" will be a separate pool of issued funds tracked by the protocol, -as described in ZIP 2001: Lockbox Funding Streams -[#zip-2001]_. No disbursement mechanism is currently defined -for this "lockbox"; the Zcash community will need to decide upon and specify a -suitable decentralized mechanism for permitting withdrawals from this lockbox -in a future ZIP in order to make these funds available for funding grants to -ecosystem participants. - -The proposed lockbox addresses significant issues observed with ZIP 1014 -[#zip-1014]_, 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, by default 100% of the -block subsidies will be allocated to miners, and no further funds will 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 will 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: - -1. **Regulatory Risks**: The current model involves direct funding of US-based - organizations, which can potentially attract regulatory scrutiny from - entities such as the SEC, posing legal risks to the Zcash ecosystem. - -2. **Funding Inefficiencies**: The current model directly funds organizations - rather than specific projects, leading to a potential mismatch between those - organizations' development priorities and the priorities of the community. - Furthermore, if organizations are guaranteed funds regardless of - performance, there is little incentive to achieve key performance indicators - (KPIs) or align with community sentiment. A future system that allocates - resources directly to projects rather than organizations may help reduce - inefficiencies and better align development efforts with community - priorities. - -3. **Centralization Concerns**: The current model centralizes decision-making - power within a few organizations, contradicting the decentralized ethos of - blockchain technology. Traditional organizational structures with boards and - executives introduce single points of failure and limit community - involvement in funding decisions. - -4. **Community Involvement**: The current system provides minimal formal input - from the community regarding what projects should be funded, leading to a - misalignment between funded projects and community priorities. - -5. **Moving Towards a Non-Direct Funding Model**: There is strong community - support for a non-direct Dev Fund funding model. Allocating funds to a - Deferred Dev Fund Lockbox incentivizes the development of a decentralized - mechanism for the disbursement of the locked funds. - -By addressing these issues, this proposal aims to ensure sustainable, -efficient, and decentralized funding for essential activities within the Zcash -ecosystem. - -Requirements -============ - -1. **In-Protocol Lockbox**: The alternatives presented in this ZIP depend upon - the Lockbox Funding Streams proposal [#zip-2001]_. - -2. **Regulatory Considerations**: The allocation of funds should minimize - regulatory risks by avoiding direct funding of specific organizations. The - design should enable and encourage compliance with applicable laws and regulations to - support the long-term sustainability of the funding model. - -Non-requirements -================ - -The following considerations are explicitly deferred to future ZIPs and are not -covered by this proposal: - -1. **Disbursement Mechanism**: The exact method for disbursing the accumulated - funds from the lockbox is not defined in this ZIP. The design, - implementation, and governance of the disbursement mechanism will be - addressed in a future ZIP. This includes specifics on how funds will be - allocated, the voting or decision-making process, and the structure of the - decentralized mechanism (such as a DAO). - -2. **Regulatory Compliance Details**: The proposal outlines the potential to - reduce regulatory risks by avoiding direct funding of US-based - organizations, but it does not detail specific regulatory compliance - strategies. Future ZIPs will need to address how the disbursement mechanism - complies with applicable laws and regulations. - -3. **Impact Assessment**: The long-term impact of reallocating a portion of the - block subsidy to the lockbox on the Zcash ecosystem, including its effect on - miners, developers, and the broader community, is not analyzed in this ZIP. - Subsequent proposals will need to evaluate the outcomes and make necessary - adjustments based on real-world feedback and data. - -Specification -============= - -The following alternatives all depend upon the Lockbox Funding Streams proposal -[#zip-2001]_ for storage of funds into a deferred value -pool. - -Some of the alternatives described below do not specify a termination height -for the funding streams they propose. In these cases, the termination height -is set to `u32::MAX_VALUE`. A future network upgrade that alters the -maximum possible block height MUST also alter these termination heights. - -Alternatives -============ - -Alternative 1: Lockbox For Decentralized Grants Allocation (perpetual 50% option) ---------------------------------------------------------------------------------- - -Proposed by Skylar Saveland - -* 50% of the block subsidy is to be distributed to the lockbox. - -As of block height 2726400, and continuing until modified by a future ZIP, the -complete set of funding streams will be: - -================= =========== ============= ============== ============ - Stream Numerator Denominator Start height End height -================= =========== ============= ============== ============ -``FS_DEFERRED`` 50 100 2726400 u32::MAX -================= =========== ============= ============== ============ - -Motivations for Alternative 1 -''''''''''''''''''''''''''''' - -This alternative proposes allocating a significantly larger portion of the block -subsidy to development funding than is currently allocated, aiming to establish -a long-term source of funding for protocol improvements. The disbursement of -these funds will be governed by a mechanism to be determined by the community -in the future, ensuring that the funds are released under agreed-upon constraints -to maintain availability for years to come. - -The proposed lockbox funding model for Zcash's post-NU6 halving period allocates -50% of the block reward to a deferred reserve, or "lockbox," designated for -future decentralized grants funding. This approach is designed to address several -critical motivations: - -.. Note: some of these are similar to the general motivations. - -1. **Regulatory Compliance**: - - - **Reduction of Regulatory Risks**: Direct funding to legal entities poses - significant regulatory risks. Allocating funds to a decentralized lockbox - mitigates these risks by avoiding direct funding of any specific - organizations. This alternative represents the strongest regulatory - posture, as it reduces the likelihood of legal challenges associated with - funding centralized entities directly. - - - **Potential Minimization of KYC Requirements**: The current funding - mechanism involves 100% KYC for recipients, which can be detrimental to - security, privacy, resilience, and participation. A sufficiently - decentralized disbursement mechanism could reduce the need for recipients - to undergo KYC with a controlling entity. This would preserve privacy and - encourage broader participation from developers and contributors who value - anonymity and privacy. By shifting from direct funding of specific legal - entities to a decentralized funding model, we create a more secure, - private, and resilient ecosystem. This potential future difference - enhances the robustness of the Zcash network by fostering a diverse and - engaged community without the constraints of centralized direct funding. - -2. **Ensuring Sustainable Development Funding**: - - - **Need for Continuous Funding**: Zcash has numerous ongoing and future - projects essential for its ecosystem's growth and security. Without a - change, the expiration of the devfund will result in 100% of the block - reward going to miners, jeopardizing funding for development. The proposed - 50% lockbox allocation ensures that funds are directed towards sustaining - and improving the Zcash ecosystem through a wide array of initiatives. - These include protocol development, new features, security audits, legal - support, marketing, ZSAs (Zcash Shielded Assets), stablecoins, - programmability, transitioning to a modern Rust codebase, wallets, - integrations with third-party services, improved node software, block - explorers, supporting ambassadors, and educational initiatives like - ZecHub. - - - **Balanced Incentives for Network and Protocol Security**: While miners - have been essential in providing network security through hashpower, - allocating 100% of the block reward to mining alone overlooks the crucial - need for development, innovation, and protocol security. By investing in - these priorities, we enhance the long-term health and value of the - protocol, which ultimately benefits miners. A well-maintained and - innovative protocol increases the overall value of the network, making - miners' rewards more valuable. This balanced approach aligns the interests - of miners with the broader community, ensuring sustainable growth and - security for Zcash. - -3. **Efficiency, Accountability, and Decentralization**: - - - **Reduction of Inefficiencies**: Traditional funding models often involve - significant corporate overhead and centralized decision-making, leading to - inefficiencies. The prior model provided two 501(c)(3) organizations with - constant funding for four years, which reduced accountability and allowed - for potential misalignment with the community's evolving priorities. By - funding projects directly rather than organizations, we can allocate - resources more efficiently, ensuring that funds are used for tangible - development rather than administrative costs. This approach minimizes the - influence of corporate executives, whose decisions have sometimes failed - to address critical issues promptly. - - - **Increased Accountability**: A presumed grants-only mechanism, to be - defined in a future ZIP, would necessitate continuous accountability and - progress for continuous funding. Unlike the prior model, where - organizations received guaranteed funding regardless of performance, a - grants-based approach would require projects to demonstrate ongoing - success and alignment with community goals to secure funding. This - continuous evaluation fosters a more responsive and responsible allocation - of resources, ensuring that funds are directed towards initiatives that - provide the most value to the Zcash ecosystem. By increasing - accountability, this model promotes a culture of excellence and - innovation, driving sustained improvements and advancements in the - protocol. - - - **Promotion of Decentralization**: The proposed non-direct funding model - stores deferred funds for future use, with the specifics of the - disbursement mechanism to be determined by a future ZIP. This could allow - the community to have a greater influence over funding decisions, aligning - more closely with the ethos of the Zcash project. By decentralizing the - allocation process, this approach has the potential to foster innovation - and community involvement, ensuring that development priorities are more - reflective of the community's needs and desires, promoting a more open, - transparent, and resilient ecosystem. - -4. **Incentives for Development and Collaboration**: - - - **Creating a Strong Incentive to Implement the Disbursement Mechanism**: - Allocating 50% of the block reward to the lockbox indefinitely creates - a powerful incentive for the community to work together to implement the - disbursement mechanism without delay. Knowing that there is a substantial - amount of funds available, stakeholders will be motivated to develop and - agree on an effective, decentralized method for distributing these funds. - - - **Incentivizing Continuous Improvements**: The accumulation of a large - stored fortune within the lockbox incentivizes continuous improvements - to the Zcash protocol and ecosystem. Developers, contributors, and - community members will be driven to propose and execute projects that - enhance the network, knowing that successful initiatives have the - potential to receive funding. This model fosters a culture of ongoing - innovation and development, ensuring that Zcash remains at the forefront - of blockchain technology. - - - **Aligning Long-Term Interests**: By tying a significant portion of the - block reward to future decentralized grants funding, the model aligns - the long-term interests of all stakeholders. Miners, developers, and - community members alike have a vested interest in maintaining and - improving the Zcash network, as the value and success of their efforts - are directly linked to the availability and effective use of the lockbox - funds. This alignment of incentives ensures that the collective efforts - of the community are focused on the sustainable growth and advancement - of the Zcash ecosystem. - -Guidance on Future Requirements for Alternative 1 -''''''''''''''''''''''''''''''''''''''''''''''''' - -To support the motivations outlined, the following guidance is proposed for -Alternative 1. Future ZIP(s) will define the disbursement mechanism. These are -suggestions to achieve the outlined motivations and should be considered in -those future ZIP(s). It is important to note that these are ideas and guidance, -not hard, enforceable requirements: - -1. **Cap on Grants**: Grants should be capped to promote more granular - accountability and incremental goal-setting. This approach ensures that - projects are required to define their work, goals, milestones, KPIs, and - achievements in smaller, more manageable increments. Even if a single - project is utilizing significant funds quickly, the cap ensures that - progress is continuously evaluated and approved based on tangible results - and alignment with community priorities. - -2. **Decentralized Disbursement Mechanism**: The disbursement mechanism should - be sufficiently decentralized to ensure the regulatory motivations are - fulfilled. A decentralized mechanism could reduce the need for recipients to - undergo KYC with a controlling party, preserving privacy and aligning with - the ethos of the Zcash project. - -3. **Governance and Accountability**: The governance structure for the - disbursement mechanism should be open and accountable, with decisions made - through community consensus or decentralized voting processes to maintain - trust and accountability. This approach will help ensure that the allocation - of funds is fair and aligned with the community's evolving priorities. - -4. **Periodic Review and Adjustment**: There should be provisions for periodic - review and adjustment of the funding mechanism to address any emerging - issues or inefficiencies and to adapt to the evolving needs of the Zcash - ecosystem. This could include the ability to add or remove participants as - necessary. Regular assessments will help keep the funding model responsive - and effective, ensuring it continues to meet the community's goals. - -By addressing these motivations and providing this guidance, Alternative 1 aims -to provide a robust, sustainable, and decentralized funding model that aligns -with the principles and long-term goals of the Zcash community. - -Alternative 2: Hybrid Deferred Dev Fund: Transitioning to a Non-Direct Funding Model ------------------------------------------------------------------------------------- - -Proposed by Jason McGee, Peacemonger, GGuy - -* 12% of the block subsidy is to be distributed to the lockbox. -* 8% of the block subsidy is to be distributed to the Financial Privacy - Foundation (FPF), for the express use of the Zcash Community Grants Committee - (ZCG) to fund independent teams in the Zcash ecosystem. - -As of block height 2726400, and continuing for one year, the complete set of -funding streams will be: - -================= =========== ============= ============== ============ - Stream Numerator Denominator Start height End height -================= =========== ============= ============== ============ -``FS_DEFERRED`` 12 100 2726400 3146400 -``FS_FPF_ZCG`` 8 100 2726400 3146400 -================= =========== ============= ============== ============ - -Motivations for Alternative 2 -''''''''''''''''''''''''''''' - -* **Limited Runway**: ZCG does not have the financial runway that ECC/BP and ZF - have. As such, allocating ongoing funding to ZCG will help ensure the Zcash - ecosystem has an active grants program. - -* **Promoting Decentralization**: Allocating a portion of the Dev Fund to Zcash - Community Grants ensures small teams continue to receive funding to - contribute to Zcash. Allowing the Dev Fund to expire, or putting 100% into a - lockbox, would disproportionally impact grant recipients. This hybrid - approach promotes decentralization and the growth of independent development - teams. - -* **Mitigating Regulatory Risks**: The Financial Privacy Foundation (FPF) is a - non-profit organization incorporated and based in the Cayman Islands. By - minimizing direct funding of US-based organizations, this proposal helps to - reduce potential regulatory scrutiny and legal risks. - -Alternative 3: Lockbox For Decentralized Grants Allocation (20% option) ------------------------------------------------------------------------ - -Proposed by Kris Nuttycombe - -* 20% of the block subsidy is to be distributed to the lockbox. - -As of block height 2726400, and continuing for two years, the complete set of -funding streams will be: - -================= =========== ============= ============== ============ - Stream Numerator Denominator Start height End height -================= =========== ============= ============== ============ -``FS_DEFERRED`` 20 100 2726400 3566400 -================= =========== ============= ============== ============ - -Motivations for Alternative 3 -''''''''''''''''''''''''''''' - -This alternative is presented as the simplest allocation of block rewards -to a lockbox for future disbursement that is consistent with results of -community polling. - -Alternative 4: Masters Of The Universe? ---------------------------------------- - -Proposed by NoamChom (Zcash forum) - -* 17% of the block subsidy is to be distributed to the lockbox. -* 8% of the block subsidy is to be distributed to the Financial Privacy - Foundation (FPF), for the express use of the Zcash Community Grants Committee - (ZCG) to fund independent teams in the Zcash ecosystem. - -As of block height 2726400, and continuing for four years, the complete set of -funding streams will be: - -================= =========== ============= ============== ============ - Stream Numerator Denominator Start height End height -================= =========== ============= ============== ============ -``FS_DEFERRED`` 17 100 2726400 4406400 -``FS_FPF_ZCG`` 8 100 2726400 4406400 -================= =========== ============= ============== ============ - -Motivations for Alternative 4 -''''''''''''''''''''''''''''' - -This alternative proposes a slightly larger slice of the block subsidy than is -currently allocated for development funding, in order to better provide for the -needs of the Zcash community. - - -Revisitation Requirement for Alternative 4 -'''''''''''''''''''''''''''''''''''''''''' - -The terms for this Alternative should be revisited by the Zcash ecosystem upon -creation/ activation of a "non-direct funding model" (NDFM). At that completion -of an NDFM which accessess the lockbox funds, this ZIP should be reconsidered -(potentially terminated) by the Zcash ecosystem, to determine if its ongoing -direct block subsidies are preferred for continuation. Discussions / solications -/ sentiment gathering from the Zcash ecosystem should be initiated ~6 months in -advance of the presumed activation of a "non-direct funding model", such that -the Zcash ecosystem preference can be expediently realized. - - -Requirements related to direct streams for the Financial Privacy Foundation -=========================================================================== - -The following requirements apply to Alternative 2 and Alternative 4: - -The stream allocated to Zcash Community Grants (ZCG) is intended to fund -independent teams entering the Zcash ecosystem, to perform major ongoing -development (or other work) for the public good of the Zcash ecosystem, to the -extent that such teams are available and effective. The ZCG Committee is given -the discretion to allocate funds not only to major grants, but also to a -diverse range of projects that advance the usability, security, privacy, and -adoption of Zcash, including community programs, dedicated resources, and other -projects of varying sizes. - -The funds SHALL be received and administered by the -Financial Privacy Foundation (FPF). FPF MUST disburse them for grants and -expenses reasonably related to the administration of the ZCG program, but -subject to the following additional constraints: - -1. These funds MUST only be used to issue grants to external parties that are - independent of FPF, and to pay for expenses reasonably related to the - administration of the ZCG program. They MUST NOT be used by FPF for - its internal operations and direct expenses not related to the - administration of grants or the grants program. - -2. ZCG SHOULD support well-specified work proposed by the grantee, at - reasonable market-rate costs. They can be of any duration or ongoing without - a duration limit. Grants of indefinite duration SHOULD have semiannual - review points for continuation of funding. - -3. Priority SHOULD be given to major grants that bolster teams with substantial - (current or prospective) continual existence, and set them up for long-term - success, subject to the usual grant award considerations (impact, ability, - risks, team, cost-effectiveness, etc.). Priority SHOULD be given to major - grants that support ecosystem growth, for example through mentorship, - coaching, technical resources, creating entrepreneurial opportunities, etc. - If one proposal substantially duplicates another’s plans, priority SHOULD be - given to the originator of the plans. - -4. The ZCG committee SHOULD be restricted to funding projects that further the - Zcash cryptocurrency and its ecosystem (which is more specific than - furthering financial privacy in general) as permitted by FPF - and any relevant jurisdictional requirements. - -5. ZCG awards are subject to approval by a five-seat ZCG Committee. The ZCG - Committee SHALL be selected by the ZF’s Community Advisory Panel or a - successor process (e.g. as established by FPF). Elections SHALL be staggered - to ensure continuity within the Committee. - -6. The ZCG Committee’s funding decisions will be final, requiring no approval - from the FPF Board, but are subject to veto if the FPF judges them to - violate any relevant laws or other (current or future) obligations. - -7. ZCG Committee members SHALL have a one-year term and MAY sit for reelection. - The ZCG Committee is subject to the same conflict of interest policy that - governs the FPF Board of Directors (i.e. they MUST recuse themselves when - voting on proposals where they have a financial interest). At most one - person with association with the BP/ECC, at most one person with - association with the ZF, and at most one person with association with FPF - are allowed to sit on the ZCG Committee. - “Association” here means: having a financial interest, full-time employment, - being an officer, being a director, or having an immediate family - relationship with any of the above. The ZF SHALL continue to operate the - Community Advisory Panel and SHOULD work toward making it more - representative and independent (more on that below). Similarly, FPF should - also endeavor to establish its own means of collecting community sentiment - for the purpose of administering ZCG elections. - -8. A portion of the ZCG Slice shall be allocated to a Discretionary Budget, - which may be disbursed for expenses reasonably related to the administration - of the ZCG program. The amount of funds allocated to the Discretionary - Budget SHALL be decided by the ZF’s Community Advisory Panel or successor - process. Any disbursement of funds from the Discretionary Budget MUST be - approved by the ZCG Committee. Expenses related to the administration of the - ZCG program include, without limitation the following: - - * Paying third party vendors for services related to domain name - registration, or the design, website hosting and administration of - websites for the ZCG Committee. - * Paying independent consultants to develop requests for proposals that - align with the ZCG program. - * Paying independent consultants for expert review of grant applications. - * Paying for sales and marketing services to promote the ZCG program. - * Paying third party consultants to undertake activities that support the - purpose of the ZCG program. - * Reimbursement to members of the ZCG Committee for reasonable travel - expenses, including transportation, hotel and meals allowance. - -9. A portion of the Discretionary Budget MAY be allocated to provide reasonable - compensation to members of the ZCG Committee. Committee member compensation - SHALL be limited to the hours needed to successfully perform their positions - and MUST align with the scope and responsibilities of their roles. The - allocation and distribution of compensation to committee members SHALL be - administered by the FPF. The compensation rate and hours for committee - members SHALL be determined by the ZF’s Community Advisory Panel or - successor process. - -10. The ZCG Committee’s decisions relating to the allocation and disbursement - of funds from the Discretionary Budget will be final, requiring no approval - from the FPF Board, but are subject to veto if the FPF judges - them to violate laws or FPF reporting requirements and other - (current or future) obligations. - -FPF SHALL recognize the ZCG slice of the Dev Fund as a Restricted Fund -donation under the above constraints (suitably formalized), and keep separate -accounting of its balance and usage under its Transparency and Accountability -obligations defined below. - -FPF SHALL strive to define target metrics and key performance indicators, -and the ZCG Committee SHOULD utilize these in its funding decisions. - -Furthering Decentralization ---------------------------- - -FPF SHALL conduct periodic reviews of the -organizational structure, performance, and effectiveness of the ZCG program and -committee, taking into consideration the input and recommendations of the ZCG -Committee. As part of these periodic reviews, FPF MUST commit to -exploring the possibility of transitioning ZCG into an independent organization -if it is economically viable and it aligns with the interests of the Zcash -ecosystem and prevailing community sentiment. - -In any transition toward independence, priority SHALL be given to maintaining -or enhancing the decentralization of the Zcash ecosystem. The newly formed -independent organization MUST ensure that decision-making processes remain -community-driven, transparent, and responsive to the evolving needs of the -Zcash community and ecosystem. In order to promote geographic decentralization, -the new organization SHOULD establish its domicile outside of the United -States. - -Transparency and Accountability -------------------------------- - -FPF MUST accept the following obligations in this section on behalf of ZCG: - -* Publication of the ZCG Dashboard, providing a snapshot of ZCG’s current - financials and any disbursements made to grantees. -* Bi-weekly meeting minutes documenting the decisions made by the ZCG committee - on grants. -* Quarterly reports, detailing future plans, execution on previous plans, and - finances (balances, and spending broken down by major categories). -* Annual detailed review of the organization performance and future plans. -* Annual financial report (IRS Form 990, or substantially similar information). - -BP, ECC, ZF, FPF, ZCG and grant recipients MUST promptly disclose any security -or privacy risks that may affect users of Zcash (by responsible disclosure -under confidence to the pertinent developers, where applicable). - -All substantial software whose development was funded by the Dev Fund SHOULD be -released under an Open Source license (as defined by the Open Source Initiative -[#osd]_), preferably the MIT license. - -Enforcement ------------ - -FPF MUST contractually commit to fulfill these obligations on behalf of -ZCG, and the prescribed use of funds, such that substantial violation, not -promptly remedied, will result in a modified version of Zcash node software -that removes ZCG’s Dev Fund slice and allocates it to the Deferred Dev Fund -lockbox. - -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" `_ -.. [#osd] `The Open Source Definition `_ -.. [#zip-1014] `ZIP 1014: Dev Fund Proposal and Governance `_ -.. [#zip-2001] `ZIP 2001: Lockbox Funding Streams `_ diff --git a/zips/draft-shieldedlabs-crosslink-construction.rst b/zips/draft-shieldedlabs-crosslink-construction.rst new file mode 100644 index 000000000..5b9fd3938 --- /dev/null +++ b/zips/draft-shieldedlabs-crosslink-construction.rst @@ -0,0 +1,646 @@ +:: + + ZIP: Unassigned {numbers are assigned by ZIP editors} + Title: CCC-SL: Crosslink Consensus Construction from Shielded Labs + Owners: Nate Wilcox + Credits: Daira-Emma Hopwood + Jack Grigg + Kris Nuttycombe + Status: Draft + Category: Consensus + Created: 2026-04-08 + License: MIT + Discussions-To: TBD (no specific discussion thread yet) + + +Terminology +=========== + +The key words "MUST", "MUST NOT", "SHOULD", "SHOULD NOT", 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 terms "Mainnet" and "Testnet" in this document are to be interpreted as +defined in the Zcash protocol specification [#protocol-networks]_. + +The terms below are to be interpreted as follows: + +CCC-SL (Crosslink Consensus Construction from Shielded Labs) + The hybrid consensus construction specified by this ZIP, integrating the + Zcash PoW best-chain protocol with ``CFP-SL`` to produce a protocol with + both availability and Crosslink Finality. CCC-SL is the core of Shielded + Labs Crosslink v1 and is closely based on CCC-TFLv2 from the TFL book + [#tfl-book]_. + +CCC-TFLv2 (Crosslink Consensus Construction from the TFL Book, version 2) + The abstract hybrid consensus construction documented in the Zcash TFL book + [#tfl-book]_. CCC-SL is the Shielded Labs adaptation and extension of this + construction for the Zcash PoW+TFL deployment. + +CFP-SL (Crosslink Finalization Protocol from Shielded Labs) + The BFT Proof-of-Stake finalization protocol used as the BFT subprotocol + within CCC-SL. CFP-SL satisfies the interface requirements (``Final + Agreement`` and related properties) defined in this ZIP. + +Best-chain subprotocol (Π\ :sub:`bc`) + The Zcash Proof-of-Work best-chain protocol, modified by CCC-SL to + participate in the hybrid construction. Blocks in this protocol are called + "bc-blocks" and chains are "bc-chains". + +Original best-chain subprotocol (Π\ :sub:`origbc`) + The "off-the-shelf" PoW best-chain protocol before CCC-SL modifications. + For the Zcash deployment, this corresponds to the Zcash NU5/NU6 consensus + protocol. + +BFT subprotocol (Π\ :sub:`bft`) + The BFT protocol (instantiated by ``CFP-SL``) modified to participate in + CCC-SL. Blocks in this protocol are called "bft-blocks" and finality is + called "bft-finality". + +Original BFT subprotocol (Π\ :sub:`origbft`) + The "off-the-shelf" BFT protocol before CCC-SL adaptation modifications. + CFP-SL is a specific instance of this with Zcash-specific adaptations. + +bc-confirmation-depth (σ) + A protocol parameter specifying the number of bc-block confirmations required + before a bc-block may be included in the snapshot referenced by a bft-block. + This is also the default depth used by nodes when computing the locally + finalized chain. + +Finalization gap bound (L) + A protocol parameter specifying the maximum number of unfinalized bc-blocks + permitted before CCC-SL enforces Stalled Mode. MUST satisfy ``L ≥ 2σ``. + +Bounded-availability depth (μ) + A per-node choice of confirmation depth for the locally bounded-available + chain, where ``0 < μ ≤ σ``. + +Locally finalized chain (``localfin``) + Each node's monotonically advancing view of the bc-chain that has been + finalized by ``CFP-SL``. Once a bc-block is in a node's locally finalized + chain, it will never be removed from it. + +Locally bounded-available chain (``localba``) + Each node's view of the confirmed (but not necessarily finalized) bc-chain, + computed using confirmation depth μ. + +Finality gap + At a given time, the number of bc-blocks in the bc-best-chain that have not + yet been finalized by ``CFP-SL``. + +Stalled Mode + A mode enforced by CCC-SL when the finality gap exceeds ``L``, during which + bc-block producers are constrained to produce only stalled blocks. + +Stalled block + A bc-block produced during Stalled Mode, constrained by the ``isStalledBlock`` + predicate (e.g., not including new user transactions that spend into the + unfinalized zone). + +Final Agreement + The property of the BFT subprotocol (``CFP-SL``) that all bft-valid blocks + in honest view are consistent: for any two such blocks, one must be an + ancestor of the other. + +Prefix Consistency + The property of the best-chain subprotocol (Zcash PoW) that any two honest + nodes' confirmed best-chains are consistent up to their confirmed depths. + +Crosslink Finality + The finality property provided by CCC-SL, as defined in the zebra-crosslink + design documentation [#zebra-crosslink-terminology]_. Formally: for any two + honest nodes ``i`` and ``j`` at any times ``t`` and ``u``, if both + ``localfin_i(t)`` and ``localfin_j(u)`` are non-genesis then one is a + prefix of the other (``localfin_i(t) ≼_bc localfin_j(u)`` or + ``localfin_j(u) ≼_bc localfin_i(t)``). See the Security Analysis section. + +``≼_bc`` (bc-prefix relation) + ``A ≼_bc B`` holds iff the bc-chain with tip ``A`` is a prefix of the + bc-chain with tip ``B``; equivalently, ``A`` is an ancestor of ``B`` or + ``A = B``. The notation ``≼`` (without subscript) is used as a shorthand + for ``≼_bc`` when the context is unambiguous. + +``C.truncate_bc(k)`` + For a bc-chain ``C`` and natural number ``k``: the bc-chain obtained by + removing the last ``k`` blocks from ``C``. The tip of ``C.truncate_bc(k)`` + is the block at depth ``k`` in ``C``. If ``len(C) ≤ k``, the result is the + genesis block ``Origin_bc``. When applied to a block ``H`` (shorthand for + the chain ending at ``H``), ``H.truncate_bc(k)`` denotes the block at + depth ``k`` from ``H``. + +``lastCommonAncestor(A, B)`` + For two bc-blocks ``A`` and ``B``: the most recent (deepest) bc-block that + is an ancestor of both ``A`` and ``B``. Equivalently, the tip of the longest + common prefix of the bc-chains ending at ``A`` and ``B``. If one block is an + ancestor of the other, ``lastCommonAncestor(A, B) = min(A, B)`` by depth. + +``bftLastFinal(B)`` + For a bft-block ``B``, the function returning the last bft-block that is + considered final in the context of ``B`` (including ``B`` itself, if + applicable). This function is defined by ``CFP-SL``. + +``snapshot(B)`` + For a bft-block or bft-proposal ``B``, the bc-block at the base of the + bc-chain snapshot committed to by ``B``. Formally: if ``B.headers_bc`` is + null (genesis), ``snapshot(B) = Origin_bc``; otherwise + ``snapshot(B) = B.headers_bc[0].truncate_bc(1)``. + +``LF(H)`` + For a bc-block ``H``, the last final bft-block in the context of ``H``: + ``LF(H) = bftLastFinal(H.context_bft)``. + +``candidate(H)`` + For a bc-block ``H``, the candidate finalization point: + ``candidate(H) = lastCommonAncestor(snapshot(LF(H)), H.truncate_bc(σ))``. + + +Abstract +======== + +This ZIP specifies **CCC-SL** (the Crosslink Consensus Construction from +Shielded Labs), the hybrid consensus protocol at the core of Shielded Labs +Crosslink v1 [#zip-crosslink-overview]_. CCC-SL integrates the Zcash +Proof-of-Work best-chain protocol with the ``CFP-SL`` BFT finalization +protocol to provide both the availability properties of the PoW chain and the +Crosslink Finality of a BFT protocol. + +CCC-SL is closely based on the ``CCC-TFLv2`` construction from the Zcash TFL +book [#tfl-book]_. The key features of CCC-SL are: + +1. Cross-referencing fields in both bc-blocks and bft-blocks/proposals that + allow each chain to objectively verify properties of the other. + +2. A locally finalized chain (``localfin``) maintained by each node that + advances monotonically and never rolls back. + +3. A locally bounded-available chain (``localba``) providing a + confirmed-but-not-necessarily-finalized view of the PoW chain. + +4. A Stalled Mode mechanism implementing bounded availability when the + finality gap exceeds the threshold ``L``. + +This ZIP is accompanied by ZIP [#zip-crosslink-overview]_, which provides the +design motivation and architecture overview for the full Shielded Labs +Crosslink v1 protocol suite. + + +Motivation +========== + +See ZIP [#zip-crosslink-overview]_ for the full motivation. In brief: + +* Zcash's current PoW-only consensus provides only probabilistic finality, + creating friction for exchanges, bridges, and other services. + +* Integrating ``CFP-SL`` as a finality layer via CCC-SL preserves PoW + availability and security while adding Crosslink Finality. + +* CCC-SL (following CCC-TFLv2) improves on the Snap-and-Chat construction + [#ebb-and-flow]_ by eliminating the need for transaction-log sanitization + and by implementing bounded availability. + +* The cross-referencing design of CCC-SL enables each chain to provide + objective validity checks on the other, strengthening the security of the + hybrid construction. + + +Requirements +============ + +CCC-SL MUST satisfy: + +* **Crosslink Finality**: If both subprotocols satisfy their safety assumptions, + the locally finalized chain of any two honest nodes must be consistent — + neither node's locally finalized chain can conflict with the other's. + +* **Local Finalization Linearity**: For each honest node, the locally finalized + chain is monotonically non-decreasing: it only ever advances forward, never + rolls back. + +* **Prefix Consistency** (inherited from Π\ :sub:`bc`): Two honest nodes' + confirmed best-chains must be consistent. + +* **Bounded Availability**: The finality depth of any non-stalled bc-block + MUST NOT exceed ``L`` while honest bc-block producers follow the protocol. + (Stalled blocks may exist at finality depth greater than ``L``; the bound + applies to transaction-carrying blocks only.) When the finality depth at the + chain tip exceeds ``L``, bc-block producers MUST enter Stalled Mode. + +* **Objective Validity**: The validity of any bc-block MUST be determinable + from the block itself and its ancestors in both chains, with no external + context beyond the two chains. + +* **Minimal Subprotocol Modification**: The modifications to the PoW and + ``CFP-SL`` subprotocols SHOULD be as minimal as possible while satisfying + the above requirements. + + +Non-requirements +================ + +The following are out of scope for this ZIP: + +* The specific BFT algorithm used internally by ``CFP-SL``. This ZIP specifies + only the interface requirements (Final Agreement, etc.) that + Π\ :sub:`origbft` must satisfy. The CFP-SL specification is a separate ZIP. + +* The staking mechanics, Finalizer registration, delegation, and slashing + rules (specified in the RSM-SL-v1 ZIP). + +* Reward distribution between PoW miners and Finalizers (a separate funding + ZIP). + +* The specific activation height(s) for the network upgrade. + + +Specification +============= + +Parameters +---------- + +CCC-SL is parameterized by: + +* **bc-confirmation-depth** ``σ ∈ ℕ⁺``: the number of bc-block headers + included in each bft-block's ``headers_bc`` field, representing the depth + at which a bc-block is considered confirmed for snapshotting purposes. This + is also the default confirmation depth for the locally finalized chain. + +* **Finalization gap bound** ``L ∈ ℕ⁺``, where ``L`` is significantly greater + than ``σ`` (the minimum is ``L ≥ 2σ``): the maximum finality gap before + Stalled Mode is enforced. + +The precise values of ``σ`` and ``L`` for Mainnet and Testnet deployment are +to be determined through a network upgrade process ZIP, taking into account +measured CFP-SL latency and desired time-to-finality targets. + +Subprotocol Interface Requirements +------------------------------------ + +CCC-SL places the following requirements on Π\ :sub:`origbft` (which is +instantiated as ``CFP-SL`` in Shielded Labs Crosslink v1): + +* Π\ :sub:`origbft` MUST be a protocol with an identified set of blocks + forming a DAG with a defined genesis block ``Origin_bft``. + +* Π\ :sub:`origbft` MUST define a function + ``bftValid(B) → Boolean`` determining whether a bft-block ``B`` is valid + in the context of the bft-chain. + +* Π\ :sub:`origbft` MUST define a function + ``bftLastFinal(B) → BftBlock`` returning the last bft-block that is + "final" in the context of bft-block ``B``, where ``bftLastFinal(Origin_bft) + = Origin_bft``. + +* Π\ :sub:`origbft` MUST satisfy **Final Agreement**: in any execution where + safety assumptions hold, for all bft-valid blocks ``C`` in honest view and + all times ``t``, ``bftLastFinal(C)`` must be an ancestor of every other + bft-valid block that honest nodes have finalized. + +CCC-SL places the following requirements on Π\ :sub:`origbc` (the Zcash PoW +protocol): + +* Π\ :sub:`origbc` MUST be a best-chain protocol with bc-blocks forming a tree + rooted at ``Origin_bc``. + +* Π\ :sub:`origbc` MUST define a fork-choice function selecting the "best + chain" among all bc-valid chains known to a node. + +* Π\ :sub:`origbc` MUST satisfy **Prefix Consistency** (Common Prefix): in any + execution where assumptions hold, for any two honest nodes' confirmed chains + ``C1`` and ``C2``, one is a prefix of the other. + +Structural Additions +-------------------- + +CCC-SL extends the block formats of both subprotocols with cross-referencing +fields: + +bc-block structural additions + Each bc-block header MUST include, in addition to all + Π\ :sub:`origbc`-block fields: + + * ``context_bft``: a hash identifying a bft-block. This commits the + bc-block producer to their view of the ``CFP-SL`` chain at the time the + block was produced. The referenced bft-block MUST be a bft-valid block in + the bc-block producer's view at the time of production. + +bft-proposal structural additions + Each non-genesis bft-proposal MUST include, in addition to all + Π\ :sub:`origbft`-proposal fields: + + * ``headers_bc``: a sequence of exactly ``σ`` bc-block headers (zero-indexed, + deepest first, i.e., ``headers_bc[0]`` is deepest and + ``headers_bc[σ-1]`` is the most recent). These headers MUST form a valid + chain in Π\ :sub:`bc` (each header's parent hash must match the previous + header's hash). The genesis bft-block has ``headers_bc = null``. + +bft-block structural additions + Each non-genesis bft-block MUST include, in addition to all + Π\ :sub:`origbft`-block fields: + + * ``headers_bc``: the same sequence of ``σ`` bc-block headers as in the + corresponding bft-proposal. The genesis bft-block has ``headers_bc = null``. + +Derived Functions +----------------- + +Based on the structural additions above, define: + +``snapshot(B)`` + For a bft-block or bft-proposal ``B``:: + + snapshot(B) := + if B.headers_bc == null: + Origin_bc + else: + B.headers_bc[0].truncate_bc(1) + + That is, the bc-block one step before the deepest header in the snapshot, + i.e., the bc-block at depth ``σ+1`` relative to the tip of the snapshot + chain. [#note-snapshot]_ + +``LF(H)`` + For a bc-block ``H``:: + + LF(H) := bftLastFinal(H.context_bft) + +``candidate(H)`` + For a bc-block ``H``:: + + candidate(H) := lastCommonAncestor(snapshot(LF(H)), H.truncate_bc(σ)) + + When ``H`` is the tip of a node's bc-best-chain, ``candidate(H)`` gives the + candidate finalization point (subject to the local finalization update rule + below). It represents the deepest bc-block that both (a) has been snapshotted + by the last final bft-block in context, and (b) is at least ``σ`` deep in + the bc-best-chain. + +Locally Finalized Chain +----------------------- + +Each node ``i`` maintains a locally finalized bc-chain ``localfin_i``, +initialized at ``Origin_bc``. The chain state MUST NOT be exposed to external +clients of the node until the node has synced (see `Syncing and Checkpoints`_). + +When node ``i``'s bc-best-chain view is updated from ``ch_i(s)`` to +``ch_i(t)``:: + + UpdateLocalFin(localfin_i, ch_i(t), s): + let N = candidate(ch_i(t)) + if N is a descendant of localfin_i(s) (i.e., localfin_i(s) ≼ N): + localfin_i(t) ← N + else: + localfin_i(t) ← localfin_i(s) + if N conflicts with localfin_i(s) (i.e., neither is a prefix of the other): + record a finalization safety hazard + +A finalization safety hazard record SHOULD include ``ch_i(t)`` and the history +of ``localfin_i`` updates including and since the last update that was an +ancestor of ``N``. + +**Lemma (Local Finalization Linearity)**: The time series of bc-blocks +``localfin_i(t)`` for any honest node ``i`` is bc-linear: for all times +``s ≤ t``, ``localfin_i(s) ≼_bc localfin_i(t)``. + +*Proof*: By the update rule, ``localfin_i(t)`` is either ``localfin_i(s)`` or +a descendant of it, never a conflicting chain or an ancestor. + +**Lemma (Local Fin-Depth)**: For any honest node ``i`` at time ``t``, there +exists a time ``r ≤ t`` such that +``localfin_i(t) ≼_bc ch_i(r).truncate_bc(σ)``. + +*Proof*: By definition of ``candidate``, ``candidate(H) ≼ H.truncate_bc(σ)`` +for all bc-blocks ``H``. Let ``r ≤ t`` be the last time ``localfin_i(t)`` +changed, or genesis time ``0`` if it has never changed. + +Locally Bounded-Available Chain +--------------------------------- + +Each node ``i`` chooses a bounded-availability depth ``μ`` where +``0 < μ ≤ σ``. The locally bounded-available chain is:: + + localba(μ)_i(t) := ch_i(t).truncate_bc(μ) + +.. warning:: + Choosing ``μ < σ`` is at the node's own risk and may increase susceptibility + to rollback attacks. The default SHOULD be ``μ = σ``. + +Syncing and Checkpoints +------------------------ + +When a node first syncs or re-syncs, the locally finalized chain state MUST +NOT be exposed to external clients until the node has processed the full bc-chain +and bft-chain up to a recent point. The node MAY use checkpoints embedded in +the software (committing to a known bc-block and bft-block at a given height) +to accelerate syncing. + +Checkpoints MUST be chosen conservatively to avoid committing to blocks that +could be reorganized or that have not been finalized by ``CFP-SL``. A +checkpoint at bc-height ``h`` SHOULD only be used if ``CFP-SL`` has finalized +bc-blocks up to height ``h - σ`` or deeper. + +Π\ :sub:`bft` (CFP-SL) Changes from Π\ :sub:`origbft` +-------------------------------------------------------- + +BFT block and proposal validity + In addition to Π\ :sub:`origbft` validity rules, a bft-proposal ``P`` is + bft-valid only if: + + 1. ``P.headers_bc`` is a sequence of exactly ``σ`` bc-block headers forming + a valid bc-chain (headers are correctly linked by parent hashes and each + satisfies the bc-block header validity rules, including proof-of-work and + difficulty adjustment). + + 2. For each header ``h`` in ``P.headers_bc``, the proof-of-work MUST be + valid (checking this requires only the headers, enabling DoS mitigation). + + 3. ``P.headers_bc[σ-1]`` (the most recent header) MUST be at block height + at least as great as the snapshot committed to in the bft-parent of + ``P``, to prevent proposers from referencing stale bc-chain snapshots. + + 4. The bc-chain committed to by ``P.headers_bc`` MUST be consistent with + (i.e., a descendant of) the snapshot committed to in the bft-parent of + ``P``. + +BFT honest proposal rule (CFP-SL) + An honest CFP-SL Finalizer proposing a bft-block at time ``t`` MUST set + ``headers_bc`` to the sequence of the most recent ``σ`` bc-block headers + in the node's bc-best-chain at time ``t``. The Finalizer MUST only propose + if they have a bc-best-chain that is at least ``σ`` blocks deep. + +BFT honest voting rule (CFP-SL) + An honest CFP-SL Finalizer voting on a bft-proposal ``P`` MUST verify that + ``P.headers_bc`` satisfies the proposal validity rules above. In particular, + it MUST verify proof-of-work for all headers in ``P.headers_bc`` before + accepting the proposal. + + If ``P.headers_bc`` connects to the Finalizer's known bc-chain, the + Finalizer SHOULD download and fully validate any bc-blocks it has not yet + seen before voting. If the headers do not connect to any known bc-chain, the + Finalizer SHOULD assign lower priority to validating the proposal (to limit + DoS exposure) and MAY drop it. + +Π\ :sub:`bc` (Zcash PoW) Changes from Π\ :sub:`origbc` +--------------------------------------------------------- + +BC block validity (structural) + In addition to Π\ :sub:`origbc` validity rules, a bc-block ``H`` is + bc-valid only if: + + 1. ``H.context_bft`` is a hash identifying a bft-valid block in + Π\ :sub:`bft`. + + 2. ``H.context_bft`` refers to a bft-block that is an ancestor of, or + equal to, the bft-block referred to by ``H``'s bc-parent's + ``context_bft`` field. (Context can only move forward in the bft-chain.) + +BC contextual validity (finality gap) + A bc-block ``H`` is contextually valid only if the finality gap constraint + is satisfied. Let ``fin_height(H)`` be the bc-height of ``candidate(H)`` + and ``tip_height(H)`` be the bc-height of ``H``. The finality gap is + ``tip_height(H) - fin_height(H)``. + + If the finality gap at ``H`` exceeds ``L``, then ``H`` MUST be a stalled + block (i.e., ``isStalledBlock(H)`` MUST return ``true``). + +BC honest block production + An honest bc-block producer creating bc-block ``H`` at time ``t`` MUST: + + 1. Set ``H.context_bft`` to the hash of the most recent bft-valid block + in the producer's CFP-SL node view at time ``t``. + + 2. Check the finality gap: if the finality gap would exceed ``L`` for the + new block, the producer MUST apply the stalled-block policy. + + 3. Not include ``H.context_bft`` referencing a bft-block whose + ``headers_bc[σ-1]`` refers to a bc-block that is not a prefix of + ``H``'s bc-ancestor chain (consistency check). + +Stalled Mode Policy +-------------------- + +The stalled-block predicate ``isStalledBlock(H) → Boolean`` determines whether +a bc-block is a stalled block. The specific definition of ``isStalledBlock`` +for the Zcash deployment is deferred to a subsequent consensus ZIP, but MUST +satisfy: + +1. A stalled block MUST NOT include transactions that spend outputs created in + bc-blocks that are not in the locally finalized chain (i.e., unfinalized + outputs). This prevents users from having their funds locked in a deep + unfinalized zone. + +2. A stalled block MAY include coinbase transactions for miner rewards. + +3. The validity of ``isStalledBlock(H)`` MUST be objectively determinable from + ``H`` and its bc-ancestors (it requires no external state beyond the chain). + +4. Nodes MUST enforce the stalled block policy: a non-stalled block with a + finality gap exceeding ``L`` MUST be rejected as bc-invalid. + +Open questions +'''''''''''''' + +* Should stalled blocks be permitted to include transactions spending finalized + outputs only, or should they be entirely empty of user transactions? The + tradeoff is between some throughput during a stall versus specification + simplicity. + +* What is the correct definition of "unfinalized outputs" in the context of + Zcash shielded transactions, where output ownership is not publicly visible? + +TODO: Define the specific encoding of ``context_bft`` in Zcash block headers, +including the exact byte representation of the bft-block hash reference. + +TODO: Define the specific encoding of ``headers_bc`` in bft-proposals and +bft-blocks, including the exact byte layout. + +TODO: Specify the precise values of ``σ`` and ``L`` for Mainnet and Testnet. + +Security Analysis +----------------- + +The following properties are claimed for CCC-SL under the stated assumptions. + +Crosslink Finality +'''''''''''''''''' + +**Property**: If ``CFP-SL`` satisfies Final Agreement and the Zcash PoW +protocol satisfies Prefix Consistency, then for any two honest nodes ``i`` and +``j`` at any times ``t`` and ``u``, their locally finalized chains are +consistent: either ``localfin_i(t) ≼_bc localfin_j(u)`` or +``localfin_j(u) ≼_bc localfin_i(t)``. + +*Proof sketch*: By the ``UpdateLocalFin`` rule, ``localfin_i(t)`` is always +equal to ``candidate(ch_i(r))`` for some time ``r ≤ t``. By the definition of +``candidate``, this is the last common ancestor of ``snapshot(LF(ch_i(r)))`` +and ``ch_i(r).truncate_bc(σ)``. + +By Final Agreement of ``CFP-SL``, ``LF(ch_i(r))`` and ``LF(ch_j(s))`` (for +any two honest nodes and times) must be consistent: one is an ancestor of the +other in the bft-chain. By the monotonic inclusion of snapshots in bft-ancestor +chains and Prefix Consistency of the PoW protocol, ``candidate(ch_i(r))`` and +``candidate(ch_j(s))`` are consistent bc-blocks. Since both +``localfin_i(t)`` and ``localfin_j(u)`` are derived from ``candidate`` values +of consistent finalization points and consistent bc-chains, they must be +consistent. + +Bounded Availability +'''''''''''''''''''' + +**Property**: If all honest bc-block producers follow the stalled-block policy, +then every non-stalled bc-block accepted by honest full nodes has finality depth +at most ``L``. (Stalled blocks may have finality depth greater than ``L``; the +bound applies only to transaction-carrying, non-stalled blocks.) + +*Proof sketch*: By the BC contextual validity rule, a bc-block whose finality +gap exceeds ``L`` that is not a stalled block is rejected as bc-invalid. Since +honest bc-block producers only produce stalled blocks when the gap would exceed +``L``, and honest full nodes reject non-stalled blocks with +``tip_height(H) - fin_height(H) > L``, all non-stalled blocks in any honest +full node's view of the bc-chain satisfy ``tip_height(H) - fin_height(H) ≤ L``. +Stalled blocks may accumulate arbitrarily, but they do not carry new +unfinalized-output-spending transactions, so the set of pending unfinalized +user transactions is bounded. + +Resilience of Finality to PoW Reorgs +'''''''''''''''''''''''''''''''''''''' + +**Property**: A rollback of the bc-best-chain shorter than ``σ`` blocks does +not cause the locally finalized chain to roll back. + +*Proof sketch*: The candidate finalization point ``candidate(H)`` for a chain +tip ``H`` is at depth ``σ`` or deeper in the bc-chain (by the Local Fin-Depth +lemma). A reorg of fewer than ``σ`` blocks cannot affect the bc-block at depth +``σ``. Furthermore, the ``UpdateLocalFin`` rule only advances the locally +finalized chain, never rolling it back. + + +Reference Implementation +======================== + +A prototype implementation of CCC-SL is being developed in the +``zebra-crosslink`` component of [#zebra-crosslink]_ and integrated in the +``crosslink_monolith`` repository [#crosslink-monolith]_. These implementations +are experimental and should not be used in production. + +Reference documentation for CCC-SL's theoretical foundations is available in +the Zcash TFL design book [#tfl-book]_, specifically the "Crosslink 2 +Construction" chapter (which corresponds to CCC-TFLv2, the basis for CCC-SL). + + +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 2022.3.8 or later `_ +.. [#protocol-networks] `Zcash Protocol Specification, Version 2022.3.8. Section 3.12: Mainnet and Testnet `_ +.. [#zip-0200] `ZIP 200: Network Upgrade Mechanism `_ +.. [#zip-crosslink-overview] `ZIP [Unassigned]: Shielded Labs Crosslink v1: Protocol Overview and Architecture `_ +.. [#tfl-book] `Zcash Trailing Finality Layer Design Book — The Crosslink 2 Construction `_ +.. [#ebb-and-flow] `Ebb-and-Flow Protocols: A Resolution of the Availability-Finality Dilemma. David Neu, Joachim Neu, Ertem Nusret Tas, David Tse. `_ +.. [#zebra-crosslink] `ShieldedLabs zebra-crosslink repository `_ +.. [#crosslink-monolith] `ShieldedLabs crosslink_monolith repository `_ +.. [#zebra-crosslink-terminology] `Shielded Labs zebra-crosslink design book: Terminology `_ + +.. [#note-snapshot] The snapshot function returns the bc-block at depth 1 from the deepest header, i.e., the parent of ``headers_bc[0]``. This means the snapshot is a bc-block at depth ``σ+1`` relative to the tip of the snapshotted chain. This ensures that a bft-block referring to a snapshot provides evidence (via the ``σ`` headers) that the snapshot was confirmed at the time of the proposal. diff --git a/zips/draft-shieldedlabs-crosslink-overview.rst b/zips/draft-shieldedlabs-crosslink-overview.rst new file mode 100644 index 000000000..058e87469 --- /dev/null +++ b/zips/draft-shieldedlabs-crosslink-overview.rst @@ -0,0 +1,725 @@ +:: + + ZIP: Unassigned {numbers are assigned by ZIP editors} + Title: Shielded Labs Crosslink v1: Protocol Overview and Architecture + Owners: Nate Wilcox + Credits: Daira-Emma Hopwood + Jack Grigg + Kris Nuttycombe + Status: Draft + Category: Informational + Created: 2026-04-08 + License: MIT + Discussions-To: TBD (no specific discussion thread yet) + + +Terminology +=========== + +The key words "MUST", "MUST NOT", "SHOULD", "SHOULD NOT", 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 terms "Mainnet" and "Testnet" in this document are to be interpreted as +defined in the Zcash protocol specification [#protocol-networks]_. + +The terms below are to be interpreted as follows: + +Zcash Trailing Finality Layer (TFL) + An initiative by the former Electric Coin Company (ECC) to augment the + Zcash Proof-of-Work consensus with a Proof-of-Stake finality layer, + documented in the TFL book [#tfl-book]_. The TFL initiative produced the + theoretical design basis for Shielded Labs Crosslink v1. + +Crosslink Consensus Construction from the TFL Book (CCC-TFLv2) + The abstract hybrid consensus construction documented in the TFL book + [#tfl-book]_, version 2. CCC-TFLv2 describes how to integrate a best-chain + (PoW) protocol with a BFT (PoS) protocol and provides a formal security + analysis of the resulting hybrid. This construction is the direct theoretical + basis for ``CCC-SL``. + +Shielded Labs Crosslink v1 + The complete protocol and working implementation produced by the Shielded + Labs non-profit, extending CCC-TFLv2 with additional practical and + theoretical design details necessary for a production deployment. Shielded + Labs Crosslink v1 is a superset of the TFL in several respects: it includes + a fully prototyped working implementation, and it extends the older TFL + design with additional components (``CFP-SL``, ``RSM-SL-v1``, ``CNTP-SL``) + that are not fully specified in the TFL book. This ZIP and its companions + specify the protocols of Shielded Labs Crosslink v1. + +Crosslink Consensus Construction from Shielded Labs (CCC-SL) + The abstract hybrid consensus construction that is the core of Shielded Labs + Crosslink v1, inspired by CCC-TFLv2. CCC-SL treats the Zcash PoW protocol + and ``CFP-SL`` as somewhat opaque subprotocols, each performing their own + consensus, while requiring specific cross-referencing modifications to each. + CCC-SL is specified in ZIP [#zip-ccc-sl]_. + +Crosslink Finalization Protocol from Shielded Labs (CFP-SL) + The Proof-of-Stake BFT protocol used as the finalization subprotocol in + Shielded Labs Crosslink v1, with "adaptation modifications" to interface + with ``CCC-SL``. ``CFP-SL`` provides Crosslink Finality by running Byzantine + Fault Tolerant consensus over snapshots of the Zcash PoW chain. + +Roster State Module (RSM) + An abstract interface required by ``CFP-SL``. The RSM provides the latest + ``Active Roster Mapping`` from cryptographically self-authenticating vote + verifier identities to their associated voting weights. The Active Roster + Mapping also defines ``Roster Evolution Rules``, which are a subset of + ledger state evolution rules composing Zcash's ledger state consensus. + +RSM-SL-v1 + The specific instantiation of the Roster State Module for Shielded Labs + Crosslink v1. RSM-SL-v1 defines all staking rules that users interact with + directly: staking ZEC to a Finalizer identity, unbonding periods, amount + quantization, slashing conditions, and related rules. + +Crosslink Network Transport Protocol from Shielded Labs (CNTP-SL) + The network transport layer for Shielded Labs Crosslink v1, enabling + ``CFP-SL`` to safely and efficiently disseminate finality updates. + ``CNTP-SL`` provides pragmatic protections against network threats (DoS, + message tampering, etc.) and improvements over the status quo Zcash p2p + protocol, including transport-layer encryption, faster block and ledger + syncing, and firewall traversal. + +Active Roster Mapping + A mapping from Finalizer vote-verifier public keys to their associated + voting weights, maintained by the Roster State Module. This mapping defines + which parties are authorized to participate in ``CFP-SL`` voting at a given + point in the ledger history. + +Finalizer + A participant in the ``CFP-SL`` subprotocol who holds an active entry in + the Active Roster Mapping and participates in BFT consensus to finalize + PoW blocks. + +Roster Evolution Rules + The subset of ledger state evolution rules (within Zcash's consensus) that + govern how the Active Roster Mapping changes over time: new stakers joining, + unstaking and unbonding, slashing, and similar events. + +Crosslink Finality + The finality property provided by Shielded Labs Crosslink v1, as defined in + the zebra-crosslink design documentation [#zebra-crosslink-terminology]_. + Crosslink Finality has five key characteristics: + + 1. **Accountable**: Safety violations can be attributed to specific + Finalizers, enabling slashing penalties. + 2. **Irreversible**: Once a block achieves Crosslink Finality, it cannot be + reverted by the protocol under any circumstances permitted by the security + assumptions. + 3. **Objectively verifiable**: Any third party with access to the chain data + can independently verify whether a given block has achieved Crosslink + Finality without trusting any particular node. + 4. **Globally consistent**: All honest nodes that agree on the chain data + agree on which blocks have achieved Crosslink Finality. + 5. **Asymmetric cost-of-attack defense**: An adversary seeking to violate + Crosslink Finality must expend significantly more resources than honest + participants spend to maintain it. + +Trailing Finality + A protocol property wherein transactions become final some time after first + appearing in PoW blocks. + +Bounded Availability + The property that the best-chain ledger does not grow unboundedly ahead of + the finalized ledger during a finality stall, preventing indefinite + accumulation of unfinalized transactions. + +Finality Gap + The number of best-chain (PoW) blocks that have not yet been finalized by + ``CFP-SL`` at a given time. + +Stalled Mode + A mode entered when the finality gap exceeds a threshold ``L``, indicating + an exceptional or emergency condition. In Stalled Mode, PoW block producers + are constrained by the ``CCC-SL`` rules to produce only stalled blocks. + + +Abstract +======== + +This ZIP describes the high-level design goals, motivations, and architecture +of **Shielded Labs Crosslink v1**, a complete protocol and implementation +produced by the Shielded Labs non-profit to add Crosslink Finality to the +Zcash network. + +Shielded Labs Crosslink v1 builds on the Zcash Trailing Finality Layer (TFL) +initiative and its ``CCC-TFLv2`` hybrid construction, extending it into a +deployable system with a fully specified finalization protocol (``CFP-SL``), +staking rules (``RSM-SL-v1``), and network transport layer (``CNTP-SL``). The +core hybrid consensus mechanism is ``CCC-SL``, which is formally specified in +ZIP [#zip-ccc-sl]_. + +This document is intended as the top-level overview for the entire Shielded +Labs Crosslink v1 protocol suite. It does not itself specify consensus rules, +but provides the rationale, component definitions, architecture diagram, and +cross-references needed to understand and evaluate the companion ZIPs. + + +Background: The TFL Initiative and CCC-TFLv2 +============================================= + +The Zcash Trailing Finality Layer (TFL) was an initiative by the former +Electric Coin Company (ECC) to introduce Crosslink Finality to Zcash through +a hybrid Proof-of-Work / Proof-of-Stake consensus design. The TFL design book +[#tfl-book]_ documents this initiative and produces the Crosslink Consensus +Construction (version 2, ``CCC-TFLv2``), which provides the theoretical +framework and security analysis for integrating a PoW chain with a BFT +finality layer. + +Shielded Labs Crosslink v1 is a successor to the TFL initiative, produced by +the Shielded Labs non-profit. While ``CCC-TFLv2`` provides the abstract +consensus foundation, many practical design and implementation details were +left unspecified in the TFL book. Shielded Labs has extended the TFL work in +several important ways: + +* **CCC-SL**: A fully specified consensus construction closely following + CCC-TFLv2 but with practical adaptations and Zcash-specific details. + +* **CFP-SL**: A complete specification and prototype implementation of the + BFT finalization protocol (the ``Π_bft`` component left abstract in + CCC-TFLv2). + +* **RSM-SL-v1**: A full specification of the staking rules and roster + management (the "PoS staking mechanics" left unspecified in CCC-TFLv2). + +* **CNTP-SL**: A network transport layer for finality updates (entirely new + relative to CCC-TFLv2, which does not address the network layer). + +* **Working prototype**: A complete prototype implementation based on Zebra + [#zebra-crosslink]_ demonstrating all components working together. + +Readers who wish to understand the theoretical foundations of the consensus +construction are encouraged to read the TFL book [#tfl-book]_ alongside these +ZIPs, with the understanding that Shielded Labs Crosslink v1 may use different +terminology and make different design trade-offs in some areas. + + +Motivation +========== + +Probabilistic vs. Crosslink Finality +-------------------------------------- + +The current Zcash consensus protocol uses Nakamoto-style Proof-of-Work, which +provides only *probabilistic* finality: a transaction confirmed at depth ``k`` +can theoretically be reversed by an adversary with sufficient hash rate. +Although deep reorgs are costly and increasingly unlikely as depth increases, +they are not impossible. This limitation has several practical consequences: + +* **Exchange and service delays**: Exchanges and other services must wait for + many confirmations before crediting deposits, increasing friction for users. + +* **Bridge trust assumptions**: Cross-chain bridges and atomic swaps must + account for reorg risk, often requiring conservative confirmation depths or + additional trust assumptions. + +* **Wallet complexity**: Wallets must communicate uncertainty about + transaction finality to users, complicating UX. + +Crosslink Finality — the property that a finalized transaction *cannot* be +reversed by the protocol — removes these limitations. Any system that can +rely on Crosslink Finality can offer faster, safer service with simpler +reasoning about transaction status. + +Why Proof-of-Stake for Finality? +--------------------------------- + +Proof-of-Stake (PoS) consensus protocols using Byzantine Fault Tolerant (BFT) +algorithms are well-established approaches for providing Crosslink Finality. +Tendermint, PBFT, Casper, and related protocols all achieve this goal with +strong theoretical foundations. Integrating a BFT PoS layer into Zcash as a +*finality layer* — rather than replacing PoW entirely — allows the ecosystem to: + +1. **Retain PoW security**: The PoW chain continues to provide its well-understood + liveness and censorship-resistance properties. + +2. **Add PoS staking rewards**: ZEC holders can participate in network security + by staking ZEC (directly or by delegating to a Finalizer), earning protocol + rewards. + +3. **Minimize disruption**: The transition preserves existing wallets, services, + and tooling with minimal required changes. + +4. **Enable future evolution**: A successful hybrid PoW/PoS transition builds + confidence and infrastructure for potential future full PoS transitions. + +Why CCC-SL Rather Than Snap-and-Chat? +--------------------------------------- + +An earlier candidate for the hybrid construction was the Snap-and-Chat +protocol from the Ebb-and-Flow paper [#ebb-and-flow]_. The TFL initiative +identified several issues with Snap-and-Chat [#tfl-book]_, motivating the +development of CCC-TFLv2 (and by extension CCC-SL): + +* Snap-and-Chat's "sanitization" step complicates transaction finality + semantics in ways that interact poorly with Zcash's shielded transaction + model. + +* Snap-and-Chat does not implement bounded availability, which is a safety + property important for protecting users during finality stalls. + +* The security analysis of CCC-TFLv2 / CCC-SL is more rigorous and complete + than what is available for Snap-and-Chat. + +The Case for Bounded Availability +----------------------------------- + +A key design goal of CCC-SL is *bounded availability*: preventing the PoW +chain from growing unboundedly ahead of the finalized chain during a finality +stall. Without this property, a period of ``CFP-SL`` failure could allow +unbounded accumulation of unfinalized transactions. When ``CFP-SL`` recovered, +users would face uncertainty about which transactions would ultimately be +finalized and which would be reversed. + +Bounded availability addresses this by entering "Stalled Mode" when the +finality gap exceeds a threshold ``L``. In Stalled Mode, PoW block producers +are constrained to produce only "stalled blocks" — blocks that do not include +new user transactions spending into the unfinalized zone. This limits user +exposure during finalization failures. + + +Requirements +============ + +Shielded Labs Crosslink v1 MUST satisfy the following requirements: + +Finality Requirements +--------------------- + +* The protocol MUST provide Crosslink Finality for transactions included in + finalized blocks. + +* The expected time-to-finality SHOULD be below 30 minutes under normal + network conditions. + +* The protocol MUST maintain Local Finalization Linearity: from any single + node's perspective, the locally-finalized chain can only grow forward, never + roll back. + +Safety Requirements +-------------------- + +* The cost-of-attack for a 1-hour rollback of the PoW chain MUST NOT be + reduced compared to the current Zcash consensus protocol, given a reasonably + rigorous security argument. + +* The cost-of-attack to halt the chain MUST be larger than the 24-hour revenue + of PoW mining rewards, given a reasonably rigorous security argument. + +Backward Compatibility Requirements +------------------------------------- + +* All currently supported wallet operations (addresses, payment flow, ZEC + transfers, backup/restore, etc.) MUST continue to function without change + through the protocol transition, assuming wallets rely on the lightwalletd + protocol or a full-node API. + +* Mining pool operators relying on zcashd-compatible ``GetBlockTemplate`` + MUST NOT be required to make software changes, with the narrow exception of + software that hardcodes block reward amounts rather than deriving them from + ``GetBlockTemplate``. + +* The ZEC supply cap and issuance schedule MUST be preserved. + +* Block explorers that display transaction and block information MUST continue + to function with the same user experience through the transition. + +Bounded Availability Requirements +----------------------------------- + +* ``CCC-SL`` MUST implement bounded availability: the finality depth of any + non-stalled bc-block MUST NOT exceed ``L``, where ``L`` is a protocol + parameter. (Stalled blocks may exist at any finality depth; Bounded + Availability bounds the depth of *transaction-carrying* blocks only.) + +* ``L`` MUST be set significantly larger than the bc-confirmation-depth ``σ``, + with a minimum of ``L ≥ 2σ``. + +Staking Requirements +-------------------- + +* ZEC holders MUST be able to earn protocol rewards by operating as Finalizers + or delegating ZEC to Finalizers via ``RSM-SL-v1``. + +* Finalizers MUST NOT have discretionary control over delegated funds; they + MUST NOT be able to steal delegated ZEC. + +* The protocol MUST allow slashing of Finalizer stake for provable misbehavior. + + +Non-requirements +================ + +The following are explicitly out of scope for Shielded Labs Crosslink v1: + +* Minimizing time-to-finality as a primary goal over other considerations such + as protocol simplicity or impact on existing use cases. + +* In-protocol liquid staking derivatives. + +* Maximizing the Finalizer count ceiling. The design may have a relatively low + ceiling of hundreds to a few thousand Finalizers. + +* Reducing overall network energy usage (this cannot be achieved for a + hybrid PoW/PoS design without loss of security). + + +Specification +============= + +Protocol Component Overview +----------------------------- + +Shielded Labs Crosslink v1 is composed of five major protocol components that +interact with the existing Zcash PoW consensus and ledger rules: + +1. **CCC-SL** — the hybrid consensus construction at the core of Crosslink v1. +2. **CFP-SL** — the BFT PoS finalization protocol run by Finalizers. +3. **RSM-SL-v1** — the Roster State Module that manages the Active Roster + Mapping and staking rules. +4. **CNTP-SL** — the network transport layer for finality updates. +5. **Zcash PoW consensus** (existing, with minimal CCC-SL modifications). + +Component Diagram +----------------- + +The following diagram illustrates the components of Shielded Labs Crosslink v1 +and their interactions. Arrows indicate data flow or dependency:: + + ┌──────────────────────────────────────────────────────────┐ + │ Shielded Labs Crosslink v1 │ + │ │ + ┌──────────┐ │ ┌────────────────────────────────────────────────────┐ │ + │ Zcash │ │ │ CCC-SL (Crosslink Consensus Construction │ │ + │ PoW │◄─┼──│ from Shielded Labs) │ │ + │ (Π_bc) │──┼─►│ • context_bft field in bc-block headers │ │ + └──────────┘ │ │ • Finality gap / Stalled Mode enforcement │ │ + ▲ │ │ • Locally finalized chain (localfin) │ │ + │ │ │ • Locally bounded-available chain (localba) │ │ + │ │ └──────────────────────┬─────────────────────────────┘ │ + │ │ │ │ + │ │ ┌──────────────────────▼─────────────────────────────┐ │ + │ │ │ CFP-SL (Crosslink Finalization Protocol │ │ + │ │ │ from Shielded Labs) │ │ + └────────┼──│ • BFT PoS consensus over PoW chain snapshots │ │ + │ │ • headers_bc in bft-proposals and bft-blocks │ │ + │ │ • Final Agreement property │ │ + │ │ • Adaptation modifications for CCC-SL interface │ │ + │ └────────────┬──────────────────┬────────────────────┘ │ + │ │ │ │ + │ ┌────────────▼───────────┐ ┌──▼──────────────────────┐ │ + │ │ RSM-SL-v1 │ │ CNTP-SL │ │ + │ │ (Roster State Module) │ │ (Crosslink Network │ │ + │ │ │ │ Transport Protocol) │ │ + │ │ • Active Roster │ │ │ │ + │ │ Mapping │ │ • Finality update │ │ + │ │ • Roster Evolution │ │ dissemination │ │ + │ │ Rules │ │ • Transport encryption │ │ + │ │ • Staking rules: │ │ • Faster sync │ │ + │ │ - ZEC delegation │ │ • Firewall traversal │ │ + │ │ - Unbonding periods │ │ • DoS protection │ │ + │ │ - Slashing │ │ │ │ + │ │ - Quantization │ │ │ │ + │ └────────────────────────┘ └─────────────────────────┘ │ + │ │ + └───────────────────────────────────────────────────────────┘ + +Component Descriptions +----------------------- + +CCC-SL: Crosslink Consensus Construction from Shielded Labs + CCC-SL is the core hybrid consensus construction specifying how the Zcash + PoW subprotocol and ``CFP-SL`` interact. It is closely based on CCC-TFLv2 + and provides the following key mechanisms: + + * **Cross-referencing fields**: Each PoW block header includes a + ``context_bft`` field referencing a ``CFP-SL`` block; each ``CFP-SL`` + proposal includes a ``headers_bc`` field with ``σ`` PoW block headers. + These fields allow each chain to objectively verify properties of the + other. + + * **Locally finalized chain**: Each node maintains a locally finalized + bc-chain (``localfin``) that only ever advances forward, never rolling + back. + + * **Locally bounded-available chain**: Each node also maintains a confirmed + (but not necessarily finalized) bc-chain view (``localba``) at a chosen + confirmation depth. + + * **Stalled Mode**: When the finality gap (number of unfinalized PoW blocks) + exceeds ``L``, CCC-SL enforces Stalled Mode, constraining PoW block + producers to produce only stalled blocks. + + CCC-SL is formally specified in ZIP [#zip-ccc-sl]_. + +CFP-SL: Crosslink Finalization Protocol from Shielded Labs + CFP-SL is the BFT Proof-of-Stake consensus protocol run by Finalizers to + provide Crosslink Finality. It operates over snapshots of the Zcash PoW chain: + each CFP-SL proposal commits to a sequence of PoW block headers, and + finalized CFP-SL blocks determine which PoW blocks are considered final. + + CFP-SL is a modified version of an off-the-shelf BFT protocol, with + adaptation modifications to: + + * Include ``headers_bc`` in proposals and blocks (required by CCC-SL). + * Consult the Active Roster Mapping from ``RSM-SL-v1`` for voter weights. + * Verify PoW header validity before voting on proposals. + + The specific off-the-shelf BFT algorithm used by CFP-SL will be specified in + a companion ZIP. CFP-SL must satisfy the **Final Agreement** property: in any + execution where safety assumptions hold, all honest nodes' views of finalized + CFP-SL blocks are consistent. + +RSM-SL-v1: Roster State Module (Shielded Labs v1) + RSM-SL-v1 is the specific instantiation of the abstract Roster State Module + interface required by CFP-SL. It maintains the Active Roster Mapping that + determines which Finalizer identities are authorized to vote in CFP-SL and + with what weight. + + RSM-SL-v1 defines all staking rules that users interact with directly, + including: + + * **ZEC delegation**: Staking ZEC to a Finalizer vote-verifier identity. + * **Unbonding periods**: The mandatory waiting period before staked ZEC can + be withdrawn after unbonding. + * **Amount quantization**: Minimum and increment sizes for staking amounts. + * **Slashing**: Conditions and amounts for penalizing provably misbehaving + Finalizers, enforced as Roster Evolution Rules. + * **Roster Evolution Rules**: Ledger state evolution rules that govern how + the Active Roster Mapping changes over time as part of Zcash's broader + ledger state consensus. + + RSM-SL-v1 will be specified in a companion ZIP. + +CNTP-SL: Crosslink Network Transport Protocol from Shielded Labs + CNTP-SL is the network transport layer providing the communication substrate + for Shielded Labs Crosslink v1. Although not strictly logically required for + a correct Crosslink deployment (any sufficiently reliable broadcast network + would suffice), CNTP-SL provides important practical properties: + + * **Finality update dissemination**: Efficient propagation of CFP-SL blocks + and finality updates to all network participants, including light clients. + * **DoS protection**: Network-layer defenses against denial-of-service + attacks targeting the finalization protocol. + * **Transport-layer encryption**: Authenticated, encrypted communication + between Crosslink v1 nodes. + * **Faster sync protocols**: Improved block and ledger synchronization + compared to the status quo Zcash p2p protocol. + * **Firewall traversal**: Support for nodes behind NAT/firewalls. + + CNTP-SL will be specified in a companion ZIP. + +Interaction Between Components +-------------------------------- + +The components of Shielded Labs Crosslink v1 interact as follows: + +1. **Zcash PoW ↔ CCC-SL**: CCC-SL augments PoW block validity rules with + the ``context_bft`` cross-reference requirement and the Stalled Mode + policy. Honest PoW block producers consult their CFP-SL node to determine + the current BFT chain tip for ``context_bft``. + +2. **CCC-SL ↔ CFP-SL**: CCC-SL defines the interface requirements CFP-SL must + satisfy (Final Agreement, the ``headers_bc`` format, and the + ``bftLastFinal`` function). CFP-SL produces finalized blocks that CCC-SL + uses to compute ``localfin``. CFP-SL proposals include PoW block headers + that CCC-SL verifies. + +3. **CFP-SL ↔ RSM-SL-v1**: CFP-SL queries RSM-SL-v1 for the current Active + Roster Mapping to determine voter weights and authorized identities for each + round of BFT consensus. RSM-SL-v1's Roster Evolution Rules are enforced as + part of Zcash ledger state transitions, so the Active Roster Mapping changes + as the PoW ledger evolves. + +4. **CFP-SL ↔ CNTP-SL**: CNTP-SL provides the network transport over which + CFP-SL messages (proposals, votes, finalized blocks) are communicated + between Finalizers and propagated to all network participants. + +5. **Zcash PoW ↔ RSM-SL-v1**: The Roster Evolution Rules in RSM-SL-v1 are + expressed as standard Zcash ledger state evolution rules, enforced by the + PoW consensus mechanism. Staking and unstaking transactions appear on the + PoW chain and update the Active Roster Mapping. + +Relationship to the Existing Zcash Protocol +--------------------------------------------- + +The Zcash PoW subprotocol within Shielded Labs Crosslink v1 is closely related +to the existing Zcash NU5/NU6 consensus protocol but is not identical. The +CCC-SL construction requires the following changes (specified in detail in ZIP +[#zip-ccc-sl]_): + +* Each PoW block header MUST include a ``context_bft`` field referencing a + CFP-SL block, committing the PoW block producer to their view of the + finalization chain. + +* PoW block validity rules are extended with contextual checks enforcing the + finality gap constraint and Stalled Mode policy. + +The RSM-SL-v1 staking rules add new transaction types and ledger state to the +Zcash protocol, specified as consensus rule additions. + +Network Upgrade Mechanism +-------------------------- + +Shielded Labs Crosslink v1 would be deployed via the existing Zcash network +upgrade mechanism [#zip-0200]_ as a consensus rule change. The precise +activation height(s) will be determined in subsequent process ZIPs once all +component specifications are finalized. + +Reward Distribution +-------------------- + +Activating Shielded Labs Crosslink v1 requires adjusting the Zcash block +reward to provide rewards to Finalizers (via RSM-SL-v1) while maintaining the +existing ZEC supply schedule. The specific reward allocation between PoW miners +and Finalizers is not specified in this ZIP; it will be addressed in a separate +funding ZIP. + +The ZEC supply cap of 21 million ZEC and the overall issuance schedule MUST +be preserved. + + +Security Considerations +======================= + +Hybrid Protocol Security +------------------------- + +The security of Shielded Labs Crosslink v1 depends on the security of both the +Zcash PoW subprotocol and ``CFP-SL``, as well as the correctness of ``CCC-SL``. +The CCC-SL specification (ZIP [#zip-ccc-sl]_) includes a security analysis +establishing the key properties: Crosslink Finality, Prefix Consistency, and +Bounded Availability. + +CFP-SL Failure +--------------- + +If ``CFP-SL`` experiences a safety failure (e.g., due to more than one-third +of staked weight being controlled by adversarial Finalizers), the CCC-SL +construction's finalization safety hazard detection will record the event. The +bounded availability property limits the damage from CFP-SL liveness failures +by entering Stalled Mode when the finality gap grows too large. + +PoW Protocol Failure +--------------------- + +If the Zcash PoW subprotocol experiences a deep reorg, but CFP-SL has not yet +finalized the affected blocks, CCC-SL will simply not finalize those blocks. If +the reorg affects already-finalized blocks, the finalization safety hazard +detection will record the event — but such an event can only occur if safety +assumptions about CFP-SL (e.g., that fewer than one-third of staked weight is +adversarial) are also violated. + +Staked ZEC Risk +--------------- + +ZEC staked to Finalizers via RSM-SL-v1 may be subject to slashing penalties +for provable misbehavior. The protocol design MUST ensure that slashing +penalties cannot be imposed on honest Finalizers, and that the slashing +conditions and amounts are deterministic and auditable. + +Privacy Considerations +----------------------- + +Shielded Labs Crosslink v1 introduces new on-chain data (CFP-SL blocks, +Finalizer votes, cross-references between chains, and staking transactions). +Care must be taken to ensure that this new data does not leak information about +shielded transactions. The privacy implications of Finalizer identity and +staking will be analyzed in the RSM-SL-v1 specification ZIP. + + +Reference Implementation +======================== + +A complete prototype implementation of Shielded Labs Crosslink v1 is being +developed based on Zebra in the ``zebra-crosslink`` repository [#zebra-crosslink]_ +and integrated in the ``crosslink_monolith`` repository [#crosslink-monolith]_. +These implementations are experimental and should not be used in production. + + +Appendix: Divergences Between Reference Sources +================================================ + +The Shielded Labs Crosslink v1 ZIPs draw on three main reference sources: + +1. **The TFL book** [#tfl-book]_ — the original ECC design document specifying + ``CCC-TFLv2``. +2. **The zebra-crosslink design book** [#zebra-crosslink-cl2]_ — Shielded Labs' + working design documentation, which is based on the TFL book but records + intentional divergences. +3. **These ZIPs** (this document and the CCC-SL construction ZIP) — the formal + protocol specifications for Shielded Labs Crosslink v1. + +The zebra-crosslink design book ``book/src`` is treated as the authoritative +source for terminology and design decisions when sources diverge. The following +known divergences exist between these sources: + +Finality Terminology +--------------------- + +* **TFL book** uses "Assured Finality" as the name of the formal safety + property of the hybrid construction. +* **zebra-crosslink** ``security-properties.md`` [#zebra-crosslink-security]_ + refers to the same concept as "Irreversible Finality". +* **zebra-crosslink** ``terminology.md`` [#zebra-crosslink-terminology]_ + defines "Crosslink Finality" as the user-facing name for this property, with + five defining characteristics (accountable, irreversible, objectively + verifiable, globally consistent, asymmetric cost-of-attack defense). +* **These ZIPs** adopt "Crosslink Finality" as the primary term, following + ``terminology.md`` as the authoritative source. + +Stalled Mode +------------ + +* **CCC-TFLv2** (TFL book) and **CCC-SL** (these ZIPs) include Stalled Mode: + when the finality depth exceeds ``L``, bc-block producers MUST produce only + stalled blocks (blocks that do not include new unfinalized-output-spending + transactions). +* **zebra-crosslink** explicitly omits Stalled Mode from its current design. + The ``cl2-construction.md`` file in the zebra-crosslink design book contains + a prominent warning: "The ``zebra-crosslink`` design in this book diverges + from this text by *not* including 'Stalled Mode' rules." +* **These ZIPs** retain Stalled Mode from CCC-TFLv2, as it is a key component + of the Bounded Availability property. This divergence from the current + zebra-crosslink implementation is intentional and will need to be resolved + before deployment. + +``finality_depth`` Naming +-------------------------- + +* **TFL book** defines ``finality_depth(H)`` as the height of ``H`` minus the + height of ``snapshot(LF(H))``, and uses ``finality_depth(H) > L`` as the + condition for Stalled Mode. +* **These ZIPs** use the equivalent expression + ``tip_height(H) - fin_height(H) > L``, where ``fin_height(H)`` is the + height of ``candidate(H)``. The quantity ``candidate(H)`` is closely + related to ``snapshot(LF(H))`` via the ``lastCommonAncestor`` function. + The two formulations are equivalent in normal operation. + +Construction Name +----------------- + +* **TFL book** and **zebra-crosslink** refer to the hybrid construction as + "Crosslink 2" (or "CL2"). +* **These ZIPs** use "CCC-SL" (Crosslink Consensus Construction from Shielded + Labs) to distinguish the Shielded Labs adaptation from the abstract + CCC-TFLv2 construction. + + +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 2022.3.8 or later `_ +.. [#protocol-networks] `Zcash Protocol Specification, Version 2022.3.8. Section 3.12: Mainnet and Testnet `_ +.. [#zip-0200] `ZIP 200: Network Upgrade Mechanism `_ +.. [#zip-ccc-sl] `ZIP [Unassigned]: CCC-SL: Crosslink Consensus Construction from Shielded Labs `_ +.. [#tfl-book] `Zcash Trailing Finality Layer Design Book `_ +.. [#ebb-and-flow] `Ebb-and-Flow Protocols: A Resolution of the Availability-Finality Dilemma. David Neu, Joachim Neu, Ertem Nusret Tas, David Tse. `_ +.. [#zebra-crosslink] `ShieldedLabs zebra-crosslink repository `_ +.. [#crosslink-monolith] `ShieldedLabs crosslink_monolith repository `_ +.. [#zebra-crosslink-terminology] `Shielded Labs zebra-crosslink design book: Terminology `_ +.. [#zebra-crosslink-cl2] `Shielded Labs zebra-crosslink design book: Crosslink 2 Construction `_ +.. [#zebra-crosslink-security] `Shielded Labs zebra-crosslink design book: Security Properties `_ diff --git a/zips/draft-str4d-orchard-balance-proof.md b/zips/draft-str4d-orchard-balance-proof.md new file mode 100644 index 000000000..0af984679 --- /dev/null +++ b/zips/draft-str4d-orchard-balance-proof.md @@ -0,0 +1,235 @@ + ZIP: unassigned + Title: Air drops, Proof-of-Balance, and Stake-weighted Polling + Owners: Daira-Emma Hopwood + Jack Grigg + Status: Draft + Category: Informational + Created: 2023-12-07 + License: MIT + Discussions-To: + + +# Terminology + +The key words "MUST", "MUST NOT", and "MAY" in this document are to be +interpreted as described in BCP 14 [#BCP14]_ when, and only when, they appear in +all capitals. + +"Pool snapshot" refers to a snapshot of the state of balances in a shielded pool +as of the end of a specified block. + +"Claim" refers to a proof by a ZEC holder (TODO: support ZSAs) that they held a +set of notes summing to a committed value at the time of a given pool snapshot. + + +# Abstract + +This ZIP specifies a mechanism that effectively takes a snapshot of the state of +shielded balances in the Orchard pool, and allows holders to prove that they had +at least a given balance as of the snapshot, in such a way that they cannot claim +the same balance more than once. The privacy of holders is retained, in the sense +that claims cannot be linked to their past or future spends. + +Possible applications include private air drops, private proof-of-balance, and +private stake-weighted polling. + + +# Motivation + +TODO: Explain why this can't be done more simply, and how the problem is +isomorphic to air-drops and stake-weighted polling. + +> Do we need to be able to construct a note in another token corresponding to the +> claimed value? Can that be done just with the existing ZSA spec + a public value +> commitment? + + +# Requirements + +Who is eligible to vote / claim an airdrop? +* Most likely approach: snapshot the Zcash chain at some height. Eligible notes + exist in the commitment tree at that height, but don’t exist in the nullifier + set at that height. + +Does the Zcash side need to prove spend authority? +* Yes, it does (otherwise if people gave out their viewing keys to others, those + others could vote / claim the airdrop instead). +* UX effect: anyone who moved their funds to a different spend authority after + the snapshot and then lost their old spending keys become unable to vote / + claim the airdrop. + + +# Specification + +Sketch: + +A "nullifier non-membership tree" is a Merkle tree of sorted disjoint +(start, end) pairs representing the gaps between revealed nullifiers at a pool +snapshot. That is, the union of the regions start..=end is exactly the +complement of the set of revealed nullifiers at the snapshot. + +An "alternate nullifier" is a value derived from a note, with similar +cryptographic properties to its standard nullifier, but including a "nullifier +domain" as input to the derivation. It is distinct from and unlinkable with the +standard nullifier, or any of the other alternate nullifiers for that note in +other nullifier domains. A note has exactly one alternate nullifier for each +nullifier domain. + +An entity that wants to conduct an air-drop, stake-weighted poll, etc. does the +following: + +* Choose a pool snapshot at a particular block height. +* Choose a previously unused nullifier domain $\mathsf{dom}$. + * > TODO: how to ensure it is previously unused? What are the consequences if it isn't? + * Maybe the domain is derived from the pool snapshot and a string identifying + the air-drop/poll? Then a wallet that supports this protocol can display the + string and the block height/date of the snapshot to the wallet user. +* Deterministically construct a nullifier non-membership tree as of the snapshot, + with root $\mathsf{rt^{excl}}$. Anyone can check that this root is correct using + public information. +* Keep track of a set of alternate nullifiers revealed by the statement below and + make sure that they don't repeat. + +To participate, a holder proves the following informal statement: + +"Given: +* a value commitment $\mathsf{cv}$; +* a nullifier domain $\mathsf{dom}$; +* an alternate nullifier $\mathsf{nf_{dom}}$; +* a pool snapshot $(\mathsf{rt^{cm}}, \mathsf{rt^{excl}})$; + +I am the holder of a note $\mathbf{n}$ that is unspent at pool snapshot +$(\mathsf{rt^{cm}}, \mathsf{rt^{excl}})$, such that $\mathbf{n}$ has value +commitment $\mathsf{cv}$ and alternate nullifier $\mathsf{nf_{dom}}$ in +nullifier domain $\mathsf{dom}$." + +### Another possible approach + +Have the holder *actually* spend the claimed notes (e.g. to themself) with an +anchor at the pool snapshot. This has the disadvantage that they cannot +participate in concurrent polls/air-drops. + +## Alternate nullifier derivation + +Given a nullifier domain $\mathsf{dom}$ and an Orchard note +$\mathbf{n} = (\mathsf{d^{old}}, \mathsf{pk_d^{old}}, \mathsf{v^{old}}, \text{ρ}^{\mathsf{old}}, \text{φ}^{\mathsf{old}}, \mathsf{rcm^{old}})$ +with note commitment $\mathsf{cm^{old}}$, the alternate nullifier $\mathsf{nf_{dom}}$ +for $\mathbf{n}$ is computed as: +$$ +\begin{array}{rcl} +\mathsf{nf_{dom}} &\!\!\!=\!\!\!& \mathsf{DeriveAlternateNullifier_{nk}}(\text{ρ}^{\mathsf{old}}, \text{φ}^{\mathsf{old}}, \mathsf{cm^{old}}, \mathsf{dom}) \\ +&\!\!\!=\!\!\!& \mathsf{Extract}_{\mathbb{P}}\big(\big[(\mathsf{PRF^{nfAlternate}_{nk}} (\text{ρ}^{\mathsf{old}}, \mathsf{dom}) + \text{φ}) \bmod q_{\mathbb{P}}\big]\, \mathcal{K}^\mathsf{Orchard} + \mathsf{cm^{old}}\big) +\end{array} +$$ + +Here $\mathsf{PRF^{nfAlternate}}$ is another instantiation of Poseidon. In order +for $\mathsf{dom}$ to be an arbitrary field element without any loss of security, +it would have to use an instantiation of Poseidon with a 4-element to 4-element +permutation. + +> TODO: security analysis, in particular for collision attacks and for linkability across domains. + + +
    + + +### Rationale for not using a similar nullifier derivation to ZSA split notes + + +The nullifier derivation in draft ZIP 226 for ZSA split notes is: +$$ +\mathsf{nf} = \mathsf{Extract}_{\mathbb{P}}\big(\big[(\mathsf{PRF^{nfOrchard}_{nk}} (\text{ρ}^{\mathsf{old}}) + \text{φ}') \bmod q_{\mathbb{P}}\big]\, \mathcal{K}^\mathsf{Orchard} + \mathsf{cm^{old}} + \mathcal{L}^\mathsf{Orchard}\big) +$$ This fails to do what we want in two ways: +* It is nondeterministic, due to the random $\text{φ}'$. +* If $\text{φ}'$ were required to be $\text{φ}^{\mathsf{old}}$ and + $\mathcal{L}^\mathsf{Orchard}$ were replaced by a hash-to-curve of + $\mathsf{dom}$, then nullifiers for different domains (including the original + ZEC domain) would be linkable, since they would differ by a predictable point. + (There are two possible points corresponding to a given nullifier, but this is + only a trivial obstable to linking them.) +
    + +## Making a claim + +For each note that the holder wants to claim, they prove an instance of the +circuit below, and provide this proof together with a spend authorization +signature (constructed as though they were spending the note). + +> It is easy to add up value commitments and then open them if desired, or use them in another zk proof. + +> Can we make it more efficient to claim that you hold multiple notes? + +## Circuit + +A valid instance of a Claim statement, $\pi$, assures that given a primary input: +* $\mathsf{cv} ⦂ \mathsf{ValueCommit^{Orchard}.Output}$ +* $\mathsf{dom} ⦂ \{ 0 .. q_{\mathbb{P}}-1 \}$ +* $\mathsf{nf_{dom}} ⦂ \{0 .. q_{\mathbb{P}}-1 \}$ +* $\mathsf{rk} ⦂ \mathsf{SpendAuthSig^{Orchard}.Public}$ + +the prover knows an auxiliary input: + +* $\mathsf{path} ⦂ \{ 0 .. q_{\mathbb{P}}-1 \}^{[\mathsf{MerkleDepth^{Orchard}}]}$ +* $\mathsf{pos} ⦂ \{ 0 .. 2^{\mathsf{MerkleDepth^{Orchard}}}\!-1 \}$ +* $\mathsf{g_d^{old}} ⦂ \mathbb{P}^*$ +* $\mathsf{pk_d^{old}} ⦂ \mathbb{P}^*$ +* $\mathsf{v^{old}} ⦂ \{ 0 .. 2^{\ell_{\mathsf{value}}}-1 \}$ +* $\text{ρ}^{\mathsf{old}} ⦂ \mathbb{F}_{q_{\mathbb{P}}}$ +* $\text{φ}^{\mathsf{old}} ⦂ \mathbb{F}_{q_{\mathbb{P}}}$ +* $\mathsf{rcm^{old}} ⦂ \{ 0 .. 2^{\ell^{\mathsf{Orchard}}_{\mathsf{scalar}}}-1 \}$ +* $\mathsf{cm^{old}} ⦂ \mathbb{P}$ +* $\mathsf{nf^{old}} ⦂ \{ 0 .. q_{\mathbb{P}}-1 \}$ +* $\alpha ⦂ \{ 0 .. 2^{\ell^{\mathsf{Orchard}}_{\mathsf{scalar}}}-1 \}$ +* $\mathsf{ak}^{\mathbb{P}} ⦂ \mathbb{P}^*$ +* $\mathsf{nk} ⦂ \mathbb{F}_{q_{\mathbb{P}}}$ +* $\mathsf{rivk} ⦂ \mathsf{Commit^{ivk}.Trapdoor}$ +* $\mathsf{rcv} ⦂ \{ 0 .. 2^{\ell^{\mathsf{Orchard}}_{\mathsf{scalar}}}-1 \}$ +* $\mathsf{path^{excl}} ⦂ \{ 0 .. q_{\mathbb{P}}-1 \}^{[\mathsf{MerkleDepth^{excl}}]}$ +* $\mathsf{pos^{excl}} ⦂ \{ 0 .. 2^{\mathsf{MerkleDepth^{excl}}}\!-1 \}$ +* $\mathsf{start} ⦂ \{ 0 .. 2^{\mathsf{MerkleDepth^{Orchard}}}\!-1 \}$ +* $\mathsf{end} ⦂ \{ 0 .. 2^{\mathsf{MerkleDepth^{Orchard}}}\!-1 \}$ + +such that the following conditions hold: + +**Note commitment integrity** $\hspace{0.5em} \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}}) \in \{ \mathsf{cm^{old}}, \bot \}$. + +**Merkle path validity for** $\mathsf{cm^{old}} \hspace{0.5em} (\mathsf{path^{cm}}, \mathsf{pos^{cm}})$ is a valid Merkle path of depth $\mathsf{MerkleDepth^{Orchard}}$, as defined in § 4.9 'Merkle Path Validity', from $\mathsf{cm^{old}}$ to the anchor $\mathsf{rt^{cm}}$. + +**Value commitment integrity** $\hspace{0.5em} \mathsf{cv} = \mathsf{ValueCommit^{Orchard}_{rcv}}(\mathsf{v^{old}})$. + +**Nullifier integrity** $\hspace{0.5em} \mathsf{nf^{old}} = \mathsf{DeriveNullifier_{nk}}(\text{ρ}^{\mathsf{old}}, \text{φ}^{\mathsf{old}}, \mathsf{cm^{old}})$. + +**Spend authority** $\hspace{0.5em} \mathsf{rk} = \mathsf{SpendAuthSig^{Orchard}.RandomizePublic}(\alpha, \mathsf{ak}^{\mathbb{P}})$. + +**Diversified address integrity** $\hspace{0.5em} \mathsf{ivk} = \bot$ or $\mathsf{pk_d^{old}} = [\mathsf{ivk}]\, \mathsf{g_d^{old}}$ where $\mathsf{ivk} = \mathsf{Commit^{ivk}_{rivk}}(\mathsf{Extract}_{\mathbb{P}}(\mathsf{ak}^{\mathbb{P}}), \mathsf{nk})$. + +**Merkle path validity for** $(\mathsf{start}, \mathsf{end}) \hspace{0.5em} (\mathsf{path^{excl}}, \mathsf{pos^{excl}})$ is a valid Merkle path of depth $\mathsf{MerkleDepth^{excl}}$, as defined in § 4.9 'Merkle Path Validity', from $\mathsf{excl}$ to the anchor $\mathsf{rt^{excl}}$, where $\mathsf{excl} = \mathsf{MerkleCRH^{Orchard}}(\mathsf{MerkleDepth^{excl}}, \mathsf{start}, \mathsf{end})$. + +**Nullifier in excluded range** $\hspace{0.5em} \mathsf{start} \leq \mathsf{nf^{old}} \leq \mathsf{end}$. + +**Alternate nullifier integrity** $\hspace{0.5em} \mathsf{nf_{dom}} = \mathsf{DeriveAlternateNullifier_{nk}}(\text{ρ}^{\mathsf{old}}, \text{φ}^{\mathsf{old}}, \mathsf{cm^{old}}, \mathsf{dom})$. + +## Circuit implementation + +All of these but the last three checks are identical to the corresponding parts +of an Action statement. + +**Merkle path validity for** $(\mathsf{start}, \mathsf{end})$ is almost identical +to the other Merkle path validity check. + +Alternate nullifier integrity is probably very similar to **Nullifier integrity**. + +**Nullifier in excluded range** is fairly straightforward. Nullifiers are +arbitrary field elements so be careful of overflow. Since we can check outside +the circuit that $\mathsf{start} \leq \mathsf{end}$, the check becomes +equivalent to $0 \leq \mathsf{nf^{old}} - \mathsf{start} \leq \mathsf{end} - \mathsf{start}$. + +## Rationale + +> TODO + + +# 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 2023.4.0 or later diff --git a/zips/draft-zf-community-dev-fund-2-proposal.rst b/zips/draft-zf-community-dev-fund-2-proposal.rst deleted file mode 100644 index 603aa981a..000000000 --- a/zips/draft-zf-community-dev-fund-2-proposal.rst +++ /dev/null @@ -1,499 +0,0 @@ -:: - - ZIP: Unassigned - Title: Establishing a Hybrid Dev Fund for ZF, ZCG and a Dev Fund Reserve - Owners: Jack Gavigan - Credits: The ZIP 1014 Authors - Status: Withdrawn - Category: Consensus Process - Created: 2024-07-01 - License: MIT - Discussions-To: - Pull-Request: - - -Terminology -=========== - -The key words "MUST", "MUST NOT", "SHALL", "SHALL 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]_ and the Zcash Trademark Donation and License Agreement -([#trademark]_ or successor agreement). - -The terms "block subsidy" and "halving" in this document are to be interpreted -as described in sections 3.10 and 7.8 of the Zcash Protocol Specification. -[#protocol]_ - -"Electric Coin Company", also called "ECC", refers to the US-incorporated -Zerocoin Electric Coin Company, LLC. - -"Bootstrap Project", also called "BP", refers to the US-incorporated 501(c)(3) -nonprofit corporation of that name. - -"Zcash Foundation", also called "ZF", refers to the US-incorporated 501(c)(3) -nonprofit corporation of that name. - -"Financial Privacy Foundation", also called "FPF", refers to the Cayman -Islands-incorporated non-profit foundation company limited by guarantee of -that name. - -"Autonomous Entities" refers to committees, DAOs, teams or other groups to -which FPF provides operations, administrative, and financial management -support. - -"Section 501(c)(3)" refers to that section of the U.S. Internal Revenue Code -(Title 26 of the U.S. Code). [#section501c3]_ - -"Zcash Community Advisory Panel", also called "ZCAP", refers to the panel of -community members assembled by the Zcash Foundation and described at [#zcap]_. - -The terms "Testnet" and "Mainnet" are to be interpreted as described in -section 3.12 of the Zcash Protocol Specification [#protocol-networks]_. - -“Lockbox” refers to a deferred funding pool of issued Zcash value as described -in ZIP 2001 [#zip-2001]_. - -“Dev Fund Reserve”, also called “DFR”, refers to the funds that are to be -stored in the Lockbox as a result of the changes described in this ZIP. - - -Abstract -======== - -This proposal describes a structure for a new Zcash Development Fund (“Dev -Fund”), to be enacted in Network Upgrade 6 and last for 2 years. This Dev -Fund shall consist of 20% of the block subsidies. - -The Dev Fund shall be split into 3 slices: - -* 32% for Zcash Foundation; -* 40% for "Zcash Community Grants", intended to fund large-scale long-term - Projects (administered by the Financial Privacy Foundation, with extra - community input and scrutiny). -* 28% for a Dev Fund Reserve, to be stored in a Lockbox. - -The Lockbox will securely store funds until a disbursement mechanism is -established in a future ZIP. - -Governance and accountability are based on existing entities and legal -mechanisms, and increasingly decentralized governance is encouraged. - - -Motivation -========== - -Starting at Zcash's second halving in November 2024, the first Dev Fund will -expire, meaning that by default 100% of the block subsidies will be allocated -to miners, and no further funds will be automatically allocated to any other -entities. Consequently, no substantial new funding may be available to -existing teams dedicated to furthering charitable, educational, or scientific -purposes, such as research, development, and outreach: the Electric Coin -Company (ECC), the Zcash Foundation (ZF), and the many entities funded by the -ZF grants and Zcash Community Grants programs. - -There is a need to continue to strike a balance between incentivizing the -security of the consensus protocol (i.e., mining) versus crucial charitable, -educational, and/or scientific aspects, such as research, development and -outreach. - -Furthermore, there is a need to balance the sustenance of ongoing work by the -current teams dedicated to Zcash, with encouraging decentralization and growth -of independent development teams. - -For these reasons, the Zcash Community desires to allocate and contribute a -slice of the block subsidies otherwise allocated to miners as a donation to -support charitable, educational, and scientific activities within the meaning -of Section 501(c)(3) of Title 26 of the United States Code, and the Cayman -Islands’ Foundation Companies Law, 2017. - -The Zcash Community also supports the concept of a non-direct funding model, -and desires to allocate a slice of the block subsidies otherwise allocated -to miners to a Lockbox, with the expectation that those funds will be -distributed under a non-direct funding model, which may be implemented in a -future network upgrade. - -For these reasons, the Zcash Community wishes to establish a Hybrid -Development Fund after the second halving in November 2024, and apportion it -among ZF, ZCG, and a Dev Fund Reserve to be held in a Lockbox. - - -Requirements -============ - -The Dev Fund should encourage decentralization of the Zcash ecosystem, by -supporting new teams dedicated to Zcash. - -The Dev Fund should maintain the existing teams and capabilities in the Zcash -ecosystem, unless and until concrete opportunities arise to create even -greater value for the Zcash ecosystem. - -There should not be any single entity which is a single point of failure, -i.e., whose capture or failure will effectively prevent effective use of the -funds. - -Major funding decisions should be based, to the extent feasible, on inputs -from domain experts and pertinent stakeholders. - -The Dev Fund mechanism itself should not modify the monetary emission curve -(and in particular, should not irrevocably burn coins). - -In case the value of ZEC jumps, the Dev Fund recipients should not wastefully -use excessive amounts of funds. Conversely, given market volatility and -eventual halvings, it is desirable to create rainy-day reserves. - -The Dev Fund mechanism should not reduce users' financial privacy or security. -In particular, it should not cause them to expose their coin holdings, nor -cause them to maintain access to secret keys for much longer than they would -otherwise. (This rules out some forms of voting, and of disbursing coins to -past/future miners.) - -The new Dev Fund system should be simple to understand and realistic to -implement. In particular, it should not assume the creation of new mechanisms -(e.g., election systems) or entities (for governance or development) for its -execution; but it should strive to support and use these once they are built. - -The Dev Fund should comply with legal, regulatory, and taxation constraints in -pertinent jurisdictions. - -The Lockbox must be prepared to allocate resources efficiently once the -disbursement mechanism is defined. This includes ensuring that funds are -readily available for future projects and not tied up in organizational -overhead. - -The Lockbox must implement robust security measures to protect against -unauthorized access or misuse of funds. It must not be possible to disburse -funds from the Lockbox until the Zcash Community reaches consensus on the -design of a disbursement mechanism that is defined in a ZIP and implemented as -part of a future Network Upgrade. - - -Non-requirements -================ - -General on-chain governance is outside the scope of this proposal. - -Rigorous voting mechanisms (whether coin-weighted, holding-time-weighted or -one-person-one-vote) are outside the scope of this proposal, though there is -prescribed room for integrating them once available. - -The mechanism by which funds held in the Dev Fund Reserve Lockbox are to be -distributed is outside the scope of this proposal. - - -Specification -============= - -Consensus changes implied by this specification are applicable to the Zcash -Mainnet. Similar (but not necessarily identical) consensus changes SHOULD be -applied to the Zcash Testnet for testing purposes. - - -Dev Fund allocation -------------------- - -Starting at the second Zcash halving in 2024, until block height 3566400 -(which is expected to occur approximately two years after the second Zcash -halving), 20% of the block subsidy of each block SHALL be allocated to a Dev -Fund that consists of the following three slices: - -* 32% for the Zcash Foundation (denoted **ZF slice**); -* 40% for the Financial Privacy Foundation, for "Zcash Community Grants" for - large-scale long-term projects (denoted **ZCG slice**); -* 28% for the Dev Fund Reserve (denoted **DFR slice**). - -The slices are described in more detail below. The fund flow will be -implemented at the consensus-rule layer, by sending the corresponding ZEC to -the designated address(es) for each block. This Dev Fund will end at block -height 3566400 (unless extended/modified by a future ZIP). - - -ZF slice (Zcash Foundation) -~~~~~~~~~~~~~~~~~~~~~~~~~~~ - -This slice of the Dev Fund will flow as charitable contributions from the -Zcash Community to ZF, to be used at its discretion for any purpose within its -mandate to support financial privacy and the Zcash platform, including: -development, education, supporting community communication online and via -events, gathering community sentiment, and awarding external grants for all of -the above, subject to the requirements of Section 501(c)(3). The ZF slice will -be treated as a charitable contribution from the Community to support these -educational, charitable, and scientific purposes. - - -ZCG slice (Zcash Community Grants) -~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ - -This slice of the Dev Fund is intended to fund independent teams entering the -Zcash ecosystem, to perform major ongoing development (or other work) for the -public good of the Zcash ecosystem, to the extent that such teams are -available and effective. - -The funds SHALL be received and administered by FPF. FPF MUST disburse them -for "Zcash Community Grants" and expenses reasonably related to the -administration of Zcash Community Grants, but subject to the following -additional constraints: - -1. These funds MUST only be used to issue Zcash Community Grants to external - parties that are independent of FPF or to Autonomous Entities that operate - under the FPF umbrella, and to pay for expenses reasonably related to - the administration of Zcash Community Grants. They MUST NOT be used by FPF - for its internal operations and direct expenses not related to - administration of Zcash Community Grants. Additionally, ZF is ineligible to - receive Zcash Community Grants while ZF is receiving a slice of the Dev - Fund. - -2. Zcash Community Grants SHOULD support well-specified work proposed by the - grantee, at reasonable market-rate costs. They can be of any duration or - ongoing without a duration limit. Grants of indefinite duration SHOULD be - reviewed periodically (on a schedule that the Zcash Community Grants - Committee considers appropriate for the value and complexity of the grant) - for continuation of funding. - -3. Priority SHOULD be given to Zcash Community Grants that bolster teams with - substantial (current or prospective) continual existence, and set them up - for long-term success, subject to the usual grant award considerations - (impact, ability, risks, team, cost-effectiveness, etc.). Priority SHOULD - Be given to grants that support ecosystem growth, for example through - mentorship, coaching, technical resources, creating entrepreneurial - opportunities, etc. If one proposal substantially duplicates another's - plans, priority SHOULD be given to the originator of the plans. - -4. Zcash Community Grants SHOULD be restricted to furthering the Zcash - cryptocurrency and its ecosystem (which is more specific than furthering - financial privacy in general). - -5. Zcash Community Grants awards are subject to approval by a five-seat Zcash - Community Grants Committee. The Zcash Community Grants Committee SHALL be - selected by the ZF's Zcash Community Advisory Panel (ZCAP) or successor - process. - -6. The Zcash Community Grants Committee's funding decisions will be final, - requiring no approval from the FPF Board, but are subject to veto if FPF - judges them to violate Cayman law or the FPF's reporting requirements and - other (current or future) obligations under the Cayman Islands’ Companies - Act (2023 Revision) and Foundation Companies Law, 2017. - -7. Zcash Community Grants Committee members SHALL have a one-year term and MAY - sit for reelection. The Zcash Community Grants Committee is subject to the - same conflict of interest policy that governs the FPF Board of Directors - (i.e. they MUST recuse themselves when voting on proposals where they have - a financial interest). At most one person with association with the BP/ECC, - at most one person with association with the ZF and at most one person with - association with the FPF, are allowed to sit on the Zcash Community Grants - Committee. "Association" here means: having a financial interest, - full-time employment, being an officer, being a director, or having an - immediate family relationship with any of the above. - -8. A portion of the ZCG Slice shall be allocated to a Discretionary Budget, - which may be disbursed for expenses reasonably related to the - administration of Zcash Community Grants. The amount of funds allocated to - the Discretionary Budget SHALL be decided by the ZF's Zcash Community - Advisory Panel or successor process. Any disbursement of funds from the - Discretionary Budget MUST be approved by the Zcash Community Grants - Committee. Expenses related to the administration of Zcash Community Grants - include, without limitation the following: - - * Paying for operational management and administration services that - support the purpose of the Zcash Community Grants program, including - administration services provided by FPF. - * Paying third party vendors for services related to domain name - registration, or the design, website hosting and administration of - websites for the Zcash Community Grants Committee. - * Paying independent consultants to develop requests for proposals that - align with the Zcash Community Grants program. - * Paying independent consultants for expert review of grant applications. - * Paying for sales and marketing services to promote the Zcash Community - Grants program. - * Paying third party consultants to undertake activities that support the - purpose of the Zcash Community Grants program. - * Reimbursement to members of the Zcash Community Grants Committee for - reasonable travel expenses, including transportation, hotel and meals - allowance. - - The Zcash Community Grants Committee's decisions relating to the allocation - and disbursement of funds from the Discretionary Budget will be final, - requiring no approval from the FPF Board, but are subject to veto if FPF - judges them to violate Cayman law or the FPF's reporting requirements and - other (current or future) obligations under Cayman Islands law. - - -9. A portion of the Discretionary Budget MAY be allocated to provide - reasonable compensation to members of the Zcash Community Grants Committee. - The time for which each Committee member is compensated SHALL be limited to - the hours needed to successfully perform their positions, up to a maximum - of 15 hours in each month, and MUST align with the scope and - responsibilities of that member's role. The compensation rate for each - Committee member SHALL be $115 per hour (and therefore the maximum - compensation for a Committee member is $1725 per month). The allocation and - distribution of compensation to committee members SHALL be administered by - FPF. Changes to the hours or rate SHALL be determined by the ZF’s Zcash - Community Advisory Panel or successor process. - -As part of the contractual commitment specified under the `Enforcement`_ section -below, FPF SHALL be contractually required to recognize the ZCG slice of the Dev -Fund as a Restricted Fund donation under the above constraints (suitably -formalized), and keep separate accounting of its balance and usage under its -`Transparency and Accountability`_ obligations defined below. - - -DFR slice (Dev Fund Reserve) -~~~~~~~~~~~~~~~~~~~~~~~~~~~~ - -This slice of the Dev Fund is to be stored in a Lockbox until such time as the -Zcash Community reaches consensus on the design of a disbursement mechanism -that is defined in a ZIP and implemented as part of a future Network Upgrade. - - -Transparency and Accountability -------------------------------- - -Obligations -~~~~~~~~~~~ - -ZF, FPF and Zcash Community Grant recipients (during and leading to their award -period) SHALL all accept the obligations in this section. - -Ongoing public reporting requirements: - -* Quarterly reports, detailing future plans, execution on previous plans, and - finances (balances, and spending broken down by major categories). -* Monthly developer calls, or a brief report, on recent and forthcoming tasks. - (Developer calls may be shared.) -* Annual detailed review of the organization performance and future plans. -* Annual financial report (IRS Form 990, or substantially similar - information). - -These reports may be either organization-wide, or restricted to the income, -expenses, and work associated with the receipt of Dev Fund. - -It is expected that ZF, FPF and Zcash Community Grant recipients will be -focused primarily (in their attention and resources) on Zcash. Thus, they MUST -promptly disclose: - -* Any major activity they perform (even if not supported by the Dev Fund) that - is not in the interest of the general Zcash ecosystem. -* Any conflict of interest with the general success of the Zcash ecosystem. - -BP, ECC, ZF, FPF and grant recipients MUST promptly disclose any security or -privacy risks that may affect users of Zcash (by responsible disclosure under -confidence to the pertinent developers, where applicable). - -ZF's and FPF's annual reports on its non-grant operations, SHOULD be at least -as detailed as grant proposals/reports submitted by other funded parties, and -satisfy similar levels of public scrutiny. - -All substantial software whose development was funded by the Dev Fund SHOULD -be released under an Open Source license (as defined by the Open Source -Initiative [#osd]_), preferably the MIT license. - -The ZF SHALL continue to operate the Zcash Community Advisory Panel and SHOULD -work toward making it more representative and independent (more on that below). - -Enforcement -~~~~~~~~~~~ - -For grant recipients, these conditions SHOULD be included in their contract -with FPF, such that substantial violation, not promptly remedied, will cause -forfeiture of their grant funds and their return to FPF. - -ZF and FPF MUST contractually commit to each other to fulfill these conditions, -and the prescribed use of funds, such that substantial violation, not promptly -remedied, will permit the other parties to issue a modified version of Zcash -node software that removes the violating party's Dev Fund slice, and use the -Zcash trademark for this modified version. The slice's funds will be reassigned -to ZCG (whose integrity is legally protected by the Restricted Fund treatment). - - -Amendments and Replacement of the Dev Fund ------------------------------------------- - -Nothing in this ZIP is intended to preclude any amendments to the Dev Fund -(including but not limited to, changes to the Dev Fund allocation and/or the -addition of new Dev Fund recipients), if such amendments enjoy the consensus -support of the Zcash community. - -Nothing in this ZIP is intended to preclude replacement of the Dev Fund with a -different mechanism for ecosystem development funding. - -ZF and FPF SHOULD facilitate the amendment or replacement of the Dev Fund if -there is sufficient community support for doing so. - -This ZIP recognizes there is strong community support for a non-direct funding -model. As such, ZF MUST collaborate with the Zcash community to research and -explore the establishment of a non-direct funding model. The research should -consider potential designs as well as possible legal and regulatory risks. - - -Future Community Governance ---------------------------- - -Decentralized community governance is used in this proposal via the Zcash -Community Advisory Panel as input into the Zcash Community Grants Committee -which governs the `ZCG slice (Zcash Community Grants)`_. - -It is highly desirable to develop robust means of decentralized community -voting and governance, either by expanding the Zcash Community Advisory Panel -or a successor mechanism. ZF, FPF and ZCG SHOULD place high priority on such -development and its deployment, in their activities and grant selection. - - -ZF Board Composition --------------------- - -Members of ZF's Board of Directors MUST NOT hold equity in ECC or have current -business or employment relationships with ECC or BP. - -The Zcash Foundation SHOULD endeavor to use the Zcash Community Advisory Panel -(or successor mechanism) as advisory input for future board elections. - - -FPF Board Composition ---------------------- - -Members of FPF's Board of Directors MUST NOT hold equity in ECC or have current -business or employment relationships with ECC or BP. - - -Acknowledgements -================ - -This proposal is a modification of ZIP 1014 [#zip-1014]_ by the Zcash Foundation based on -feedback and suggestions from the community, and incorporating elements of draft ZIPs by -community members Jason McGee and Skylar. - -ZIP 1014 is a limited modification of Eran Tromer's ZIP 1012 [#zip-1012]_ -by the Zcash -Foundation and ECC, further modified by feedback from the community. - -Eran's proposal is most closely based on the Matt Luongo 'Decentralize the -Dev Fee' proposal (ZIP 1011) [#zip-1011]_. Relative to ZIP 1011 there are substantial -changes and mixing in of elements from *@aristarchus*'s '20% Split Evenly -Between the ECC and the Zcash Foundation' (ZIP 1003) [#zip-1003]_, Josh Cincinnati's -'Compromise Dev Fund Proposal With Diverse Funding Streams' (ZIP 1010) [#zip-1010]_, and -extensive discussions in the `Zcash Community Forum`_, including valuable comments -from forum users *@aristarchus* and *@dontbeevil*. - -.. _Zcash Community Forum: https://forum.zcashcommunity.com/ - - -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 2021.2.16 or later `_ -.. [#protocol-networks] `Zcash Protocol Specification, Version 2021.2.16. Section 3.12: Mainnet and Testnet `_ -.. [#trademark] `Zcash Trademark Donation and License Agreement `_ -.. [#osd] `The Open Source Definition `_ -.. [#zip-0200] `ZIP 200: Network Upgrade Mechanism `_ -.. [#zip-1003] `ZIP 1003: 20% Split Evenly Between the ECC and the Zcash Foundation, and a Voting System Mandate `_ -.. [#zip-1010] `ZIP 1010: Compromise Dev Fund Proposal With Diverse Funding Streams `_ -.. [#zip-1011] `ZIP 1011: Decentralize the Dev Fee `_ -.. [#zip-1012] `ZIP 1012: Dev Fund to ECC + ZF + Major Grants `_ -.. [#zip-1014] `ZIP 1014: Establishing a Dev Fund for ECC, ZF, and Major Grants `_ -.. [#zip-2001] `ZIP 2001: Lockbox Funding Streams `_ -.. [#zcap] `Zcash Community Advisory Panel `_ -.. [#section501c3] `U.S. Code, Title 26, Section 501(c)(3) `_ - diff --git a/zips/zip-0000.rst b/zips/zip-0000.rst index b777f9701..ae511b942 100644 --- a/zips/zip-0000.rst +++ b/zips/zip-0000.rst @@ -2,16 +2,21 @@ ZIP: 0 Title: ZIP Process - Owners: Jack Grigg - Conrado Gouvêa + Owners: Jack Grigg + Mark Henderson + Daira-Emma Hopwood Arya Kris Nuttycombe - Original-Authors: Daira-Emma Hopwood - Josh Cincinnati + Sam H. Smith + Sean Bowe + Tal Derei + Dev Ojha + Original-Authors: Josh Cincinnati George Tankersley Deirdre Connolly - teor + Teor Aditya Bharadwaj + Conrado Gouvêa Credits: Luke Dashjr Status: Active Category: Process @@ -52,11 +57,14 @@ This document is based partly on the work done by Luke Dashjr with `BIP 2 `__. +Specification +============= + ZIP Workflow -============ +------------ The ZIP process begins with a new idea for Zcash. Each potential ZIP -must have Owners — one or more people who write the ZIP using the style +MUST have Owners — one or more people who write the ZIP using the style and format described below, shepherd the discussions in the appropriate forums, and attempt to build community consensus around the idea. The ZIP Owners should first attempt to ascertain whether the idea is ZIP-able. @@ -67,9 +75,9 @@ development workflow with a patch submission to the applicable issue tracker. Additionally, many ideas have been brought forward for changing Zcash that have been rejected for various reasons. The first step should be to search past discussions to see if an idea has been considered -before, and if so, what issues arose in its progression. After -investigating past work, the best way to proceed is by posting about the -new idea to the `Zcash Community Forum `__. +before, and if so, what issues arose in its progression. After investigating +past work, the best way to proceed is usually by posting about the new +idea to the `Zcash Community Forum `__. Vetting an idea publicly before going as far as writing a ZIP is meant to save both the potential Owners and the wider community time. Asking @@ -79,27 +87,36 @@ prior discussions (searching the internet does not always do the trick). It also helps to make sure the idea is applicable to the entire community and not just the Owners. Just because an idea sounds good to the Owners does not mean it will work for most people in most areas -where Zcash is used. +where Zcash is used. On the other hand, some Owners may already have +the experience and knowledge of the history of Zcash development needed +to determine whether the idea is applicable without this vetting step. -Once the Owners have asked the Zcash community as to whether an idea -has any chance of acceptance, a draft ZIP should be presented to the +Once the Owners are convinced that an idea has some chance of +acceptance, a ZIP draft should be presented to the `Zcash Community Forum `__. -This gives the Owners a chance to flesh out the draft ZIP to make it -properly formatted, of high quality, and to address additional concerns -about the proposal. Following a discussion, the proposal should be -submitted to the ZIPs git repository [#zips-repo]_ as a pull request. -This draft must be written in ZIP style as described below, and named -with an alias such as ``draft-zatoshizakamoto-42millionzec`` until the -ZIP Editors have assigned it a ZIP number (Owners MUST NOT self-assign -ZIP numbers). +Particularly in the case of first-time submitters, this gives the Owners +a chance to flesh out the ZIP draft to make it properly formatted and +of high quality. It can also allow concerns about the proposal to be +addressed at an early stage, potentially reducing the amount of re-work +required; however, addressing concerns at this stage is *not* a +requirement in order for a ZIP draft to be merged. + +Following a discussion, the proposal should be submitted to the ZIPs git +repository [#zips-repo]_ as a pull request. This draft MUST be written +in ZIP style as described below, and named with an alias such as +``draft-zatoshizakamoto-42millionzec`` until the ZIP Editors have +assigned it a ZIP number (Owners MUST NOT self-assign ZIP numbers). ZIP Owners are responsible for collecting community feedback on both -the initial idea and the ZIP before submitting it for review. However, +the initial idea and the ZIP draft before submitting it for review. However, wherever possible, long open-ended discussions on forums should be avoided. +In some cases the need for a ZIP arises for technical or process reasons +that are not in doubt, in which case a forum discussion might not be +necessary. It is highly recommended that a single ZIP contain a single key proposal or new idea. The more focused the ZIP, the more successful it tends to -be. If in doubt, split your ZIP into several well-focused ones. +be. If in doubt, split your ZIP draft into several well-focused ones. When the ZIP draft is complete, the ZIP Editors will assign the ZIP a number (if that has not already been done) and one or more Categories, @@ -116,9 +133,8 @@ must be solid and must not complicate the protocol unduly. The ZIP Owners may update the draft as necessary in the git repository. Updates to drafts should also be submitted by the Owners as pull requests. - ZIP Numbering Conventions -------------------------- +^^^^^^^^^^^^^^^^^^^^^^^^^ The ZIP Editors currently use the following conventions when numbering ZIPs: @@ -130,19 +146,22 @@ ZIPs: * if it affects only higher layers but is needed for interoperability between node implementations or other parts of the ecosystem, assign a number in the range 300..399; -* if it is specific to an implementation (e.g. zcashd or zebra), assign - a number in the range 400..499; +* if it is specific to an implementation (e.g. `zebra` or `zcashd`), + assign a number in the range 400..499; * if it concerns Consensus Process, assign a number in the range 0..9 - or above 1000; + or 1000..1199; +* if it only describes updates to existing ZIPs and/or the Zcash + Protocol Specification (that will be a complete specification in + themselves after deployment), assign a number in the range + 2000..2999. * try to number ZIPs that should or will be deployed together consecutively (subject to the above conventions), and in a coherent reading order. These conventions are subject to change by consensus of the ZIP Editors. - Transferring ZIP Ownership --------------------------- +^^^^^^^^^^^^^^^^^^^^^^^^^^ It occasionally becomes necessary to transfer ownership of ZIPs to a new Owner. In general, we'd like to retain the original Owner as a @@ -165,29 +184,41 @@ If an author of a ZIP is no longer an Owner, an Original-Authors: field SHOULD be added to the ZIP metadata indicating the original authorship (without email addresses), unless the original author(s) request otherwise. - ZIP Editors ------------ +^^^^^^^^^^^ The current ZIP Editors are: -* Jack Grigg and Kris Nuttycombe, associated with the Electric Coin Company; -* Conrado Gouvêa and Arya, associated with the Zcash Foundation. +* Jack Grigg, Daira-Emma Hopwood, and Kris Nuttycombe in their individual + capacities. +* Arya, associated with the Zcash Foundation. +* Mark Henderson and Sam H. Smith, associated with Shielded Labs. +* Sean Bowe and Tal Derei, associated with Project Tachyon. +* Dev Ojha, associated with Valar Group. All can be reached at zips@z.cash. The current design of the ZIP Process -dictates that there are always at least two ZIP Editors: at least one -from the Electric Coin Company and at least one from the Zcash Foundation. +dictates that there are always at least two ZIP Editors, including at least +one from the Zcash Foundation. ZIP Editors MUST declare any potential or perceived conflict of interest they have relating to their responsibilities as ZIP Editors. +Daira-Emma Hopwood declares a conflict of interest in acting as a ZIP Editor +and as Head of Research and Assurance at Zcash Open Development Lab, and +will endeavour to minimize the downsides of that confluence of roles as far +as possible. +In particular, ze commits to stepping down from the ZIP Editor role after +the deployment of Zcash Shielded Assets, assuming ze is still in a +management role at a company primarily involved with the development of +Zcash at that point. + ZIP Editors MUST be publicly transparent about any external influence or constraints that have been placed or attempted to be placed on their -actions as ZIP Editors (including from the Electric Coin Company, -Zcash Foundation, or other organizations with which the Editors are -associated), whether or not it affects those actions. This should not be -interpreted as requiring ZIP Editors to reveal knowledge of undisclosed -security vulnerabilities or mitigations. +actions as ZIP Editors (including from Zcash Foundation, Shielded Labs, +or other organizations with which the Editors are associated), whether +or not it affects those actions. This should not be interpreted as +requiring ZIP Editors to reveal knowledge of undisclosed security +vulnerabilities or mitigations. Additional Editors may be selected, with their consent, by consensus among the current Editors. @@ -206,38 +237,80 @@ Whenever the ZIP Editors change, the new ZIP Editors SHOULD: * update the email alias, and * invite new Editors to the Zcash Community Forum, and the #zips channel on Discord. -If it has been at least 12 months since the last ZIP Editor change, the ZIP Editors SHOULD: - -* review this ZIP to make sure it reflects current practice. - +Whenever it has been at least 12 months since this ZIP was last reviewed +(whether or not that was a review in response to a ZIP Editor change), the +ZIP Editors SHOULD review this ZIP again to make sure that it reflects +current practice. ZIP Editor Responsibilities ---------------------------- +^^^^^^^^^^^^^^^^^^^^^^^^^^^ The ZIP Editors subscribe to the `Zcash Community Forum. `__ -Each new ZIP SHOULD be submitted as a "pull request" to the ZIPs git -repository [#zips-repo]_. It SHOULD NOT contain a ZIP number unless -one had already been assigned by the ZIP Editors. The pull request -SHOULD initially be marked as a Draft. The ZIP content SHOULD be -submitted in reStructuredText [#rst]_ or Markdown [#markdown]_ -format. Generating HTML for a ZIP is OPTIONAL. - -For each new ZIP that comes in, the ZIP Editors SHOULD: - -* Read the ZIP to check if it is ready: sound and complete. The ideas - must make technical sense, even if they don't seem likely to be - accepted. -* Check that the title accurately describes the content. -* Ensure that the ZIP draft has been sent to the Zcash Community Forum - and as a PR to the ZIPs git repository [#zips-repo]_. -* Ensure that motivation and backward compatibility have been - addressed, if applicable. +Each new ZIP draft SHOULD be submitted as a "pull request" to the ZIPs +git repository [#zips-repo]_. It SHOULD NOT contain a ZIP number unless +one had already been assigned by the ZIP Editors. The ZIP content +SHOULD be submitted in reStructuredText [#rst]_ or Markdown [#markdown]_ +format, and the Status field MUST initially be set to Draft. Generated +HTML MUST NOT be included in the pull request. + +For each new ZIP draft that is received, the ZIP Editors SHOULD: + +* Read the ZIP draft to check if it is ready: sound and complete. The + ideas must make technical sense, even if they don't seem likely to be + accepted. See `Reviewing a ZIP`_ below for further detail. +* Check that the Title, Category, and other metadata fields accurately + describe the content. +* Ensure that a PR has been created for the ZIP draft in the ZIPs git + repository [#zips-repo]_. +* Ensure that the existence of the draft has been announced on the Zcash + Community Forum and the `#zips` channel of the Zcash R&D Discord. * Check that the licensing terms are acceptable for ZIPs. +For proposals to revise an existing ZIP, the ZIP Editors SHOULD: + +* Read the proposed modification to check if it is ready: sound, + complete, and non-disruptive to the ZIP's existing deployments if any. + See `Reviewing a ZIP`_ below for further detail. +* If the proposed changes primarily affect already-deployed aspects + of the Zcash consensus protocol, they SHOULD be specified in an + "Update ZIP" describing the changes to be made, rather than directly + as a pull request modifying the existing ZIP(s) or the Zcash Protocol + Specification. At the discretion of the ZIP Editors, this might not + be needed for compatible changes or clarifications. +* If a change is to be made to an existing ZIP, check that the Title, + Category, and other metadata fields still accurately describe the + modified content. +* If the ZIP has a Change History section, check that it is accurately + updated. If it does not, consider whether the ZIP is a "living ZIP", + and whether a Change History section would be beneficial. +* Ensure that the update has been submitted as a PR to the ZIPs git + repository [#zips-repo]_. +* If the proposed update is substantive and not merely editorial, + ensure that it has been announced on the Zcash Community Forum and + the `#zips` channel of the Zcash R&D Discord. +* Check that the licensing terms are still acceptable for ZIPs. + +Announcing new ZIP drafts and updated ZIPs helps ensure transparency and +encourages timely community engagement and feedback. Such announcements +SHOULD clearly state the ZIP number, title, and a brief summary. + +If an Update ZIP is accepted, it is the responsibility of the ZIP Editors +to apply the changes it describes to any existing specifications, but +this MUST only be done once the Status of the Update ZIP has reached at +least Proposed. + +If a new Revision is added to a ZIP, then its original deployment is +called Revision 0. In some cases the revisions of a ZIP may have +differing deployment Status, which is expressed in the Status field as +described in `ZIP Status Field`_ below. + +The ZIP Editors are also generally responsible for adminstration and +access control of the ZIPs repository [#zips-repo]_. + Reviewing a ZIP ---------------- +^^^^^^^^^^^^^^^ Any ZIP Editor can suggest changes to a ZIP. These suggestions are the opinion of the individual ZIP Editor. Any technical or process review that @@ -245,23 +318,65 @@ ZIP Editors perform is expected to be independent of their contractual or other relationships. ZIP Owners are free to clarify, modify, or decline suggestions from ZIP Editors. -If the ZIP Editors make a change to a ZIP that the Owners disagree with, then -the Editors SHOULD revert the change. +If the ZIP Editors make a change to a ZIP that the Owners object to, then the +Editors MUST either revert the change or provide a public rationale for +overriding the objection. Examples of reasons to override an objection could +be that the change is necessary in order to accurately document the ZIP's +deployment status, to call attention to a security or privacy issue or +significant community opposition, or to enforce a process requirement of this +or another ZIP. + +If a previous publication or update is found after-the-fact to have been made +in a way that violated a process requirement, the ZIP Editors MAY revert it. +Any changes to a ZIP by the ZIP Editors SHOULD be communicated to the ZIP Owners. Typically, the ZIP Editors suggest changes in two phases: -* `content review`: multiple ZIP Editors discuss the ZIP, and suggest - changes to the overall content. This is a "big picture" review. +* `content review`: multiple ZIP Editors discuss the ZIP draft or update, and + suggest changes to the overall content. This is a "big picture" review. * `format review`: two ZIP Editors do a detailed review of the - structure and format of the ZIP. This ensures the ZIP is consistent - with other Zcash specifications. + structure and format of the ZIP draft. This ensures the ZIP draft is + consistent with other Zcash specifications. -If the ZIP isn't ready, the Editors will send it back to the Owners for +The content review is where general weaknesses in the ZIP draft should +be identified, which might include: + +* Insufficient or unclear motivation. +* Unclear, under-documented, or missing privacy implications. +* Significant objectives of the ZIP draft that are not clearly documented in + the `Requirements` section. +* Missing trust assumptions. +* Security risks that are insufficiently addressed. +* Unaddressed backward compatibility issues. + +In addition, ZIP Editors may request input from community security or +privacy experts for proposals with significant implications. + +Note that it is not the primary responsibility of the ZIP Editors to +review proposals for security, correctness, or implementability. + +If the ZIP draft isn't ready, the Editors SHOULD make suggestions to the Owners +for the ZIP draft to be revised. + +If a pull request exclusively updates ZIP drafts owned by the PR creator (and is +free from spam, abusive or malicious content, etc.), then the ZIP Editors SHOULD +approve it without any need for substantive editorial review, so that the Owners +are able to merge their changes into the ``main`` branch essentially at will. + +If changes to a ZIP draft are merged into ``main``, an issue tracking the +ZIP draft MUST be opened if one is not open already. In this situation, any +outstanding suggestions or comments that need to be addressed before the ZIP +draft can be converted to a numbered ZIP SHOULD be moved to this issue. + +If the ZIP draft isn't ready, the Editors will send it back to the Owners for revision, with specific instructions. This decision is made by consensus among the current Editors. -When a ZIP is ready, the ZIP Editors will: +Format review should generally occur after content review feedback has +been addressed, to avoid unnecessary document churn or merge conflicts. + +When a ZIP draft is ready, the ZIP Editors will: * Ensure that a unique ZIP number has been assigned in the pull request. * Regenerate the corresponding HTML documents, if required. @@ -271,9 +386,9 @@ The ZIP editors monitor ZIP changes and update ZIP headers as appropriate. Rejecting a ZIP or update -------------------------- +^^^^^^^^^^^^^^^^^^^^^^^^^ -The ZIP Editors MAY reject a new ZIP or an update to an existing ZIP, +The ZIP Editors MAY reject a new ZIP draft or an update to an existing ZIP, by consensus among the current Editors. Rejections can be based on any of the following reasons: @@ -284,6 +399,7 @@ of the following reasons: are not excluded for this reason); * it has manifest security flaws (including being unrealistically dependent on user vigilance to avoid security weaknesses); +* it fails to adequately consider privacy implications; * it disregards compatibility with the existing Zcash blockchain or ecosystem; * it is manifestly unimplementable; * it includes buggy code, pseudocode, or algorithms; @@ -297,11 +413,11 @@ of the following reasons: adoption of the ZIP; * it includes commercial advertising or spam; * it disregards formatting rules; -* it makes non-editorial edits to previous entries in a ZIP's Change history, +* it makes non-editorial edits to previous entries in a ZIP's Change History, if there is one; * an update to an existing ZIP extends or changes its scope to an extent that would be better handled as a separate ZIP; -* a new ZIP has a category that does not reflect its content, or an update +* a new ZIP draft has a category that does not reflect its content, or an update would change a ZIP to an inappropriate category; * it violates any specific "MUST" or "MUST NOT" rule in this document; * the expressed political views of a Owner of the document are inimical @@ -313,17 +429,14 @@ of the following reasons: * it violates a conformance requirement of any Active Process ZIP (including this ZIP). -The ZIP Editors MUST NOT unreasonably deny publication of a ZIP proposal +The ZIP Editors MUST NOT unreasonably deny publication of a ZIP draft or update that does not violate any of these criteria. If they refuse a proposal or update, they MUST give an explanation of which of the criteria were violated, with the exception that spam may be deleted without an explanation. -Note that it is not the primary responsibility of the ZIP Editors to -review proposals for security, correctness, or implementability. - Communicating with the ZIP Editors ----------------------------------- +^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ Please send all ZIP-related communications either: @@ -331,11 +444,10 @@ Please send all ZIP-related communications either: * by opening an issue on the `ZIPs issue tracker `_, or * by sending a message in the `#zips channel on the Zcash R&D Discord `_. -**All communications should abide by the Zcash Code of Conduct** [#conduct]_ -**and follow the GNU Kind Communication Guidelines** [#gnukind]_. +**All communications should abide by the Zcash Code of Conduct** [#conduct]_. ZIP Editor Meeting Practices ----------------------------- +^^^^^^^^^^^^^^^^^^^^^^^^^^^^ The ZIP Editors SHOULD meet on a regular basis to review draft changes to ZIPs. Meeting times are agreed by consensus among the current ZIP Editors. @@ -357,7 +469,7 @@ If the draft agenda is empty, any ZIP Editor MAY submit agenda items, or suggest that the meeting is cancelled. ZIP format and structure -======================== +------------------------ ZIPs SHOULD be written in reStructuredText [#rst]_, Markdown [#markdown]_, or LaTeX [#latex]_. For ZIPs written in LaTeX, a ``Makefile`` MUST be @@ -373,13 +485,50 @@ Each ZIP SHOULD have the following parts: * Terminology — Definitions of technical or non-obvious terms used in the document. -* Abstract — A short (~200 word) description of the technical issue - being addressed. +* Abstract — The abstract SHOULD be a concise summary (approximately + 200 words) that clearly describes the issue the ZIP addresses, the + proposed solution, and the intended outcome. The ZIP MUST remain + complete without the abstract. + + The abstract SHOULD, as far as practical, provide enough context for + readers to quickly understand what the ZIP is about, why it matters, + and how it fits into the broader Zcash ecosystem. In addition to + summarizing the technical content, the abstract SHOULD briefly mention + any significant privacy implications. The abstract should not be + vague or overly generic, but should serve as a faithful, high-level + summary of the proposal that enables reviewers to understand the key + ideas and potential implications without reading the entire document. * Motivation — The motivation is critical for ZIPs that want to change the Zcash protocol. It should clearly explain why the existing protocol is inadequate to address the problem that the ZIP solves. +* Privacy Implications — This section SHOULD be present if the ZIP makes + trade-offs or assumptions that could impact the privacy of Zcash users + or protocol participants. Since this section is not part of the + Specification, it MUST NOT directly include or duplicate conformance + requirements on implementations or processes. Instead it contains a + high-level overview of the privacy implications that may need to be + considered for deployment of the ZIP. + + The contents of this section could include, for example, trust assumptions + affecting privacy that are introduced or modified by the proposal; privacy + trade-offs or changes to anonymity guarantees; potential data leakage + (e.g., from metadata, timing, or usage patterns); and exposure to known + or novel privacy attack vectors. Proposals SHOULD consider any relevant + threat model(s), and SHOULD propose updates to those threat models if the + ZIP introduces new privacy-relevant assumptions or risks not currently + addressed. + + If a change affects how wallets construct, interpret, or expose + transaction data, or modifies user-facing protocol behavior, the ZIP + SHOULD assess the implications for user privacy in that context. + +* Requirements — This section describes high-level goals that the + Specification MUST ensure. It MUST NOT itself include conformance + requirements, so that it is possible to perform a consistency check + that what is specified meets the Requirements. + * Specification — The technical specification should describe the interface and semantics of any new feature. The specification should be detailed enough to allow competing, interoperable implementations for @@ -439,11 +588,6 @@ Each ZIP SHOULD have the following parts: -* Security and privacy considerations — If applicable, security - and privacy considerations should be explicitly described, particularly - if the ZIP makes explicit trade-offs or assumptions. For guidance on - this section consider RFC 3552 [#RFC3552]_ as a starting point. - * Reference implementation — Literal code implementing the ZIP's specification, and/or a link to the reference implementation of the ZIP's specification. The reference implementation MUST be @@ -451,8 +595,16 @@ Each ZIP SHOULD have the following parts: but it generally need not be completed before the ZIP is accepted into “Proposed”. +* Change History — A list of dates, each with details of any semantic changes + made to the ZIP (not editorial changes). This section is OPTIONAL; if present, + the Preamble MUST include a Last-Updated field. It is RECOMMENDED to include + this section in "living ZIPs" (Released ZIPs to which semantic changes are + made after their initial transition out of Draft). If a ZIP that already + contains a Change History section is modified with semantic changes, the + Change History section and Last-Updated field MUST also be updated. + ZIP stubs ---------- +^^^^^^^^^ A ZIP stub records that the ZIP Editors have reserved a number for a ZIP that is under development. It is not a ZIP, but exists in the ZIPs @@ -465,7 +617,7 @@ at the discretion of the ZIP Editors. If a ZIP stub is removed then its number MAY be reused, possibly for an entirely different ZIP. ZIP header preamble -------------------- +^^^^^^^^^^^^^^^^^^^ Each ZIP or ZIP stub MUST begin with a RFC 822-style header preamble. For ZIPs and ZIP stubs written in reStructuredText, this is represented @@ -488,6 +640,7 @@ The following additional header fields are OPTIONAL for ZIPs:: Original-Authors: Discussions-To: Pull-Request: + Last-Updated: Obsoleted-By: Updated-By: Obsoletes: @@ -529,16 +682,15 @@ For ZIPs written in reStructuredText, URLs in header fields SHOULD be surrounded by ``<`` ``>``; this ensures that the link is rendered correctly. Auxiliary Files ---------------- +^^^^^^^^^^^^^^^ ZIPs may include auxiliary files such as diagrams. Auxiliary files should be included in a subdirectory for that ZIP; that is, for any ZIP that requires more than one file, all of the files SHOULD be in a subdirectory named zip-XXXX. - ZIP categories -============== +-------------- Each ZIP is in one or more of the following categories, as specified in the Category header: @@ -570,7 +722,7 @@ Informational Network Specifications of peer-to-peer networking behaviour. RPC - Specifications of the RPC interface provided by zcashd nodes. + Specifications of the RPC interface provided by `zebra` or `zcashd` nodes. Wallet Specifications affecting wallets (e.g. non-consensus changes to how transactions, addresses, etc. are constructed or interpreted). @@ -586,9 +738,8 @@ Consensus ZIPs SHOULD have a Deployment section, describing how and when the consensus change is planned to be deployed (for example, in a particular network upgrade). - ZIP Status Field -================ +---------------- * Reserved: The ZIP Editors have reserved this ZIP number, and there MAY be a Pull Request for it, but no ZIP has been published. The ZIP Editors @@ -616,7 +767,7 @@ ZIP Status Field * Implemented: When a Consensus or Standards ZIP has a working reference implementation but before activation on the Zcash network. The status MAY indicate which node implementation has implemented - the ZIP, e.g. "Implemented (zcashd)" or "Implemented (zebra)". + the ZIP, e.g. "Implemented (zebra)" or "Implemented (zcashd)". * Final: When a Consensus or Standards ZIP is both implemented and activated on the Zcash network. @@ -624,8 +775,22 @@ ZIP Status Field * Obsolete: The status when a ZIP is no longer relevant (typically when superseded by another ZIP). +If a ZIP has multiple Revisions, they may have differing deployment +status. In that case the status of every Revision SHOULD be specified, +using the format "[Revision 0] , [Revision 1] , ..." +where "" is one of the alternatives above. + +Once any Revision has been Released (as defined in the next section), +all subsequent Revisions MUST also be at least Proposed (that is, +they MUST NOT be Reserved or Draft). For example, a status such as: + + [Revision 0] Final, [Revision 1] Draft + +is not valid, because changes that are in Draft should not have been +applied yet. + Specification of Status Workflow --------------------------------- +^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ Owners of a ZIP MAY decide on their own to change the status between Draft or Withdrawn. All other changes in status MUST be approved by @@ -641,6 +806,14 @@ will specify a network upgrade in which the consensus change is to activate. A ZIP's status is Released if it is Proposed, Active, Implemented, or Final (i.e. not Draft, Rejected, Obsolete, or Withdrawn). +A ZIP that has significant security or privacy implications MUST NOT +be changed from a non-Released status to a Released status without the +design having undergone independent security review from qualified +security or privacy experts. Similarly, changes to a Released ZIP that might +invalidate the conclusions of previous security or privacy review, or leave +significant security or privacy implications unaddressed, MUST undergo +further independent review. + A ZIP SHOULD NOT be changed from a non-Released status to a Released status if there is significant community opposition to its content. (However, Draft ZIPs explicitly MAY describe proposals to which there @@ -653,7 +826,7 @@ Process ZIP still reflects a consensus of the community. A Standards ZIP SHOULD only change status from Proposed to Implemented once the Owners provide an associated reference implementation. For Consensus ZIPs, an implementation MUST have been merged into at least -one consensus node codebase (currently zcashd and/or zebra), typically +one consensus node codebase (currently `zebra` and/or `zcashd`), typically in the period after the network upgrade's specification freeze but before the implementation audit. If the Owners miss this deadline, the Editors or Owners MAY choose to update the Deployment section of the ZIP to @@ -679,17 +852,17 @@ another specified ZIP or ZIPs (check the optional Updated-By header). If a non-editorial update is made to an Obsolete, Withdrawn, or Rejected ZIP, its status MUST be changed appropriately. +The above process also applies to any subsequent Revisions of a ZIP. ZIP Comments -============ +------------ Comments from the community on the ZIP should occur on the Zcash Community Forum and the comment fields of the pull requests in any open ZIPs. Editors will use these sources to judge rough consensus. - ZIP Licensing -============= +------------- New ZIPs may be accepted with the following licenses. Each new ZIP MUST identify at least one acceptable license in its preamble. Each license @@ -721,7 +894,7 @@ acceptable license(s) should be listed in the License header. Recommended licenses --------------------- +^^^^^^^^^^^^^^^^^^^^ * MIT: `Expat/MIT/X11 license `__ * BSD-2-Clause: `OSI-approved BSD 2-clause @@ -735,14 +908,17 @@ Recommended licenses * Apache-2.0: `Apache License, version 2.0 `__ -In addition, it is RECOMMENDED that literal code included in the ZIP be -dual-licensed under the same license terms as the project it modifies. -For example, literal code intended for zcashd would ideally be -dual-licensed under the MIT license terms as well as one of the above -with the rest of the ZIP text. +In addition, it is RECOMMENDED that literal code included in the ZIP, or +written for and linked by the ZIP, be multi-licensed under the union of the +license(s) of the project(s) it is intended to be used by. In particular, +code intended for `zebra`, `zcashd`, `Zallet`, `Zaino`, or their dependencies +SHOULD be multi-licensed under at least the MIT and Apache-2.0 license terms. + +If a ZIP links to a reference implementation that does not follow the above +recommendation, its license terms MUST be documented in the ZIP. Not recommended, but acceptable licenses ----------------------------------------- +^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ * BSL-1.0: `Boost Software License, version 1.0 `__ @@ -750,23 +926,17 @@ Not recommended, but acceptable licenses International `__ * CC-BY-SA-4.0: `Creative Commons Attribution-ShareAlike 4.0 International `__ -* AGPL-3.0+: `GNU Affero General Public License (AGPL), version 3 or - newer `__ * FDL-1.3: `GNU Free Documentation License, version 1.3 `__ -* GPL-2.0+: `GNU General Public License (GPL), version 2 or - newer `__ -* LGPL-2.1+: `GNU Lesser General Public License (LGPL), version 2.1 or - newer `__ Not acceptable licenses ------------------------ +^^^^^^^^^^^^^^^^^^^^^^^ All licenses not explicitly included in the above lists are not acceptable terms and MUST NOT be used for a Zcash Improvement Proposal. Rationale ---------- +^^^^^^^^^ Bitcoin's BIP 1 allowed the Open Publication License or releasing into the public domain; was this insufficient? @@ -787,6 +957,16 @@ Why are there software licenses included? * Despite this, not all software licenses would be acceptable for content included in ZIPs. +Why are GPL/AGPL/LGPL-style licenses not included? + +* No existing ZIP had used these licenses. +* There is no reason to use such licenses for documentation, and including + literal code under these licenses in a ZIP could undesirably affect the + distribution terms of the ZIP as a whole. +* If necessary, code under such licenses can be linked for informational + purposes, or as long as its incompatibility with the `zebra`, `zcashd`, + `Zallet`, and/or `Zaino` licenses is noted. + See Also ======== @@ -799,18 +979,16 @@ See Also Acknowledgements ================ -We thank George Tankersley, Deirdre Connolly, Daira-Emma Hopwood, teor, -and Aditya Bharadwaj for their past contributions as ZIP Editors. +We thank George Tankersley, Deirdre Connolly, Teor, Aditya Bharadwaj, and +Conrado Gouvêa for their past contributions as ZIP Editors. 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" `_ -.. [#RFC3552] `RFC 3552: Guidelines for Writing RFC Text on Security Considerations `_ .. [#zip-0200] `ZIP 200: Network Upgrade Mechanism `_ .. [#conduct] `Zcash Code of Conduct `_ -.. [#gnukind] `GNU Kind Communication Guidelines `_ .. [#rst] `reStructuredText documentation `_ .. [#markdown] `The Markdown Guide `_ .. [#latex] `LaTeX — a document preparation system `_ diff --git a/zips/zip-0032.rst b/zips/zip-0032.rst index 69817e5a3..7360d1f1b 100644 --- a/zips/zip-0032.rst +++ b/zips/zip-0032.rst @@ -2,8 +2,8 @@ ZIP: 32 Title: Shielded Hierarchical Deterministic Wallets - Owners: Jack Grigg - Daira-Emma Hopwood + Owners: Jack Grigg + Daira-Emma Hopwood Credits: Sean Bowe Kris Nuttycombe Ying Tong Lai @@ -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 =========== @@ -25,6 +25,8 @@ interpreted as described in BCP 14 [#BCP14]_ when, and only when, they appear in "Jubjub" refers to the elliptic curve defined in [#protocol-jubjub]_. +A "cryptovalue" is a high-entropy value used in a cryptographic protocol that is not necessarily a key. + A "chain code" is a cryptovalue that is needed, in addition to a spending key, in order to derive descendant keys and addresses of that key. @@ -64,8 +66,8 @@ Zcash's transparent addresses [#slip-0044]_) generate keys and addresses determi advantages over random generation: - Wallets only need to store a single seed (particularly useful for hardware wallets). -- A one-time backup of the seed (usually stored as a word phrase [#bip-0039]_) can be used to recover funds - from all future addresses. +- A one-time backup of the seed (usually stored as a BIP 39 mnemonic [#bip-0039]_ or SLIP 39 shares + [#slip-0039]_) can be used to recover funds from all future addresses. - Keys are arranged into a tree of chains, enabling wallets to represent "accounts" or other high-level structures. - Viewing authority or spending authority can be delegated independently for sub-trees without compromising @@ -83,64 +85,112 @@ 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]_: + +- $\mathsf{CKDfvk}(\mathsf{CKDfvk}(\mathsf{CKDfvk}(m_\mathsf{Sapling}, a), b), c)$ is written as $m_\mathsf{Sapling} / a / b / c$. + +Note: no corresponding notation is currently defined for the result of +`Hardened-only child key derivation`_ with non-zero $\mathsf{lead}$ and/or non-empty $\mathsf{tag}$. + + +Specification: Wallet seeds +=========================== + +Several of the key derivation algorithms specified in this ZIP derive a master key from a +seed byte sequence. Any such seed byte sequence MUST be at least 32 and at most 252 bytes. + +The method of generating such a seed byte sequence for Zcash purposes MUST ensure that it +has at least 256 bits of entropy. This requirement also applies to any mnemonic or input +randomness used to obtain the seed byte sequence. See ZIP 315 [#zip-0315-wallet-seeds]_ for +further guidance. + +Rationale for the 256-bit entropy requirement +--------------------------------------------- + +.. raw:: html + +
    + Click to show/hide + +Zcash consistently uses cryptovalues of length at or close to 256 bits, throughout its +cryptographic design. Although the target security level for the protocol against classical +cryptanalytic attacks is $2^{125}$ (i.e. any such attack should take at least $2^{125}$ +operations, as explained in [#zcash-security]_), this does not imply that 128-bit keys or +seeds are sufficient. The apparent gap between the security target and the key length is +well motivated: it provides better resistance to attacks using parallel hardware +[#Bernstein2005]_ in the multi-user setting [#Zaverucha2012]_; it takes into account small +entropy losses in the key derivation process; and it simplifies the analysis of the protocol +against quantum attacks for unknown addresses [#zcash-security]_, or in the context of a +future post-quantum recovery protocol [#zip-2005]_. + +In particular, for the hierarchical key derivation method described in this ZIP, if the seed +or mnemonic has entropy less than 256 bits, it will be a weak link in the derivation of +*all* keys belonging to that wallet. -- :math:`\mathsf{CKDfvk}(\mathsf{CKDfvk}(\mathsf{CKDfvk}(m_\mathsf{Sapling}, a), b), c)` is written as :math:`m_\mathsf{Sapling} / a / b / c`. +It should be noted that an adversary can search for uses of lower-entropy mnemonics across +multiple wallets simultaneously. They can collect a large set of (transparent or shielded) +target addresses and/or viewing keys, and then perform a brute-force search over mnemonics +in a lower-entropy subspace, efficiently checking whether the first few addresses or viewing +keys that would be generated from each mnemonic match any of the targets. + +.. raw:: html + +
    Specification: Sapling key derivation @@ -163,110 +213,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 meeting the requirements in `Specification: Wallet seeds`_. -- 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 +333,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 +381,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. @@ -365,50 +415,56 @@ non-hardened derivation appear. With that in mind, we now have a general hardene process that retains compatibility with existing derivation path semantics (to enable deriving the same path across multiple contexts). +The functions defined in this section are intended for internal use by context-specific mechanisms in +subsequent sections, rather than for direct use. + 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)` +As well as the integer child index $i$, the child key derivation function defined here supports a +lead byte $\mathsf{lead}$ (used for domain separation) and byte sequence $\mathsf{tag}$. Each triple +$(i, \mathsf{lead}, \mathsf{tag})$ produces an independent output. -- Check whether :math:`i \geq 2^{31}` (whether the child is a hardened key). +$\mathsf{CKDh}^\mathsf{Context}((\mathsf{sk}_{par}, \mathsf{c}_{par}), i, \mathsf{lead}, \mathsf{tag})$ $\rightarrow (\mathsf{sk}_{child}, \mathsf{c}_{child})$ : - - If so (hardened child): let - :math:`I = \mathsf{PRF^{expand}}(\mathsf{c}_{par}, [\mathsf{Context.CKDDomain}]\,||\,\mathsf{sk}_{par}\,||\,\mathsf{I2LEOSP}_{32}(i))`. - - If not (normal child): return failure. +- If $i < 2^{31}$ (non-hardened child index): return failure. +- Let $\mathsf{lead\_enc} = \begin{cases} \,[\,],&\!\!\textsf{if } \mathsf{lead} = 0 \textsf{ and } \mathsf{tag} = [\,] \\ \,[\mathsf{lead}],&\!\!\textsf{otherwise.}\end{cases}$ +- Let $I = \mathsf{PRF^{expand}}(\mathsf{c}_{par}, [\mathsf{Context.CKDDomain}]\,||\,\mathsf{sk}_{par}\,||\,\mathsf{I2LEOSP}_{32}(i)\,||\,\mathsf{lead\_enc}\,||\,\mathsf{tag})$. +- Split $I$ into two 32-byte sequences, $I_L$ and $I_R$. +- Return $(I_L, I_R)$. -- 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)`. +Note that in the input to $\mathsf{PRF^{expand}}$, the case $\mathsf{lead} = 0$ and $\mathsf{tag} = [\,]$ +is encoded in a way compatible with the definition of $\mathsf{CKDh}$ in previous versions of this +specification (before $\mathsf{lead}$ and $\mathsf{tag}$ were added). Specification: Orchard key derivation @@ -417,29 +473,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 meeting the requirements in `Specification: Wallet seeds`_. -- 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, 0, [\,])$ 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 +510,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}}\big(\mathsf{PRF}^{\mathsf{expand}}_{K}\big([\mathtt{0x83}] \,||\, \mathsf{I2LEOSP_{256}}(\mathsf{ak}) \,||\, \mathsf{I2LEOSP_{256}}(\mathsf{nk})\kern-0.1em\big)\kern-0.15em\big)$. +- 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: @@ -489,8 +545,8 @@ Account level. It was implemented in `zcashd` as part of support for ZIP 316 [#z Note that the resulting FVK may be invalid, as specified in [#protocol-orchardkeycomponents]_. -Orchard diversifier derivation ------------------------------- +Orchard diversifier and OVK 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 @@ -499,57 +555,145 @@ 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)`: +Let $\mathsf{DeriveDkAndOvk^{Orchard}}$ be as defined in [#protocol-orchardkeycomponents]_. + +Given an Orchard full viewing key $(\mathsf{ak}, \mathsf{nk}, \mathsf{rivk})$ (which may be +either external or internal): + +- $(\mathsf{dk}, \mathsf{ovk}) = \mathsf{DeriveDkAndOvk^{Orchard}}(\mathsf{rivk}, \mathsf{ak}, \mathsf{nk})$. +- Let $j$ be the index of the desired diversifier, in the range $0\,..\, 2^{88} - 1$. +- $\mathsf{d}_j = \mathsf{FF1}\text{-}\mathsf{AES256.Encrypt}\big(\mathsf{dk}, \texttt{“”}, \mathsf{I2LEBSP}_{88}(j)\kern-0.1em\big)$. -- 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))`. +Note that unlike Sapling, all Orchard diversifiers are valid, and thus all possible values +of $j$ yield valid diversifiers. -Note that unlike Sapling, all Orchard diversifiers are valid, and thus all possible values of :math:`j` yield -valid diversifiers. +The default diversifier for $(\mathsf{ak}, \mathsf{nk}, \mathsf{rivk})$ is defined to be +$\mathsf{d}_0.$ -The default diversifier for :math:`(\mathsf{sk}_i, \mathsf{c}_i)` is defined to be :math:`d_{i,0}.` +No mechanism is provided to derive distinct Outgoing Viewing Keys ($\!\mathsf{ovk}$) for +each diversified address. This is because payments are sent from accounts (with external +or internal scope), not from specific diversified addresses [#zip-0316-usage-of-outgoing-viewing-keys]_. -Specification: Arbitrary key derivation -======================================= +Specification: Registered key derivation +======================================== -In some contexts there is a need for deriving arbitrary keys with the same derivation path as -existing key material (for example, deriving an arbitrary account-level key), without the need for -ecosystem-wide coordination. The following instantiation of the hardened key generation process may -be used for this purpose. +In the context of a particular application protocol defined by a ZIP, there is sometimes +a need to define an HD subtree that will not collide with keys derived for other protocols, +as far as that is possible to assure by following the ZIP process [#zip-0000]_. -Let :math:`\mathsf{ContextString}` be a globally-unique non-empty sequence of at most 252 bytes +Within this subtree, the application protocol may use derivation paths related to those +used for existing key material — for example, to derive an account-level key. The following +instantiation of the hardened key generation process may be used for this purpose. + +It is strongly RECOMMENDED that implementors ensure that documentation of the context +string(s), and the usage and derivation paths of the application protocol's key tree in +the corresponding ZIP are substantially complete, before public deployment of software +or hardware using this mechanism. The ZIP process allows for subsequent updates and +corrections. + +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{Registered.MKGDomain} = \texttt{“ZIPRegistered\_KD”}$ +- $\mathsf{Registered.CKDDomain} = \mathtt{0xAC}$ + +Registered subtree root key generation +-------------------------------------- + +Let $S$ be a seed byte sequence meeting the requirements in `Specification: Wallet seeds`_. + +The registered subtree root is obtained as: + +$\mathsf{RegKD}(\mathsf{ContextString}, \mathsf{S}, \mathsf{ZipNumber})$ $\rightarrow (\mathsf{sk}_{subtree}, \mathsf{c}_{subtree})$ : -Arbitrary master key generation +- Let $(\mathsf{sk}_{m}, \mathsf{c}_{m}) = \mathsf{MKGh}^\mathsf{Registered}([\mathsf{length}(\mathsf{ContextString})]\,||\,\mathsf{ContextString}\,||\,[\mathsf{length}(S)]\,||\,S)$. +- Return $\mathsf{CKDh}^\mathsf{Registered}((\mathsf{sk}_{m}, \mathsf{c}_{m}), \mathsf{ZipNumber} + 2^{31}, 0, [\,])$. + +Note: The intermediate key $(\mathsf{sk}_{m}, \mathsf{c}_{m})$ would grant the ability to derive the +subtree root for application protocols defined in *any* ZIP using the same $\mathsf{ContextString}$ +and seed. This is a potentially dangerous scope of grant since it cannot be known what future +protocols will use this mechanism; therefore, $(\mathsf{sk}_{m}, \mathsf{c}_{m})$ SHOULD NOT be +used or stored directly without careful consideration of security consequences. + +Registered child key derivation ------------------------------- -Let :math:`S` be a seed byte sequence of a chosen length, which MUST be at least 32 and at most 252 bytes. +As well as the integer child index $i$, the child key derivation function defined here supports a +byte sequence $\mathsf{tag}$; each pair $(i, \mathsf{tag})$ produces a different child key. If an +explicit tag is not required, $\mathsf{tag}$ is set to the empty byte sequence. -The master extended arbitrary key is: +Note: The tag MUST use an unambiguous encoding within the given context. 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:`m_\mathsf{Arbitrary} = \mathsf{MKGh}^\mathsf{Arbitrary}([\mathsf{length}(\mathsf{ContextString})]\,||\,\mathsf{ContextString}\,||\,[\mathsf{length}(S)]\,||\,S)\!`. +$\mathsf{CKDreg}((\mathsf{sk}_{par}, \mathsf{c}_{par}), i, \mathsf{tag})$ $\rightarrow (\mathsf{sk}_{child}, \mathsf{c}_{child})$ : -Arbitrary child key derivation ------------------------------- +- Return $\mathsf{CKDh}^\mathsf{Registered}((\mathsf{sk}_{par}, \mathsf{c}_{par}), i, 0, \mathsf{tag})$. + +Full-width child cryptovalue derivation +--------------------------------------- + +If the application protocol requires a 64-byte cryptovalue (for example, to avoid an entropy +bottleneck in its subsequent operations), then a similar process to `Registered child key derivation`_ +above can be used to obtain such a cryptovalue at a given child index; again with optional tag. +The same considerations about encoding of the $\mathsf{tag}$ apply as above. + +$\mathsf{derive\_child\_cryptovalue}((\mathsf{sk}_{par}, \mathsf{c}_{par}), i, \mathsf{tag})$ $\rightarrow \mathsf{K}_{child}$ : + +- Let $(I_L, I_R) = \mathsf{CKDh}^\mathsf{Registered}((\mathsf{sk}_{par}, \mathsf{c}_{par}), i, 1, \mathsf{tag})$. +- Return $I_L\,||\,I_R$. + +For the avoidance of doubt, the output of $\mathsf{derive\_child\_cryptovalue}$ +MUST NOT be provided as input to any key derivation function defined in ZIP 32. +In particular, it MUST NOT be reinterpreted directly or indirectly as an input to +$\mathsf{CKDh}$. + + +Specification: Ad-hoc key derivation (deprecated) +================================================= + +For compatibility with existing deployments, we also define a mechanism to derive ad-hoc +key trees for private use by applications, without ecosystem coordination. This was called +"arbitrary key derivation" in previous iterations of this ZIP, but that term caused confusion +as to the applicability of the mechanism. + +Since there is no guarantee of non-collision between different application protocols, and no +way to tie these key trees to well-defined specification or documentation processes, use of +this mechanism is NOT RECOMMENDED for new protocols. -:math:`\mathsf{CKDarb}((\mathsf{sk}_{par}, \mathsf{c}_{par}), i)`:math:`\rightarrow (\mathsf{sk}_i, \mathsf{c}_i)` +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 derivation process with the following constants: + +- $\mathsf{Adhoc.MKGDomain} = \texttt{“ZcashArbitraryKD”}$ +- $\mathsf{Adhoc.CKDDomain} = \mathtt{0xAB}$ + +Ad-hoc master key generation (deprecated) +----------------------------------------- + +Let $S$ be a seed byte sequence meeting the requirements in `Specification: Wallet seeds`_. + +The master extended ad-hoc key is: -- Return :math:`\mathsf{CKDh}^\mathsf{Arbitrary}((\mathsf{sk}_{par}, \mathsf{c}_{par}), i)\!`. +$m_\mathsf{Adhoc} = \mathsf{MKGh}^\mathsf{Adhoc}([\mathsf{length}(\mathsf{ContextString})]\,||\,\mathsf{ContextString}\,||\,[\mathsf{length}(S)]\,||\,S)$. -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). +Ad-hoc child key derivation (deprecated) +---------------------------------------- + +$\mathsf{CKDarb}((\mathsf{sk}_{par}, \mathsf{c}_{par}), i)$ $\rightarrow (\mathsf{sk}_i, \mathsf{c}_i)$ : + +- Return $\mathsf{CKDh}^\mathsf{Adhoc}((\mathsf{sk}_{par}, \mathsf{c}_{par}), i, 0, [\,])$. + +Note: a previous iteration of this ZIP suggested that, if $i$ is the last element of an HD path +(i.e. no extension of this path is used), then the concatenation $\mathsf{sk}_i\,||\,\mathsf{c}_i$ +could be used as a 64-bit key. This is NOT RECOMMENDED, because it is difficult to define safe APIs +that enforce the restriction that a given node in the key tree must not be used both in this way +and to derive further child keys. `Full-width child cryptovalue derivation`_ provides a safe way to +obtain the same functionality for new application protocols. Specification: Wallet usage @@ -565,18 +709,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 +736,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 +765,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 +784,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 +798,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,12 +812,15 @@ 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. +The string encoding of a seed fingerprint uses Bech32m with the Human-Readable Part +``zip32seedfp``, and the fingerprint bytes as the data. + No corresponding short tag is defined. Note: a previous version of this specification did not have the length byte prefixing the seed. @@ -691,14 +838,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 +853,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 +868,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 +890,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. @@ -756,7 +903,9 @@ for Sprout, and therefore SHOULD NOT be used in future Zcash-related specificati Test Vectors ============ -TBC +Test vectors are available at in the +`sapling_zip32`, `sapling_zip32_hard`, `orchard_zip32`, `zip_0032_registered`, and +`zip_0032_arbitrary` files for each format. Reference Implementation @@ -774,11 +923,11 @@ 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" `_ .. [#bip-0032] `BIP 32: Hierarchical Deterministic Wallets `_ .. [#bip-0039] `BIP 39: Mnemonic code for generating deterministic keys `_ +.. [#slip-0039] `SLIP 39: Shamir's Secret-Sharing for Mnemonic Codes `_ .. [#bip-0043] `BIP 43: Purpose Field for Deterministic Wallets `_ .. [#bip-0044] `BIP 44: Multi-Account Hierarchy for Deterministic Wallets `_ .. [#slip-0044] `SLIP 44: Registered coin types for BIP-0044 `_ .. [#bip-0173] `BIP 173: Base32 address format for native v0-16 witness outputs `_ -.. [#zip-0316] `ZIP 316: Unified Addresses and Unified Viewing Keys `_ .. [#protocol] `Zcash Protocol Specification, Version 2022.2.19 or later [NU5 proposal] `_ .. [#protocol-networks] `Zcash Protocol Specification, Version 2022.2.19. Section 3.12: Mainnet and Testnet `_ .. [#protocol-saplingkeycomponents] `Zcash Protocol Specification, Version 2022.2.19. Section 4.2.2: Sapling Key Components `_ @@ -793,3 +942,11 @@ References .. [#protocol-orchardfullviewingkeyencoding] `Zcash Protocol Specification, Version 2022.2.19. Section 5.6.4.4: Orchard Raw Full Viewing Keys `_ .. [#protocol-orchardspendingkeyencoding] `Zcash Protocol Specification, Version 2022.2.19. Section 5.6.4.5: Orchard Spending Keys `_ .. [#NIST-SP-800-38G] `NIST Special Publication 800-38G — Recommendation for Block Cipher Modes of Operation: Methods for Format-Preserving Encryption `_ +.. [#zcash-security] `Understanding the Security of Zcash. Presentation by Daira-Emma Hopwood at Zcon3 `_ (`slides `_). +.. [#Bernstein2005] `Understanding brute force. Daniel Bernstein, 2005. `_ +.. [#Zaverucha2012] `Hybrid Encryption in the Multi-User Setting. Gregory M. Zaverucha, 2012. `_ +.. [#zip-0000] `ZIP 0: ZIP Process `_ +.. [#zip-0315-wallet-seeds] `ZIP 315: Best Practices for Wallet Implementations — Specification: Wallet seeds `_ +.. [#zip-0316] `ZIP 316: Unified Addresses and Unified Viewing Keys `_ +.. [#zip-0316-usage-of-outgoing-viewing-keys] `ZIP 316: Unified Addresses and Unified Viewing Keys — Usage of Outgoing Viewing Keys `_ +.. [#zip-2005] `ZIP 2005: Orchard Quantum Recoverability `_ diff --git a/zips/zip-0048.md b/zips/zip-0048.md new file mode 100644 index 000000000..a0c3a45d5 --- /dev/null +++ b/zips/zip-0048.md @@ -0,0 +1,278 @@ + + ZIP: 48 + Title: Transparent Multisig Wallets + Owners: Kris Nuttycombe + Jack Grigg + Daira-Emma Hopwood + Arya + Credits: Fontaine + Status: Draft + Category: Wallet + Created: 2025-08-25 + License: MIT + Discussions-To: + + +# Terminology + +The key words "MUST", "REQUIRED", "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 terms "Mainnet" and "Testnet" in this document are to be interpreted as +defined in the Zcash protocol specification [^protocol-networks]. + + +# Abstract + +This ZIP defines how wallets should implement transparent multisignature addresses in the +Zcash ecosystem. It specifies how to derive the necessary key material in a deterministic +way, and how to create transactions spending transparent multisig-controlled funds. + +Any future changes, or new transparent protocols or scripts, will be made as Revisions to +this ZIP. + + +# Motivation + +There are a variety of important use cases for funds being controlled by a quorum of +signers. In Bitcoin, these use cases were served via "P2SH multisig", or more specifically +a Pay-to-Multi-Signature (P2MS) script specified by a P2SH address. + +A P2SM script can be constructed from any set of secp256k1 public keys, and anyone can use +any mechanism for obtaining or storing the corresponding signing keys by private agreement. +However, in order to ensure that funds are easily recoverable from backups, several +different BIPs emerged for P2MS scripts using BIP 32 Hierarchical Derivation [^bip-0032]. +Each of these has some problem when attempting to apply it as-written to Zcash: + +- BIP 45 [^bip-0045] uses `m / purpose' / cosigner_index / change / address_index`. + - The problem is that unlike BIP 44, this BIP does not include `coin_type' / account'` + in its derivation path. If naively applied to Zcash, it would result in key reuse + between Bitcoin and Zcash, which creates the potential for cross-protocol attacks + that would be complex to rule out. + - This is the BIP that essentially all hardware wallets use for Bitcoin P2SH multisig. + +- BIP 48 [^bip-0048] uses `m / purpose' / coin_type' / account' / script_type' / change / address_index` + - The problem is that `script_type` is specified solely for Bitcoin's Native Segwit (P2WSH) + and Nested Segwit (P2SH-P2WSH). Several conflicting proposed `script_type` constants + for P2SH have been considered at various points, and were rejected due to P2SH being + considered "legacy" in the context of Bitcoin. + - This is the BIP that essentially all hardware wallets use for P2WSH and P2SH-P2WSH on + any Bitcoin-compatible chain. + +- BIP 87 [^bip-0087] uses `m / purpose' / coin_type' / account' / change / address_index` + - The problem is that this BIP does not consider key reuse across different scripts + (which are to some degree different payment protocols) to be an issue, whereas we do. + - This BIP is essentially unused by hardware wallets (which instead implement BIPs 45 + and 48). + +While there is verifiable usage of P2SH multisig on the Zcash chain, there has been no +standard approach for public deployments (likely due to the above issues), and thus no +support for it in Zcash-compatible hardware wallets. This ZIP fills the gap. + + +# Privacy Implications + +This does not have any privacy implications beyond what users already accept by +using the transparent protocol and BIP 44 in particular for transparent address +derivation. + + +# Requirements + +Hardware wallet providers should only need to make limited changes relative to how they +support Bitcoin P2SH multisig. As such, this specification should hew closely to the +specifications used in the Bitcoin ecosystem for P2SH support. + + +# Specification + +This ZIP applies to both Mainnet and Testnet, using the same $\mathit{coin\_type}$ +constants as defined in [^slip-0044] where applicable. Note that in keeping with that +document, all cryptocurrency testnets share $\mathit{coin\_type}$ index 1. + +## Output descriptor and script + +Zcash wallets SHOULD use the BIP 383 [^bip-0383] `sortedmulti()` script expression to +produce Zcash P2MS scripts, which would then be contained in the BIP 381 [^bip-0381] +`sh()` script expression to produce Zcash P2SH addresses. + +The following BIP 388 [^bip-0388] wallet descriptor template produces a 2-of-3 P2SH +multisig wallet compatible with this ZIP: + +``` +sh(sortedmulti(2,@0/**,@1/**,@2/**)) +``` + +## Hierarchical Derivation + +Given a set of participants that each have some seed material (e.g. BIP 39 [^bip-0039] +mnemonic phrases), and a BIP 380 [^bip-0380] output descriptor that encodes the desired +multisig policy, wallets need to produce their individual contributions to the BIP 388 +key information vector [^bip-0388-key-information-vector]. This specification adopts +BIP 48 [^bip-0048] for this purpose, with the following modification: + +- The $\mathit{script\_type}$ values for Native Segwit and Nested Segwit MUST NOT be used + in a Zcash context. + +- The following Zcash-specific $\mathit{script\_type}$ key spaces are defined: + + - A path component of $133000'$ represents “Zcash P2SH”. + +## Transaction construction + +The transaction construction workflow for a P2SH multisig wallet is as follows: + +- One of the participants uses their local wallet to construct a PCZT [^zip-pczt] that + spends transparent UTXOs controlled by the multisig wallet, with the desired outputs, + and a change output to a P2SH address derived at the path + `m/48'/coin_type'/account'/133000'/1/*`. + +- The PCZT is conveyed to the other wallet participants out-of-band (via a private and + authenticated channel, such as a group end-to-end-encrypted messenger). + +- Each participant's wallet MUST verify that the PCZT's change outputs are to an address + that the multisig wallet controls. + +- Each participant verifies that the PCZT performs the spend action that they expect. + +- Each participant modifies their copy of the PCZT to include their signature(s) using + their wallet. + +- Each participant conveys their signed PCZT to one (or more) of the other wallet + participants (likely via the same channel that the unsigned PCZT was received on). + +- One participant takes a threshold of signed PCZTs, combines them, and extracts the final + transaction for broadcasting to the network. + +Wallets SHOULD ensure they are fully synced before proposing a transaction that generates +transparent change, to minimize the likelihood of reusing a P2SH change address. + + +# Examples + +## 2-of-3 P2SH multisig on Zcash mainnet + +Let the seeds for the three participants be (in hex): + +``` +[ + "0101010101010101010101010101010101010101010101010101010101010101", + "0202020202020202020202020202020202020202020202020202020202020202", + "0303030303030303030303030303030303030303030303030303030303030303" +] +``` + +TODO: Update example below with actual key fingerprints and xpub encodings. + +The wallet descriptor template for this multisig is: + +``` +sh(sortedmulti(2,@0/**,@1/**,@2/**)) +``` + +The three parties each derive their transparent extended public key from their respective +wallet seed, using the path `m/48'/133'/0'/133000'`. The parties then combine their +respective keys to produce a key information vector [^bip-0388-key-information-vector]: + +``` +[ + "[MSTKFP_0/48'/133'/0'/133000']EXTENDED_PUBLIC_KEY_0", + "[MSTKFP_1/48'/133'/0'/133000']EXTENDED_PUBLIC_KEY_1", + "[MSTKFP_2/48'/133'/0'/133000']EXTENDED_PUBLIC_KEY_2" +] +``` + +The wallet policy is the composition of the wallet descriptor template and the key +information vector. The corresponding multipath descriptor [^bip-0389] derived from this +policy [^bip-0388-descriptor-derivation] is (newlines and whitespace added for legibility): + +``` +sh( + sortedmulti( + 2, + [MSTKFP_0/48'/133'/0'/133000']EXTENDED_PUBLIC_KEY_0/<0;1>/*, + [MSTKFP_1/48'/133'/0'/133000']EXTENDED_PUBLIC_KEY_1/<0;1>/*, + [MSTKFP_2/48'/133'/0'/133000']EXTENDED_PUBLIC_KEY_2/<0;1>/* + ) +) +``` + +# Rationale + +The choice to use BIP 48 means that participants are not restricted to constructing a +single P2SH address; once a wallet has obtained the completed wallet policy, it can +(without additional coordination) produce the same deterministic sequence of P2SH +addresses as every other participant. + +We specify a likely-non-colliding $\mathit{script\_type}$ instead of using a path +component of either $0'$ (the gap left in BIP 48) or $2'$ (the next unassigned constant in +BIP 48), because both of those values have in the past been proposed and rejected as +referring to P2SH. This means that there is no compatibility benefit to trying to use one +or the other, and the likelihood of a collision with some other use case is higher. +Instead we pick a value that is prefixed (in decimal) with the SLIP 44 [^slip-0044] +$\mathit{coin\_type}$ for Zcash mainnet, which is highly unlikely to organically occur in +another related specification. + +By not using BIP 45, Zcash addresses will not be compatible with BIP 45 P2SH derivation +paths. We consider this acceptable because we explicitly do not want users that use the +same mnemonic phrase for both Bitcoin and Zcash to produce addresses that reuse the same +public keys. + +By not using BIP 45 (with a $\mathit{cosigner\_index}$ path element), all cosigners produce +the same sequence of P2SH addresses. This is good for agreement on, for example, the ZIP 1016 [^zip-1016] +Key-Holder Organizations’ Mainnet address, but in general usage means that two cosigners +proposing transactions can race and use the same P2SH address twice. This could result in a +situation where different members of the signing set inadvertently give the same P2SH +address to different counterparties, linking the associated payment +activity. We consider this tradeoff acceptable because it aligns with what hardware +wallets have done for years (implying that users are fine with the usability). We consider +the risk acceptable because avoiding linkage between transparent addresses is hard in any +case, and not something that Zcash actively attempts to avoid (the shielded protocols are +designed for this use case). + + +# Reference implementation + +TBD + + +# 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"](https://www.rfc-editor.org/info/bcp14) + +[^protocol-networks]: [Zcash Protocol Specification, Version 2024.5.1. Section 3.12: Mainnet and Testnet](protocol/protocol.pdf#networks) + +[^bip-0032]: [BIP 32: Hierarchical Deterministic Wallets](https://github.com/bitcoin/bips/blob/master/bip-0032.mediawiki) + +[^bip-0032-master-key-generation]: [BIP 32: Hierarchical Deterministic Wallets](https://github.com/bitcoin/bips/blob/master/bip-0032.mediawiki#master-key-generation) + +[^bip-0032-key-identifiers]: [BIP 32: Hierarchical Deterministic Wallets](https://github.com/bitcoin/bips/blob/master/bip-0032.mediawiki#key-identifiers) + +[^bip-0039]: [BIP 39: Mnemonic code for generating deterministic keys](https://github.com/bitcoin/bips/blob/master/bip-0039.mediawiki) + +[^bip-0045]: [BIP 45: Structure for Deterministic P2SH Multisignature Wallets](https://github.com/bitcoin/bips/blob/master/bip-0045.mediawiki) + +[^bip-0048]: [BIP 48: Multi-Script Hierarchy for Multi-Sig Wallets](https://github.com/bitcoin/bips/blob/master/bip-0048.mediawiki) + +[^bip-0067]: [BIP 67: Deterministic Pay-to-script-hash multi-signature addresses through public key sorting](https://github.com/bitcoin/bips/blob/master/bip-0067.mediawiki) + +[^bip-0087]: [BIP 87: Hierarchy for Deterministic Multisig Wallets](https://github.com/bitcoin/bips/blob/master/bip-0087.mediawiki) + +[^bip-0380]: [BIP 380: Output Script Descriptors General Operation](https://github.com/bitcoin/bips/blob/master/bip-0380.mediawiki) + +[^bip-0381]: [BIP 381: Non-Segwit Output Script Descriptors](https://github.com/bitcoin/bips/blob/master/bip-0381.mediawiki) + +[^bip-0383]: [BIP 383: Multisig Output Script Descriptors](https://github.com/bitcoin/bips/blob/master/bip-0383.mediawiki) + +[^bip-0388]: [BIP 388: Wallet Policies for Descriptor Wallets](https://github.com/bitcoin/bips/blob/master/bip-0388.mediawiki) + +[^bip-0388-key-information-vector]: [BIP 388: Wallet Policies for Descriptor Wallets. Key information vector](https://github.com/bitcoin/bips/blob/master/bip-0388.mediawiki#key-information-vector) + +[^bip-0388-descriptor-derivation]: [BIP 388: Wallet Policies for Descriptor Wallets. Descriptor derivation](https://github.com/bitcoin/bips/blob/master/bip-0388.mediawiki#descriptor-derivation) + +[^bip-0389]: [BIP 389: Multipath Descriptor Key Expressions](https://github.com/bitcoin/bips/blob/master/bip-0389.mediawiki) + +[^slip-0044]: [SLIP-0044: Registered coin types for BIP-0044](https://github.com/satoshilabs/slips/blob/master/slip-0044.md) + +[^zip-1016]: [ZIP 1016: Community and Coinholder Funding Model](zip-1016.md) diff --git a/zips/zip-0068.rst b/zips/zip-0068.rst index 1c22879e8..2f567313c 100644 --- a/zips/zip-0068.rst +++ b/zips/zip-0068.rst @@ -2,10 +2,11 @@ ZIP: 68 Title: Relative lock-time using consensus-enforced sequence numbers - Credits: Mark Friedenbach - BtcDrak - Nicolas Dorier - kinoshitajona + Owners: Daira-Emma Hopwood + Credits: Mark Friedenbach + BtcDrak + Nicolas Dorier + kinoshitajona Category: Consensus Status: Draft Created: 2016-06-06 diff --git a/zips/zip-0076.rst b/zips/zip-0076.rst index 35ba78a96..1da99476d 100644 --- a/zips/zip-0076.rst +++ b/zips/zip-0076.rst @@ -2,8 +2,8 @@ ZIP: 76 Title: Transaction Signature Validation before Overwinter - Owners: Jack Grigg - Daira-Emma Hopwood + Owners: Jack Grigg + Daira-Emma Hopwood Status: Reserved Category: Consensus Discussions-To: diff --git a/zips/zip-0112.rst b/zips/zip-0112.rst index a6c130c0b..7eba047a2 100644 --- a/zips/zip-0112.rst +++ b/zips/zip-0112.rst @@ -2,10 +2,10 @@ ZIP: 112 Title: CHECKSEQUENCEVERIFY - Author: Daira Hopwood - Credits: BtcDrak - Mark Friedenbach - Eric Lombrozo + Owners: Daira-Emma Hopwood + Credits: BtcDrak + Mark Friedenbach + Eric Lombrozo Category: Consensus Status: Draft Created: 2019-06-06 diff --git a/zips/zip-0113.rst b/zips/zip-0113.rst index d7d657a4c..e4d94d21b 100644 --- a/zips/zip-0113.rst +++ b/zips/zip-0113.rst @@ -2,9 +2,9 @@ ZIP: 113 Title: Median Time Past as endpoint for lock-time calculations - Author: Daira Hopwood - Credits: Thomas Kerin - Mark Friedenbach + Owners: Daira-Emma Hopwood + Credits: Thomas Kerin + Mark Friedenbach Gregory Maxwell Category: Consensus Status: Draft diff --git a/zips/zip-0129.md b/zips/zip-0129.md new file mode 100644 index 000000000..157177cdf --- /dev/null +++ b/zips/zip-0129.md @@ -0,0 +1,14 @@ + + ZIP: 129 + Title: Zcash Transparent Multisig Setup + Owners: Kris Nuttycombe + Jack Grigg + Arya + Credits: Hugo Nguyen + Peter Gray + Marko Bencun + Aaron Chen + Rodolfo Novak + Status: Reserved + Category: Wallet + Discussions-To: diff --git a/zips/zip-0143.rst b/zips/zip-0143.rst index af07101d5..09b14306f 100644 --- a/zips/zip-0143.rst +++ b/zips/zip-0143.rst @@ -2,8 +2,8 @@ ZIP: 143 Title: Transaction Signature Validation for Overwinter - Owners: Jack Grigg - Daira-Emma Hopwood + Owners: Jack Grigg + Daira-Emma Hopwood Credits: Johnson Lau Pieter Wuille Bitcoin-ABC diff --git a/zips/zip-0155.rst b/zips/zip-0155.rst index 214091629..1a5088331 100644 --- a/zips/zip-0155.rst +++ b/zips/zip-0155.rst @@ -2,7 +2,7 @@ ZIP: 155 Title: addrv2 message - Owners: Daira-Emma Hopwood + Owners: Daira-Emma Hopwood Credits: Wladimir J. van der Laan Zancas Wilcox Status: Proposed diff --git a/zips/zip-0173.rst b/zips/zip-0173.rst index 70ca789f5..75ce013e7 100644 --- a/zips/zip-0173.rst +++ b/zips/zip-0173.rst @@ -2,9 +2,9 @@ ZIP: 173 Title: Bech32 Format - Owners: Daira-Emma Hopwood - Credits: Pieter Wuille - Greg Maxwell + Owners: Daira-Emma Hopwood + Credits: Pieter Wuille + Greg Maxwell Rusty Russell Mark Friedenbach Status: Final diff --git a/zips/zip-0200.rst b/zips/zip-0200.rst index 5b3733370..4db92a743 100644 --- a/zips/zip-0200.rst +++ b/zips/zip-0200.rst @@ -2,7 +2,7 @@ ZIP: 200 Title: Network Upgrade Mechanism - Owners: Jack Grigg + Owners: Jack Grigg Status: Final Category: Consensus Created: 2018-01-08 diff --git a/zips/zip-0201.rst b/zips/zip-0201.rst index 2aae78503..0ea061814 100644 --- a/zips/zip-0201.rst +++ b/zips/zip-0201.rst @@ -2,7 +2,7 @@ ZIP: 201 Title: Network Peer Management for Overwinter - Owners: Daira-Emma Hopwood + Owners: Daira-Emma Hopwood Original-Authors: Simon Liu Status: Final Category: Network diff --git a/zips/zip-0202.rst b/zips/zip-0202.rst index adc7728df..97b365642 100644 --- a/zips/zip-0202.rst +++ b/zips/zip-0202.rst @@ -2,7 +2,7 @@ ZIP: 202 Title: Version 3 Transaction Format for Overwinter - Owners: Daira-Emma Hopwood + Owners: Daira-Emma Hopwood Original-Authors: Simon Liu Status: Final Category: Consensus diff --git a/zips/zip-0203.rst b/zips/zip-0203.rst index 3d2dbd036..e9ed61950 100644 --- a/zips/zip-0203.rst +++ b/zips/zip-0203.rst @@ -2,7 +2,7 @@ ZIP: 203 Title: Transaction Expiry - Owners: Daira-Emma Hopwood + Owners: Daira-Emma Hopwood Original-Authors: Jay Graber Status: Final Category: Consensus @@ -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-0204.rst b/zips/zip-0204.rst index 77b5cdf52..d3b9476f4 100644 --- a/zips/zip-0204.rst +++ b/zips/zip-0204.rst @@ -2,7 +2,1403 @@ ZIP: 204 Title: Zcash P2P Network Protocol - Owners: Daira-Emma Hopwood - Status: Reserved + Owners: Daira-Emma Hopwood + Kris Nuttycombe + Status: Draft Category: Network + Created: 2026-02-05 + License: MIT Discussions-To: + + +Terminology +=========== + +The key words "MUST", "MUST NOT", "SHOULD", "SHOULD NOT", and "RECOMMENDED" in this +document are to be interpreted as described in BCP 14 [#BCP14]_ when, and only when, +they appear in all capitals. + +The terms "Mainnet" and "Testnet" are to be interpreted as described in section 3.12 of +the Zcash Protocol Specification. [#protocol-networks]_ + +The term "network upgrade" is to be interpreted as described in ZIP 200. [#zip-0200]_ + +The term "block chain" in this document is to be interpreted as described in section 3.3 +of the Zcash Protocol Specification. [#protocol-blockchain]_ + +peer + A network node that participates in the Zcash P2P protocol by maintaining one or more + TCP connections to other peers and exchanging protocol messages. + +connection + A TCP session between two peers over which P2P messages are exchanged. + +inbound connection + A connection that was initiated by the remote peer. + +outbound connection + A connection that was initiated by the local node. + +protocol version + A 32-bit integer identifying the set of protocol features supported by a node. Higher + values indicate support for more recent features. + + +Abstract +======== + +This ZIP specifies the Zcash peer-to-peer network protocol, including connection setup, +message framing, message types, and relay behavior. It is intended to be sufficient for +an implementor to build a conformant Zcash network peer. + + +Motivation +========== + +There is currently no single document that specifies the full Zcash P2P network +protocol. While Bitcoin protocol documentation exists, the Zcash protocol has diverged +in several significant ways: network magic bytes differ, protocol version numbers follow +an independent numbering scheme, inventory types include ``MSG_WTX`` [#zip-0239]_, +and network upgrade activation drives protocol versioning and peer management +[#zip-0200]_ [#zip-0201]_. + +This ZIP consolidates the protocol specification into a single normative reference, +enabling independent implementations and protocol analysis. + +This ZIP does not specify the encoding of transactions and blocks; for those, refer to +the Zcash Protocol Specification [#protocol-txnencoding]_ [#protocol-blockencoding]_. + + +Specification +============= + +Network Parameters +------------------ + +Magic Bytes +``````````` + +Each Zcash network is identified by a 4-byte magic value that appears at the start of +every protocol message. A node MUST reject messages whose magic bytes do not match the +expected network. + ++-----------+---------------------+ +| Network | Magic Bytes (hex) | ++===========+=====================+ +| Mainnet | ``24 e9 27 64`` | ++-----------+---------------------+ +| Testnet | ``fa 1a f9 bf`` | ++-----------+---------------------+ +| Regtest | ``aa e8 3f 5f`` | ++-----------+---------------------+ + +Default Ports +````````````` + ++-----------+----------------+ +| Network | Default Port | ++===========+================+ +| Mainnet | 8233 | ++-----------+----------------+ +| Testnet | 18233 | ++-----------+----------------+ +| Regtest | 18344 | ++-----------+----------------+ + +DNS Seeds +````````` + +The following DNS seed hostnames are used for initial peer discovery. + +**Mainnet:** + +- ``dnsseed.z.cash`` +- ``dnsseed.str4d.xyz`` +- ``mainnet.seeder.zfnd.org`` +- ``mainnet.is.yolo.money`` + +**Testnet:** + +- ``dnsseed.testnet.z.cash`` +- ``testnet.seeder.zfnd.org`` +- ``testnet.is.yolo.money`` + +Regtest does not use DNS seeds or hardcoded seed nodes. + + +Peer Discovery +-------------- + +A node discovers peers through the following mechanisms: + +1. **DNS seeding.** On startup, a node queries the DNS seed hostnames listed above + for A and AAAA records. The zcashd implementation does this only if the address + manager is empty or if fewer than 2 outbound connections have been established + within 11 seconds; the Zebra implementation always performs DNS lookups on + startup (alongside consulting a persistent address cache). + +2. **Hardcoded seed nodes.** If DNS seeding fails or is insufficient, the node + MAY fall back to a compiled-in list of seed node addresses. In the zcashd + implementation these hardcoded addresses may be found in the chain + parameters for the relevant network. DNS seeding is preferred over + hardcoded seed nodes. + +3. **Address relay.** Connected peers exchange address information using ``addr`` and + ``getaddr`` messages (see `addr`_ and `getaddr`_). This mechanism operates + independently of the above. + + +Connection Handling +------------------- + +Transport +````````` + +All connections use unencrypted TCP. The protocol does not provide transport-layer +encryption or authentication. + +Connection Limits +````````````````` + +The specific connection limits are implementation-defined. The zcashd implementation +defaults to a maximum of 125 peer connections (``DEFAULT_MAX_PEER_CONNECTIONS``), of +which a maximum of 8 are outbound connections (``MAX_OUTBOUND_CONNECTIONS``). The Zebra +implementation computes its limits from a configurable initial target size (default 25), +applying multipliers to derive an outbound limit of 75 and an inbound limit of 125. + +Timeouts +```````` + +A node SHOULD disconnect a peer if no message has been received from that peer within +a reasonable timeout period. The zcashd implementation uses 1200 seconds (20 minutes, +``TIMEOUT_INTERVAL``) for this purpose; the Zebra implementation uses a 20-second +request timeout (``REQUEST_TIMEOUT``). Automatic ``ping`` messages (see `ping`_) are +sent periodically to keep connections alive and measure latency. + +Additional timeout rules: + +- A node SHOULD close the connection if a peer has not sent a ``version`` message + within a reasonable time after connection establishment. The zcashd implementation + uses 60 seconds; the Zebra implementation uses 3 seconds (``HANDSHAKE_TIMEOUT``). +- A node SHOULD close the connection if a peer has not responded to a ``ping`` with + a corresponding ``pong`` within a reasonable time. The zcashd implementation uses + 1200 seconds (20 minutes); the Zebra implementation uses 20 seconds + (``REQUEST_TIMEOUT``). + +The specific timeout values are implementation-defined. + + +Message Framing +--------------- + +Every protocol message consists of a 24-byte header followed by a variable-length +payload. + +Message Header +`````````````` + ++--------+------+----------------+----------------------------------------------------+ +| Offset | Size | Field | Description | ++========+======+================+====================================================+ +| 0 | 4 | ``magic`` | Network magic bytes (see `Magic Bytes`_). | ++--------+------+----------------+----------------------------------------------------+ +| 4 | 12 | ``command`` | ASCII command string, NUL-padded to 12 bytes. | ++--------+------+----------------+----------------------------------------------------+ +| 16 | 4 | ``length`` | Payload size in bytes (``uint32``, little-endian). | ++--------+------+----------------+----------------------------------------------------+ +| 20 | 4 | ``checksum`` | First 4 bytes of ``SHA-256d(payload)``. | ++--------+------+----------------+----------------------------------------------------+ + +The total header size is 24 bytes. + +Command String Validation +````````````````````````` + +The ``command`` field MUST contain only printable ASCII characters (bytes in the range +``0x20`` to ``0x7E`` inclusive) up to the first NUL byte (``0x00``). After the first NUL +byte, all remaining bytes MUST be ``0x00``. A message that violates these constraints +MUST be ignored. + +The following command strings are currently used on the Zcash network: + +``version``, ``verack``, ``ping``, ``pong``, ``reject``, ``addr``, ``addrv2``, +``getaddr``, ``inv``, ``getdata``, ``notfound``, ``getblocks``, ``getheaders``, +``headers``, ``block``, ``tx``, ``mempool``, ``filterload``, ``filteradd``, +``filterclear``, ``alert``. + +Maximum Message Size +```````````````````` + +The maximum payload size is 2,097,152 bytes (2 MiB). A node MUST reject any message +whose ``length`` field exceeds this limit. + +Checksum Verification +````````````````````` + +The ``checksum`` field contains the first 4 bytes of the double-SHA-256 hash of the +payload: + + ``checksum = SHA-256(SHA-256(payload))[0..4]`` + +A node MUST verify the checksum after receiving the full payload and MUST reject the +message if the checksum does not match. + + +Data Types and Encoding +----------------------- + +All multi-byte integer types are encoded in little-endian byte order unless otherwise +specified. The integer types used in this specification (``uint8``, ``uint16``, +``int32``, ``uint32``, ``int64``, ``uint64``) have their conventional meanings. + +CompactSize +``````````` + +.. note:: + + The CompactSize encoding is used in the Zcash Protocol Specification (section 7) + but is not formally defined there. It is defined here for completeness. + +A variable-length unsigned integer encoding used for lengths and counts: + ++------------------------------------------+---------------+---------------------------------------------------+ +| Value Range | Encoding Size | Format | ++==========================================+===============+===================================================+ +| 0 to 252 | 1 byte | Single byte with the value directly. | ++------------------------------------------+---------------+---------------------------------------------------+ +| 253 to 0xFFFF | 3 bytes | ``0xFD`` followed by the value as ``uint16``. | ++------------------------------------------+---------------+---------------------------------------------------+ +| 0x10000 to 0xFFFFFFFF | 5 bytes | ``0xFE`` followed by the value as ``uint32``. | ++------------------------------------------+---------------+---------------------------------------------------+ +| 0x100000000 to 0xFFFFFFFFFFFFFFFF | 9 bytes | ``0xFF`` followed by the value as ``uint64``. | ++------------------------------------------+---------------+---------------------------------------------------+ + +Encodings MUST be canonical: the shortest possible encoding MUST be used for any given +value. A node MUST reject messages containing non-canonical CompactSize encodings. + +Strings +``````` + +Character strings are encoded as a CompactSize length prefix followed by that many bytes +of string data. There is no NUL terminator. + +Network Address (``CService``) +`````````````````````````````` + +A network address without associated metadata, as inherited from the Bitcoin protocol: + ++------+----------+--------------------------------------------------------------+ +| Size | Field | Description | ++======+==========+==============================================================+ +| 16 | ``ip`` | IPv6 address (or IPv4-mapped IPv6 address [#rfc4291]_ for | +| | | IPv4 peers). | ++------+----------+--------------------------------------------------------------+ +| 2 | ``port`` | TCP port number (big-endian, i.e. network byte order). | ++------+----------+--------------------------------------------------------------+ + +IPv4 addresses are represented as IPv4-mapped IPv6 addresses as defined in RFC 4291 +section 2.5.5.2 [#rfc4291]_: the first 12 bytes are ``00 00 00 00 00 00 00 00 00 00 FF FF`` +followed by the 4-byte IPv4 address. + +Peer Address (``CAddress``) +``````````````````````````` + +A network address with associated metadata, used in ``version``, ``addr``, and other +messages: + ++------+--------------+-----------------------------------------------------+ +| Size | Field | Description | ++======+==============+=====================================================+ +| 8 | ``services`` | Bitfield of service flags (``uint64``, | +| | | little-endian). | ++------+--------------+-----------------------------------------------------+ +| 16 | ``ip`` | IPv6 address (or IPv4-mapped IPv6). | ++------+--------------+-----------------------------------------------------+ +| 2 | ``port`` | TCP port number (big-endian). | ++------+--------------+-----------------------------------------------------+ + +When the negotiated protocol version (see `Protocol Version Negotiation`_) is +≥ 31402 (``CADDR_TIME_VERSION``) and the address appears in a context other than a +``version`` message, the encoding is preceded by a ``uint32`` timestamp field: + ++------+--------------+-----------------------------------------------------+ +| Size | Field | Description | ++======+==============+=====================================================+ +| 4 | ``time`` | Unix-epoch UTC time in seconds when the node | +| | | was last seen (``uint32``, little-endian). | ++------+--------------+-----------------------------------------------------+ +| 8 | ``services`` | Bitfield of service flags (``uint64``, | +| | | little-endian). | ++------+--------------+-----------------------------------------------------+ +| 16 | ``ip`` | IPv6 address (or IPv4-mapped IPv6). | ++------+--------------+-----------------------------------------------------+ +| 2 | ``port`` | TCP port number (big-endian). | ++------+--------------+-----------------------------------------------------+ + + +Service Flags +------------- + +Service flags are advertised in the ``services`` field of ``version`` messages and +``CAddress`` structures. In the table below, bit $k$ refers to the bit with +numeric weight $2^k;$ that is, the ``services`` field has the corresponding flag +set if and only if ``services & (1 << k) != 0``. + ++------------------+-----+------------------------------------------------------+ +| Name | Bit | Description | ++==================+=====+======================================================+ +| ``NODE_NETWORK`` | 0 | The node is capable of serving the complete block | +| | | chain. | ++------------------+-----+------------------------------------------------------+ +| ``NODE_BLOOM`` | 2 | The node supports Bloom-filtered connections | +| | | (BIP 37 [#bip-0037]_). Zcash nodes used to support | +| | | this by default without advertising the bit, but no | +| | | longer do as of protocol version 170004 | +| | | (``NO_BLOOM_VERSION``). | ++------------------+-----+------------------------------------------------------+ + +Bits 24–31 are reserved for temporary experiments. + + +Inventory Vectors +----------------- + +Inventory vectors identify objects (transactions and blocks) for relay. The format +depends on the type: + ++------------------------+------+------------+-------------------------------------------+ +| Type | Code | Entry Size | Description | ++========================+======+============+===========================================+ +| ``MSG_TX`` | 1 | 36 bytes | Transaction identified by txid. | +| | | | 4-byte type code + 32-byte txid. | ++------------------------+------+------------+-------------------------------------------+ +| ``MSG_BLOCK`` | 2 | 36 bytes | Block identified by block hash. | +| | | | 4-byte type code + 32-byte block hash. | ++------------------------+------+------------+-------------------------------------------+ +| ``MSG_FILTERED_BLOCK`` | 3 | 36 bytes | Filtered block (``getdata`` only). | +| | | | 4-byte type code + 32-byte block hash. | ++------------------------+------+------------+-------------------------------------------+ +| ``MSG_WTX`` | 5 | 68 bytes | Transaction identified by wtxid. | +| | | | 4-byte type code + 32-byte txid + | +| | | | 32-byte authorizing data commitment | +| | | | (``auth_digest``). Requires negotiated | +| | | | protocol version ≥ 170014 | +| | | | (``CINV_WTX_VERSION``). | +| | | | See ZIP 239 [#zip-0239]_. | ++------------------------+------+------------+-------------------------------------------+ + +Because ``MSG_TX`` and ``MSG_WTX`` entries have different sizes (36 and 68 bytes +respectively), they may be mixed in a single ``inv`` or ``getdata`` message. The total +message size is therefore not determined solely by the entry count and MUST be determined +by parsing each entry individually. + +A node MUST reject inventory vectors with unrecognized type codes. A node MUST reject +``MSG_WTX`` inventory vectors if the negotiated protocol version is less than 170014. + + +Connection Handshake +-------------------- + +Peers perform a version handshake immediately upon establishing a TCP connection. + +Handshake Sequence +`````````````````` + +1. The initiating (outbound) peer sends a ``version`` message. +2. The receiving (inbound) peer sends its own ``version`` message. +3. Each peer, upon receiving a valid ``version`` message, responds with a ``verack`` + message. +4. The negotiated protocol version is ``min(local_version, remote_version)``. + +A peer MUST NOT send any message other than ``version`` before receiving the remote +peer's ``version`` message. A peer MUST NOT send any message other than ``verack`` after +sending its ``version`` and before receiving the remote peer's ``verack``. + +If validation of the ``version`` message received from a peer fails, the node +MUST disconnect the peer. See (see `Version Validation`_) below for additional +details. + +Protocol Version Negotiation +```````````````````````````` + +Each peer advertises its own protocol version in its ``version`` message. The +*negotiated protocol version* for the connection is defined as: + + ``negotiated_version = min(local_version, remote_version)`` + +Before the handshake completes, messages are serialized using the initial protocol +version 209 (``INIT_PROTO_VERSION``). Once both ``version`` and ``verack`` messages +have been exchanged, the negotiated protocol version is used for all subsequent +interpretation of protocol features and message semantics on that connection. In +particular, the negotiated protocol version determines: + +- Whether ``CAddress`` structures include a ``time`` field (version ≥ 31402). +- Whether ``MSG_WTX`` inventory vectors are permitted (version ≥ 170014). +- Whether ``addrv2`` messages are supported (see `addrv2`_). +- Whether the peer meets the minimum version requirements for the current network + epoch (see `Network Upgrade Epoch Enforcement`_). + +Note that "the protocol version" as used in this document refers to the negotiated +protocol version unless otherwise specified. A node's *advertised* protocol version +is the version it includes in its ``version`` message. + +Version Message +``````````````` + +The ``version`` message payload has the following format: + ++--------+---------+------------------+------------------------------------------------+ +| Offset | Size | Field | Description | ++========+=========+==================+================================================+ +| 0 | 4 | ``version`` | Protocol version (``int32``). | ++--------+---------+------------------+------------------------------------------------+ +| 4 | 8 | ``services`` | Bitfield of service flags (``uint64``). | ++--------+---------+------------------+------------------------------------------------+ +| 12 | 8 | ``timestamp`` | Unix-epoch UTC time in seconds (``int64``). | ++--------+---------+------------------+------------------------------------------------+ +| 20 | 26 | ``addr_recv`` | Address of the receiving node (``CAddress`` | +| | | | without ``time`` field). | ++--------+---------+------------------+------------------------------------------------+ +| 46 | 26 | ``addr_from`` | Address of the sending node (``CAddress`` | +| | | | without ``time`` field). | ++--------+---------+------------------+------------------------------------------------+ +| 72 | 8 | ``nonce`` | Random nonce for self-connection detection | +| | | | (``uint64``). | ++--------+---------+------------------+------------------------------------------------+ +| 80 | varies | ``user_agent`` | User agent string (CompactSize-prefixed, | +| | | | max 256 bytes). | ++--------+---------+------------------+------------------------------------------------+ +| varies | 4 | ``start_height`` | Best block height known to the sender | +| | | | (``int32``). | ++--------+---------+------------------+------------------------------------------------+ +| varies | 1 | ``relay`` | Whether the sender wants transaction relay | +| | | (optional) | (``uint8``; 0 for false, nonzero for true). | ++--------+---------+------------------+------------------------------------------------+ + +The ``addr_recv`` and ``addr_from`` fields use the ``CAddress`` encoding *without* +the ``time`` field, regardless of the protocol version being negotiated. + +The ``nonce`` field is used for self-connection detection. If a node receives a +``version`` message containing its own nonce, it MUST close the connection. + +The ``user_agent`` string MUST NOT exceed 256 bytes. A node SHOULD disconnect peers +that send a longer user agent. + +The ``relay`` field is optional; if not present, its value MUST be interpreted as true. +A node SHOULD reject ``version`` messages in which the ``relay`` field is present with +a value other than 0 or 1. Nodes SHOULD create `version` messages with this field +present. + +Version Validation +`````````````````` + +A receiving node MUST validate the ``version`` message as follows: + +- The ``version`` field MUST be at least 170002 (``MIN_PEER_PROTO_VERSION``). +- On Testnet, the ``version`` field MUST be at least 170040 + (``MIN_TESTNET_PEER_PROTO_VERSION``). +- The ``version`` field MUST be at least the protocol version associated with + the current network epoch (see `Network Upgrade Peer Management`_). +- The ``nonce`` MUST NOT match the local node's nonce (self-connection detection). +- A peer MUST NOT send more than one ``version`` message per connection. Duplicate + ``version`` messages incur a misbehavior penalty. + +If any of these checks fail, the node MUST disconnect the peer. A ``reject`` message +with code ``REJECT_OBSOLETE`` (``0x11``) SHOULD be sent before disconnecting for +version-related failures. + +Protocol Versioning +------------------- + +Protocol versions are 32-bit integers. The following versions are significant: + ++---------+-------------------------------------+------------------------------------------+ +| Version | Constant | Significance | ++=========+=====================================+==========================================+ +| 209 | ``INIT_PROTO_VERSION`` | Initial protocol version. Used as the | +| | | serialization version before the | +| | | ``version``/``verack`` handshake | +| | | completes. | ++---------+-------------------------------------+------------------------------------------+ +| 31402 | ``CADDR_TIME_VERSION`` | Adds the ``time`` field to ``CAddress`` | +| | | in ``addr`` messages. Also affects | +| | | encoding of the ``addr_from`` field in | +| | | ``version`` messages. | ++---------+-------------------------------------+------------------------------------------+ +| 60000 | ``BIP0031_VERSION`` | ``ping`` messages include a ``uint64`` | +| | | nonce and expect a ``pong`` response. | +| | | For protocol versions ≤ 60000, ``ping`` | +| | | has an empty payload. | ++---------+-------------------------------------+------------------------------------------+ +| 170002 | ``MIN_PEER_PROTO_VERSION`` | Minimum protocol version for Mainnet | +| | | peers. | ++---------+-------------------------------------+------------------------------------------+ +| 170004 | ``NO_BLOOM_VERSION`` | Bloom filter commands (``filterload``, | +| | | ``filteradd``, ``filterclear``) are | +| | | disabled unless the node advertises | +| | | ``NODE_BLOOM``. | ++---------+-------------------------------------+------------------------------------------+ +| 170014 | ``CINV_WTX_VERSION`` | Adds ``MSG_WTX`` inventory type for v5 | +| | | transaction relay. See ZIP 239 | +| | | [#zip-0239]_. | ++---------+-------------------------------------+------------------------------------------+ +| 170040 | ``MIN_TESTNET_PEER_PROTO_VERSION`` | Minimum protocol version for Testnet | +| | | peers. | ++---------+-------------------------------------+------------------------------------------+ +| 170140 | ``PROTOCOL_VERSION`` | Current protocol version. | ++---------+-------------------------------------+------------------------------------------+ + +Network Upgrade Epoch Enforcement +````````````````````````````````` + +Each network upgrade defines a minimum protocol version. When a network upgrade activates +(as defined in ZIP 200 [#zip-0200]_), a node MUST disconnect any peer whose negotiated +protocol version is less than the protocol version associated with the current epoch. +The node SHOULD send a ``reject`` message with code ``REJECT_OBSOLETE`` (``0x11``) +before disconnecting. + +The following protocol versions are associated with network upgrades on Mainnet: + ++-------------------+------------------+-------------------+ +| Network Upgrade | Protocol Version | Activation Height | ++===================+==================+===================+ +| Sprout | 170002 | (always active) | ++-------------------+------------------+-------------------+ +| Overwinter | 170005 | 347,500 | ++-------------------+------------------+-------------------+ +| Sapling | 170007 | 419,200 | ++-------------------+------------------+-------------------+ +| Blossom | 170009 | 653,600 | ++-------------------+------------------+-------------------+ +| Heartwood | 170011 | 903,000 | ++-------------------+------------------+-------------------+ +| Canopy | 170013 | 1,046,400 | ++-------------------+------------------+-------------------+ +| NU5 | 170100 | 1,687,104 | ++-------------------+------------------+-------------------+ +| NU6 | 170120 | 2,726,400 | ++-------------------+------------------+-------------------+ +| NU6.1 | 170140 | 3,146,400 | ++-------------------+------------------+-------------------+ + +The following protocol versions are associated with network upgrades on Testnet: + ++-------------------+------------------+-------------------+ +| Network Upgrade | Protocol Version | Activation Height | ++===================+==================+===================+ +| Sprout | 170002 | (always active) | ++-------------------+------------------+-------------------+ +| Overwinter | 170003 | 207,500 | ++-------------------+------------------+-------------------+ +| Sapling | 170007 | 280,000 | ++-------------------+------------------+-------------------+ +| Blossom | 170008 | 584,000 | ++-------------------+------------------+-------------------+ +| Heartwood | 170010 | 903,800 | ++-------------------+------------------+-------------------+ +| Canopy | 170012 | 1,028,500 | ++-------------------+------------------+-------------------+ +| NU5 | 170050 | 1,842,420 | ++-------------------+------------------+-------------------+ +| NU6 | 170110 | 2,976,000 | ++-------------------+------------------+-------------------+ +| NU6.1 | 170130 | 3,536,500 | ++-------------------+------------------+-------------------+ + +Note that Testnet protocol versions differ from Mainnet for several upgrades +(Overwinter, Blossom, Heartwood, Canopy, NU5, NU6, and NU6.1). + + +Message Types +------------- + +This section defines each protocol message. For each message, the command string, +direction, payload format, and semantics are specified. + +Control Messages +```````````````` + +``version`` +''''''''''' + +:Command: ``version`` +:Direction: Both (sent by each side during handshake) +:Payload: See `Version Message`_. + +Initiates the connection handshake. The details of this message are specified in +`Connection Handshake`_. + + +``verack`` +'''''''''' + +:Command: ``verack`` +:Direction: Both +:Payload: Empty (0 bytes). + +Acknowledges receipt of a ``version`` message. After exchanging ``version`` and +``verack`` messages, the connection is considered established. + + +``ping`` +'''''''' + +:Command: ``ping`` +:Direction: Both +:Payload: + + +------+-----------+-----------------------------------+ + | Size | Field | Description | + +======+===========+===================================+ + | 8 | ``nonce`` | Random value (``uint64``). | + +------+-----------+-----------------------------------+ + +Sent periodically to measure latency and detect dead connections. The zcashd +implementation sends ``ping`` messages every 120 seconds (``PING_INTERVAL``); the Zebra +implementation uses a 59-second heartbeat interval (``HEARTBEAT_INTERVAL``). +The receiving node MUST respond with a ``pong`` message containing the same nonce. + +.. note:: + + Historically (BIP 31 [#bip-0031]_), ``ping`` messages had an empty payload for + protocol versions ≤ 60000 (``BIP0031_VERSION``). Since the minimum Zcash peer + protocol version is 170002 (``MIN_PEER_PROTO_VERSION``), well above this threshold, + all conformant Zcash peers use the nonce-bearing format. The empty-payload variant + will never be encountered on the Zcash network. + + +``pong`` +'''''''' + +:Command: ``pong`` +:Direction: Both +:Payload: + + +------+-----------+------------------------------------------------------+ + | Size | Field | Description | + +======+===========+======================================================+ + | 8 | ``nonce`` | The nonce from the corresponding ``ping`` message | + | | | (``uint64``). | + +------+-----------+------------------------------------------------------+ + +Sent in response to a ``ping``. The ``nonce`` MUST match the ``nonce`` from the ``ping`` +that is being responded to. + + +``reject`` +'''''''''' + +:Command: ``reject`` +:Direction: Both +:Payload: + + +---------+-------------+---------------------------------------------------+ + | Size | Field | Description | + +=========+=============+===================================================+ + | varies | ``message`` | The command string of the rejected message | + | | | (CompactSize-prefixed string). | + +---------+-------------+---------------------------------------------------+ + | 1 | ``ccode`` | Reject code (``uint8``). See `Reject Codes`_. | + +---------+-------------+---------------------------------------------------+ + | varies | ``reason`` | Human-readable rejection reason | + | | | (CompactSize-prefixed string). | + +---------+-------------+---------------------------------------------------+ + | 0 or 32 | ``data`` | Optional. For ``tx`` and ``block`` rejections, | + | | | the 32-byte hash of the rejected object. | + +---------+-------------+---------------------------------------------------+ + +Notifies the peer of a rejected message. This message is informational; receipt of a +``reject`` message does not require any specific action by the receiving node. + + +``alert`` +''''''''' + +:Command: ``alert`` +:Direction: Both +:Payload: + + +---------+---------------+--------------------------------------------------+ + | Size | Field | Description | + +=========+===============+==================================================+ + | varies | ``payload`` | Serialized alert data (CompactSize-prefixed | + | | | byte vector). | + +---------+---------------+--------------------------------------------------+ + | varies | ``signature`` | ECDSA signature over the payload | + | | | (CompactSize-prefixed byte vector). | + +---------+---------------+--------------------------------------------------+ + + The serialized alert data contains: + + +---------+------------------+------------------------------------------------+ + | Size | Field | Description | + +=========+==================+================================================+ + | 4 | ``version`` | Alert format version (``int32``). | + +---------+------------------+------------------------------------------------+ + | 8 | ``relay_until`` | Timestamp after which nodes should stop | + | | | relaying (``int64``). | + +---------+------------------+------------------------------------------------+ + | 8 | ``expiration`` | Timestamp after which the alert is no longer | + | | | in effect (``int64``). | + +---------+------------------+------------------------------------------------+ + | 4 | ``id`` | Unique alert identifier (``int32``). | + +---------+------------------+------------------------------------------------+ + | 4 | ``cancel`` | ID of a previous alert to cancel (``int32``). | + +---------+------------------+------------------------------------------------+ + | varies | ``set_cancel`` | Set of alert IDs to cancel | + | | | (CompactSize-prefixed vector of ``int32``). | + +---------+------------------+------------------------------------------------+ + | 4 | ``min_ver`` | Minimum applicable client version (``int32``). | + +---------+------------------+------------------------------------------------+ + | 4 | ``max_ver`` | Maximum applicable client version (``int32``). | + +---------+------------------+------------------------------------------------+ + | varies | ``set_sub_ver`` | Set of applicable user agent substrings | + | | | (CompactSize-prefixed vector of strings). | + +---------+------------------+------------------------------------------------+ + | 4 | ``priority`` | Alert priority (``int32``). | + +---------+------------------+------------------------------------------------+ + | varies | ``comment`` | Comment for operators (CompactSize-prefixed | + | | | string, max 65536 bytes). | + +---------+------------------+------------------------------------------------+ + | varies | ``status_bar`` | Status bar message (CompactSize-prefixed | + | | | string, max 256 bytes). | + +---------+------------------+------------------------------------------------+ + | varies | ``rpc_error`` | RPC error message (CompactSize-prefixed | + | | | string, max 256 bytes). | + +---------+------------------+------------------------------------------------+ + +The ``alert`` message is deprecated. It is documented here for completeness, as it +remains part of the zcashd implementation but has been proposed for removal +[#zcashd-remove-alert]_, and implementations MAY choose not to +support it. Nodes that do support ``alert`` messages SHOULD validate the alert +signature against the network's alert public key before processing or relaying alerts. + + +Address Messages +```````````````` + +``addr`` +'''''''' + +:Command: ``addr`` +:Direction: Both +:Payload: + + +---------+---------------+------------------------------------------------+ + | Size | Field | Description | + +=========+===============+================================================+ + | varies | ``count`` | Number of addresses (CompactSize). | + +---------+---------------+------------------------------------------------+ + | varies | ``addr_list`` | List of ``CAddress`` entries (with ``time`` | + | | | field). | + +---------+---------------+------------------------------------------------+ + +The ``count`` MUST NOT exceed 1000. A node receiving an ``addr`` message with more than +1000 entries SHOULD assign a misbehavior penalty of 20 points to the sending peer. + + +``getaddr`` +''''''''''' + +:Command: ``getaddr`` +:Direction: Both (but typically only sent to inbound peers) +:Payload: Empty (0 bytes). + +Requests peer addresses from the remote node. The remote node responds by sending one or +more ``addr`` messages. A node SHOULD only send ``getaddr`` once per connection, and +SHOULD only process ``getaddr`` from inbound peers to prevent address-based fingerprinting +attacks. + + +``addrv2`` +'''''''''' + +:Command: ``addrv2`` +:Direction: Both +:Payload: + + +---------+---------------+------------------------------------------------+ + | Size | Field | Description | + +=========+===============+================================================+ + | varies | ``count`` | Number of addresses (CompactSize). | + +---------+---------------+------------------------------------------------+ + | varies | ``addr_list`` | List of address entries in ``addrv2`` format | + | | | (see below). | + +---------+---------------+------------------------------------------------+ + +Each address entry has the following format: + + +---------+---------------+------------------------------------------------+ + | Size | Field | Description | + +=========+===============+================================================+ + | 4 | ``time`` | Unix-epoch UTC time in seconds when the node | + | | | was last seen (``uint32``, little-endian). | + +---------+---------------+------------------------------------------------+ + | varies | ``services`` | Service bits (CompactSize-encoded ``uint64``). | + +---------+---------------+------------------------------------------------+ + | 1 | ``networkID`` | Network identifier (``uint8``). | + +---------+---------------+------------------------------------------------+ + | varies | ``sizeAddr`` | Length of ``addr`` in bytes (CompactSize). | + +---------+---------------+------------------------------------------------+ + | varies | ``addr`` | Network address (``sizeAddr`` bytes). | + | | | Interpretation depends on ``networkID``. | + +---------+---------------+------------------------------------------------+ + | 2 | ``port`` | Network port (``uint16``, big-endian). MUST | + | | | be 0 if not relevant for the network. | + +---------+---------------+------------------------------------------------+ + +The ``count`` MUST NOT exceed 1000. A node MUST reject messages with more than 1000 +addresses. + +The ``addr`` field MUST NOT exceed 512 bytes. A node MUST reject messages with a longer +``addr`` field, irrespective of the network ID. + +The ``services`` field is encoded as a CompactSize, unlike the fixed 8-byte ``uint64`` +encoding used in ``addr`` messages. This makes the common case (few service bits) more +compact. + +The following network IDs are defined: + + +------------+-------------+--------------+-------------------------------------+ + | Network ID | Name | Address Size | Description | + +============+=============+==============+=====================================+ + | ``0x01`` | ``IPV4`` | 4 bytes | IPv4 address. | + +------------+-------------+--------------+-------------------------------------+ + | ``0x02`` | ``IPV6`` | 16 bytes | IPv6 address. | + +------------+-------------+--------------+-------------------------------------+ + | ``0x04`` | ``TORV3`` | 32 bytes | Tor v3 onion service address | + | | | | (Ed25519 public key). | + +------------+-------------+--------------+-------------------------------------+ + | ``0x05`` | ``I2P`` | 32 bytes | I2P overlay network address | + | | | | (SHA-256 hash). | + +------------+-------------+--------------+-------------------------------------+ + | ``0x06`` | ``CJDNS`` | 16 bytes | Cjdns overlay network address | + | | | | (IPv6 in ``fc00::/8``). | + +------------+-------------+--------------+-------------------------------------+ + +Network ID ``0x03`` is reserved (it was assigned to Tor v2 in BIP 155 [#bip-0155]_, but +Tor v2 addresses are no longer supported and MUST NOT be used). + +A node MUST reject addresses whose length does not match the expected length for the +given network ID. A node MUST NOT gossip addresses with unrecognized network IDs. + +``IPV4`` and ``IPV6`` addresses are encoded in network byte order (big-endian). ``TORV3`` +addresses consist of the 32-byte Ed25519 master public key of the onion service. +``I2P`` addresses consist of the decoded 32-byte SHA-256 hash. ``CJDNS`` addresses are +16-byte IPv6 addresses in the ``fc00::/8`` range, encoded in network byte order. + +**Deployment:** Unlike BIP 155 [#bip-0155]_, which uses a ``sendaddrv2`` handshake +message, Zcash signals ``addrv2`` support through protocol version negotiation, as +specified in ZIP 155 [#zip-0155]_. The deployment version has not yet been assigned; +see ZIP 155 for the status of this assignment. +A node MUST NOT send ``addrv2`` messages on connections where the negotiated protocol +version is below the deployment threshold. A node that supports ``addrv2`` MAY still +send ``addr`` messages on any connection. + +The full specification of the ``addrv2`` message, including network address encoding +details, is given in ZIP 155 [#zip-0155]_. + + +Inventory Messages +`````````````````` + +``inv`` +''''''' + +:Command: ``inv`` +:Direction: Both +:Payload: + + +---------+---------------+------------------------------------------------+ + | Size | Field | Description | + +=========+===============+================================================+ + | varies | ``count`` | Number of inventory vectors (CompactSize). | + +---------+---------------+------------------------------------------------+ + | varies | ``inventory`` | List of inventory vectors (see | + | | | `Inventory Vectors`_). | + +---------+---------------+------------------------------------------------+ + +Announces one or more objects (transactions or blocks) that the sender has available. +The ``count`` MUST NOT exceed 50,000. A node receiving an ``inv`` message with more than +50,000 entries SHOULD assign a misbehavior penalty of 20 points. + + +``getdata`` +''''''''''' + +:Command: ``getdata`` +:Direction: Both +:Payload: + + +---------+---------------+------------------------------------------------+ + | Size | Field | Description | + +=========+===============+================================================+ + | varies | ``count`` | Number of inventory vectors (CompactSize). | + +---------+---------------+------------------------------------------------+ + | varies | ``inventory`` | List of inventory vectors (see | + | | | `Inventory Vectors`_). | + +---------+---------------+------------------------------------------------+ + +Requests one or more objects from the remote peer. The ``count`` MUST NOT exceed 50,000. +A node receiving a ``getdata`` message with more than 50,000 entries MUST assign a +misbehavior penalty of 20 points. + +If the requested object is not available, the receiving node SHOULD respond with a +``notfound`` message. + + +``notfound`` +'''''''''''' + +:Command: ``notfound`` +:Direction: Both +:Payload: + + +---------+---------------+------------------------------------------------+ + | Size | Field | Description | + +=========+===============+================================================+ + | varies | ``count`` | Number of inventory vectors (CompactSize). | + +---------+---------------+------------------------------------------------+ + | varies | ``inventory`` | List of inventory vectors identifying objects | + | | | not found. | + +---------+---------------+------------------------------------------------+ + +Sent in response to a ``getdata`` message for objects that the node does not have. + + +Block Messages +`````````````` + +``getblocks`` +''''''''''''' + +:Command: ``getblocks`` +:Direction: Both +:Payload: + + +---------+---------------------------+------------------------------------------+ + | Size | Field | Description | + +=========+===========================+==========================================+ + | 4 | ``version`` | Protocol version (``uint32``). | + +---------+---------------------------+------------------------------------------+ + | varies | ``block_locator_count`` | Number of block locator hashes | + | | | (CompactSize). | + +---------+---------------------------+------------------------------------------+ + | varies | ``block_locator_hashes`` | Block locator hashes (each 32 bytes), | + | | | from highest to lowest height. | + +---------+---------------------------+------------------------------------------+ + | 32 | ``hash_stop`` | Hash of the last desired block, or all | + | | | zeros to request as many as possible. | + +---------+---------------------------+------------------------------------------+ + +Requests an ``inv`` message containing block hashes starting after the first block +locator hash found in the responder's best chain, up to and including ``hash_stop`` or +500 blocks, whichever comes first. A node MUST NOT return more than 500 blocks. + + +``getheaders`` +'''''''''''''' + +:Command: ``getheaders`` +:Direction: Both +:Payload: + + +---------+---------------------------+------------------------------------------+ + | Size | Field | Description | + +=========+===========================+==========================================+ + | 4 | ``version`` | Protocol version (``uint32``). | + +---------+---------------------------+------------------------------------------+ + | varies | ``block_locator_count`` | Number of block locator hashes | + | | | (CompactSize). | + +---------+---------------------------+------------------------------------------+ + | varies | ``block_locator_hashes`` | Block locator hashes (each 32 bytes), | + | | | from highest to lowest height. | + +---------+---------------------------+------------------------------------------+ + | 32 | ``hash_stop`` | Hash of the last desired header, or all | + | | | zeros to request as many as possible. | + +---------+---------------------------+------------------------------------------+ + +Requests a ``headers`` message containing block headers starting after the first +block locator hash found in the responder's best chain, up to and including +``hash_stop`` or 160 headers, whichever comes first. A node MUST NOT return more than +160 headers (``MAX_HEADERS_RESULTS``). + + +``headers`` +''''''''''' + +:Command: ``headers`` +:Direction: Both +:Payload: + + +---------+-------------+---------------------------------------------------+ + | Size | Field | Description | + +=========+=============+===================================================+ + | varies | ``count`` | Number of headers (CompactSize). | + +---------+-------------+---------------------------------------------------+ + | varies | ``headers`` | Block headers. Each header is followed by a | + | | | transaction count field (CompactSize, always 0 in | + | | | ``headers`` messages). | + +---------+-------------+---------------------------------------------------+ + +The ``count`` MUST NOT exceed 160. The headers MUST form a contiguous chain +(each header's ``hashPrevBlock`` must match the hash of the preceding header). A +node receiving non-contiguous headers SHOULD assign a misbehavior penalty of 20 points. + +For the encoding of block headers, see the Zcash Protocol Specification +[#protocol-blockheader]_. + + +``block`` +''''''''' + +:Command: ``block`` +:Direction: Both +:Payload: A single serialized block. + +Sent in response to a ``getdata`` request for a ``MSG_BLOCK`` inventory entry. For the +encoding of blocks, see the Zcash Protocol Specification [#protocol-blockencoding]_. + + +Transaction Messages +```````````````````` + +``tx`` +'''''' + +:Command: ``tx`` +:Direction: Both +:Payload: A single serialized transaction. + +Sent in response to a ``getdata`` request for a ``MSG_TX`` or ``MSG_WTX`` inventory +entry. For the encoding of transactions, see the Zcash Protocol Specification +[#protocol-txnencoding]_. + + +Bloom Filter Messages +````````````````````` + +These messages implement BIP 37 [#bip-0037]_ Bloom filtering. As of protocol +version 170004, a node MUST NOT send Bloom filter commands to a peer that does +not advertise ``NODE_BLOOM`` in its service flags. Sending Bloom filter +commands to a peer that does not advertise ``NODE_BLOOM`` SHOULD incur a +misbehavior penalty of 100 points (immediate ban). + +``filterload`` +'''''''''''''' + +:Command: ``filterload`` +:Direction: Both +:Payload: A serialized Bloom filter, as defined in BIP 37 [#bip-0037]_. + +Sets a Bloom filter on the connection. After a filter is set, the peer will only relay +transactions that match the filter. + + +``filteradd`` +''''''''''''' + +:Command: ``filteradd`` +:Direction: Both +:Payload: + + +---------+----------+------------------------------------------------------+ + | Size | Field | Description | + +=========+==========+======================================================+ + | varies | ``data`` | Element to add to the Bloom filter | + | | | (CompactSize-prefixed, max 520 bytes). | + +---------+----------+------------------------------------------------------+ + +Adds an element to the existing Bloom filter. The data MUST NOT exceed 520 bytes. A node +receiving data exceeding 520 bytes SHOULD assign a misbehavior penalty of 100 points. + + +``filterclear`` +''''''''''''''' + +:Command: ``filterclear`` +:Direction: Both +:Payload: Empty (0 bytes). + +Removes the Bloom filter from the connection. Transaction relay resumes normally. + + +Memory Pool +``````````` + +``mempool`` +''''''''''' + +:Command: ``mempool`` +:Direction: Both +:Payload: Empty (0 bytes). + +Requests the contents of the peer's transaction memory pool. The peer responds by sending +one or more ``inv`` messages listing the transactions in its mempool. + + +Block Relay +----------- + +Headers-First Synchronization +````````````````````````````` + +Nodes MAY synchronize the block chain using a headers-first approach. The Zebra +implementation uses headers-first synchronization; zcashd does not [#zcashd-6292]_. + +1. The synchronizing node sends a ``getheaders`` message with a block locator. +2. The remote peer responds with a ``headers`` message containing up to 160 headers. +3. The synchronizing node validates the headers and requests full blocks via ``getdata`` + with ``MSG_BLOCK`` inventory entries. +4. Steps 1–3 repeat until the node is synchronized with the network. + +Block Download Parameters +````````````````````````` + +- **Download window:** A node SHOULD NOT request blocks more than 1024 blocks ahead + of its current validated tip (``BLOCK_DOWNLOAD_WINDOW``). +- **Per-peer limit:** A node SHOULD NOT have more than 16 blocks in transit from a + single peer simultaneously (``MAX_BLOCKS_IN_TRANSIT_PER_PEER``). +- **Stalling timeout:** If a peer has not delivered a requested block within 2 seconds + (``BLOCK_STALLING_TIMEOUT``) and there are other peers available with the same + block, the node MAY request the block from an alternative peer. +- **Maximum headers per response:** 160 (``MAX_HEADERS_RESULTS``). + +Block Announcement +`````````````````` + +Blocks are announced immediately via ``inv`` messages; they are not subject to the +trickling delay applied to transactions. + + +Transaction Relay +----------------- + +Inventory-Based Relay +````````````````````` + +Transaction relay follows an inventory-based protocol: + +1. A node with a new transaction sends an ``inv`` message to its peers. +2. Peers that want the transaction respond with a ``getdata`` message. +3. The originating node sends the transaction in a ``tx`` message. + +Transactions with version ≤ 4 MUST be announced using ``MSG_TX`` inventory vectors. +Transactions with version ≥ 5 MUST be announced using ``MSG_WTX`` inventory vectors. +Using the wrong inventory type for a transaction version SHOULD incur a misbehavior +penalty. See ZIP 239 [#zip-0239]_. + +Trickling +````````` + +To impede network topology inference, transaction inventory SHOULD NOT be sent +immediately but SHOULD instead be "trickled" at random intervals. The specific +trickling parameters are implementation-defined. The zcashd implementation uses the +following values: + +- The average broadcast interval is 5 seconds (``INVENTORY_BROADCAST_INTERVAL``). +- For outbound peers, the effective interval in seconds is halved rounding down + (2 seconds on average). +- At most 35 inventory entries (``INVENTORY_BROADCAST_MAX``) are sent per trickle + interval. +- Broadcast times follow a Poisson distribution centered on the broadcast interval. + +The Zebra implementation uses a 7-second gossip delay (``PEER_GOSSIP_DELAY``). + +Transaction Expiry +`````````````````` + +A node SHOULD NOT relay a transaction that will expire within 3 blocks of its view of +the current chain tip (``TX_EXPIRING_SOON_THRESHOLD``). + +Orphan Transactions +``````````````````` + +An orphan transaction is one that references inputs from unknown parent transactions. + +- A node SHOULD store at most 100 orphan transactions + (``DEFAULT_MAX_ORPHAN_TRANSACTIONS``). +- Orphan transactions expire and are removed after 1200 seconds (20 minutes, + ``ORPHAN_TX_EXPIRE_TIME``). +- Only fully transparent transactions are eligible for orphan storage. +- When the orphan pool is full, the oldest orphan transactions are evicted. + +Relay Fee +````````` + +Transactions are subject to a minimum relay fee. Both the zcashd and Zebra +implementations use a base rate of 100 zatoshis per 1000 bytes +(``DEFAULT_MIN_RELAY_TX_FEE``), though the zcashd implementation applies additional +logic for low-fee and free transactions [#zcashd-relay-fee]_. A node SHOULD NOT relay +transactions with fees below its minimum relay fee threshold. + + +Address Relay +------------- + +Address relay allows nodes to discover peers by propagating ``CAddress`` records through +the network. + +Rate Limiting +````````````` + +Address records SHOULD be subject to rate limiting to prevent address flooding. The +specific rate-limiting mechanism is implementation-defined. The zcashd-specific +rate-limiting mechanism uses a token-bucket algorithm: + +- Rate: 0.1 address records per second per peer (``MAX_ADDR_RATE_PER_SECOND``). +- Bucket capacity: 1000 (``MAX_ADDR_PROCESSING_TOKEN_BUCKET``), replenished at 0.1 + tokens per second. +- Upon receiving a ``getaddr`` response, 1000 tokens (``MAX_ADDR_TO_SEND``) are added + to the bucket, exempt from the soft limit. +- Whitelisted peers bypass address rate limiting. + +Address Broadcasting +```````````````````` + +The specific broadcast intervals are implementation-defined. The zcashd implementation +uses the following values: + +- Addresses are broadcast to peers at an average interval of 30 seconds + (``AVG_ADDRESS_BROADCAST_INTERVAL``). +- A node's own address is broadcast approximately every 9.6 hours + (``AVG_LOCAL_ADDRESS_BROADCAST_INTERVAL = 24 * 24 * 60 = 34560`` seconds). + + +Misbehavior and Banning +----------------------- + +Nodes SHOULD track misbehavior scores for each connected peer. The zcashd +implementation bans a peer when its cumulative score reaches or exceeds 100 +(``DEFAULT_BANSCORE_THRESHOLD``), with bans lasting 24 hours +(``DEFAULT_MISBEHAVING_BANTIME``). The Zebra implementation also uses a threshold of +100 (``MAX_PEER_MISBEHAVIOR_SCORE``) but bans persist indefinitely. The ban threshold +and duration are implementation-defined. + +Whitelisted peers accumulate misbehavior scores but are exempt from banning. + +The following table lists the misbehavior penalties assigned for specific protocol +violations: + ++--------+-------------------------------------------------------------------+ +| Points | Violation | ++========+===================================================================+ +| 1 | Duplicate ``version`` message. | ++--------+-------------------------------------------------------------------+ +| 1 | Message received before ``version`` handshake. | ++--------+-------------------------------------------------------------------+ +| 1 | Duplicate ``verack`` message. | ++--------+-------------------------------------------------------------------+ +| 10 | Alert processing failure. | ++--------+-------------------------------------------------------------------+ +| 20 | ``addr`` message with more than 1000 entries. | ++--------+-------------------------------------------------------------------+ +| 20 | ``inv`` message with more than 50,000 entries. | ++--------+-------------------------------------------------------------------+ +| 20 | ``getdata`` message with more than 50,000 entries. | ++--------+-------------------------------------------------------------------+ +| 20 | ``headers`` message with more than 160 entries. | ++--------+-------------------------------------------------------------------+ +| 20 | Non-contiguous headers sequence. | ++--------+-------------------------------------------------------------------+ +| 50 | Causing send buffer overflow. | ++--------+-------------------------------------------------------------------+ +| 100 | Bloom filter commands without ``NODE_BLOOM`` support. | ++--------+-------------------------------------------------------------------+ +| 100 | Invalid Bloom filter parameters. | ++--------+-------------------------------------------------------------------+ +| 100 | ``filteradd`` data exceeding 520 bytes. | ++--------+-------------------------------------------------------------------+ +| 100 | Using ``MSG_TX`` to announce a v5 transaction, or ``MSG_WTX`` | +| | to announce a v4-or-earlier transaction (see ZIP 239 | +| | [#zip-0239]_). | ++--------+-------------------------------------------------------------------+ +| varies | Transaction, block, or header validation failure. The penalty is | +| | determined by the severity of the validation error. | ++--------+-------------------------------------------------------------------+ + + +Network Upgrade Peer Management +------------------------------- + +Network upgrade peer management is specified in ZIP 201 [#zip-0201]_. This section +summarizes the key behaviors. + +Pre-Activation +`````````````` + +In the 1728-block window (``NETWORK_UPGRADE_PEER_PREFERENCE_BLOCK_PERIOD``) before a +network upgrade activation height, a node SHOULD preferentially connect to peers that +advertise a protocol version at or above the version required by the upcoming upgrade. +This period corresponds to approximately 1.5 days at the post-Blossom block interval. + +Post-Activation +``````````````` + +After a network upgrade activates, a node MUST disconnect any peer whose negotiated +protocol version is below the version required by the active epoch. The node SHOULD send +a ``reject`` message with code ``REJECT_OBSOLETE`` (``0x11``) before disconnecting. + + +Reject Codes +============= + ++----------+----------------------------+-----------------------------------------------+ +| Code | Constant | Description | ++==========+============================+===============================================+ +| ``0x01`` | ``REJECT_MALFORMED`` | The message could not be decoded. | ++----------+----------------------------+-----------------------------------------------+ +| ``0x10`` | ``REJECT_INVALID`` | The message was invalid (e.g., a block or | +| | | transaction that fails validation). | ++----------+----------------------------+-----------------------------------------------+ +| ``0x11`` | ``REJECT_OBSOLETE`` | The message uses an obsolete protocol | +| | | version. | ++----------+----------------------------+-----------------------------------------------+ +| ``0x12`` | ``REJECT_DUPLICATE`` | The message is a duplicate of one already | +| | | received. | ++----------+----------------------------+-----------------------------------------------+ +| ``0x40`` | ``REJECT_NONSTANDARD`` | The transaction is valid but not standard. | ++----------+----------------------------+-----------------------------------------------+ +| ``0x41`` | ``REJECT_DUST`` | One or more transaction outputs are below | +| | | the dust threshold. | ++----------+----------------------------+-----------------------------------------------+ +| ``0x42`` | ``REJECT_INSUFFICIENTFEE`` | The transaction fee is insufficient. | ++----------+----------------------------+-----------------------------------------------+ +| ``0x43`` | ``REJECT_CHECKPOINT`` | The block conflicts with a checkpoint. | ++----------+----------------------------+-----------------------------------------------+ + +Formal Model +============= + +A TLA+ formal specification of the connection lifecycle described in this +ZIP is available at [#formal-model]_. The model covers the handshake, +keepalive, block synchronization, and disconnection phases, verifying +liveness (all peers eventually reach the same block height) and safety +(message size bounds hold across all reachable states). + +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" `_ +.. [#rfc4291] `RFC 4291: IP Version 6 Addressing Architecture, Section 2.5.5.2 `_ +.. [#protocol-networks] `Zcash Protocol Specification, Version 2024.5.1 [NU6]. Section 3.12: Mainnet and Testnet `_ +.. [#protocol-blockchain] `Zcash Protocol Specification, Version 2024.5.1 [NU6]. Section 3.3: The Block Chain `_ +.. [#protocol-txnencoding] `Zcash Protocol Specification, Version 2024.5.1 [NU6]. Section 7.1: Transaction Encoding and Consensus `_ +.. [#protocol-blockencoding] `Zcash Protocol Specification, Version 2024.5.1 [NU6]. Section 7.6: Block Encoding `_ +.. [#protocol-blockheader] `Zcash Protocol Specification, Version 2024.5.1 [NU6]. Section 7.5: Block Header Encoding `_ +.. [#zip-0155] `ZIP 155: addrv2 message `_ +.. [#zip-0200] `ZIP 200: Network Upgrade Mechanism `_ +.. [#zip-0201] `ZIP 201: Network Peer Management for Overwinter `_ +.. [#zip-0225] `ZIP 225: Version 5 Transaction Format `_ +.. [#zip-0239] `ZIP 239: Relay of Version 5 Transactions `_ +.. [#zip-0244] `ZIP 244: Transaction Identifier Non-Malleability `_ +.. [#bip-0031] `BIP 31: Pong Message `_ +.. [#bip-0037] `BIP 37: Connection Bloom filtering `_ +.. [#bip-0111] `BIP 111: NODE_BLOOM service bit `_ +.. [#bip-0130] `BIP 130: sendheaders message `_ +.. [#bip-0155] `BIP 155: addrv2 message `_ +.. [#zcashd-6292] `zcashd issue 6292: zcashd does not use headers-first sync `_ +.. [#zcashd-relay-fee] `zcashd relay fee policy (policy.h) `_ +.. [#zcashd-remove-alert] `zcashd PR 7039: Remove alert handling `_ +.. [#bitcoin-protocol] `Bitcoin Developer Reference: P2P Network `_ +.. [#formal-model] `Zcash P2P Protocol TLA+ Specification `_ diff --git a/zips/zip-0205.rst b/zips/zip-0205.rst index 963959a8a..7fb1a22c7 100644 --- a/zips/zip-0205.rst +++ b/zips/zip-0205.rst @@ -2,7 +2,7 @@ ZIP: 205 Title: Deployment of the Sapling Network Upgrade - Owners: Daira-Emma Hopwood + Owners: Daira-Emma Hopwood Credits: Simon Liu Status: Final Category: Consensus / Network diff --git a/zips/zip-0206.rst b/zips/zip-0206.rst index 16d61138b..fb76fa93b 100644 --- a/zips/zip-0206.rst +++ b/zips/zip-0206.rst @@ -2,7 +2,7 @@ ZIP: 206 Title: Deployment of the Blossom Network Upgrade - Owners: Daira-Emma Hopwood + Owners: Daira-Emma Hopwood Credits: Simon Liu Status: Final Category: Consensus / Network diff --git a/zips/zip-0207.rst b/zips/zip-0207.rst index 50b79227b..4f8ec0539 100644 --- a/zips/zip-0207.rst +++ b/zips/zip-0207.rst @@ -2,11 +2,12 @@ ZIP: 207 Title: Funding Streams - Owners: Jack Grigg - Daira-Emma Hopwood - Status: Final + Owners: Jack Grigg + Daira-Emma Hopwood + Status: [Revision 0: Canopy, Revision 1: NU6] Final Category: Consensus Created: 2019-01-04 + Last-Updated: 2025-08-19 License: MIT @@ -52,14 +53,14 @@ Motivation Motivation for the Zcash Development Fund is considered in ZIP 1014 [#zip-1014]_. 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 +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 [#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. @@ -75,7 +76,7 @@ three "slices" (BP, ZF, and MG) defined in ZIP 1014 [#zip-1014]_, and also (with additional funding stream definitions) the "direct grant option" described in that ZIP. -As for the original Founders' Reward, a mechanism is provided to allow addresses +As for the original Founders’ Reward, a mechanism is provided to allow addresses for a given funding stream to be changed on a roughly-monthly basis, so that keys that are not yet needed may be kept off-line as a security measure. @@ -83,22 +84,36 @@ that are not yet needed may be kept off-line as a security measure. Specification ============= +Revisions +--------- + +.. _`Revision 0`: + +* Revision 0: The initial version of this specification, as agreed upon + by the Zcash community in ZIP 1014 [#zip-1014]_. + +.. _`Revision 1`: + +* Revision 1: Adds the `Deferred Development Fund Chain Value Pool Balance`_ as + a potential recipient of funding stream outputs, as agreed upon by the + Zcash community in ZIP 1015 [#zip-1015]_ and specified in ZIP 2001 + [#zip-2001]_. + Definitions ----------- We use the following constants and functions defined in [#protocol-constants]_, -[#protocol-diffadjustment]_, [#protocol-subsidies]_, and [#protocol-foundersreward]_: +[#protocol-diffadjustment]_, and [#protocol-subsidies]_: -- :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})$ 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 @@ -126,15 +141,20 @@ 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 -[#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 -used for development funding, the distribution of which is to be determined via -a future ZIP. +The value of each funding stream is paid to one of a pre-defined set of +recipients, depending on the block height. + +As of `Revision 0`_, each recipient MUST be the string encoding of a +transparent P2SH address or Sapling address (as specified in +[#protocol-transparentaddrencoding]_ or [#protocol-saplingpaymentaddrencoding]_). + +As of `Revision 1`_, 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]_) +or the identifier $\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. 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 @@ -142,7 +162,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 +171,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 @@ -181,77 +201,94 @@ periods: ``PostBlossomHalvingInterval + 1`` C2 ================================== ======== ======== ======== -On Mainnet, Canopy is planned to activate exactly at the point when the Founders' +On Mainnet, Canopy is planned to activate exactly at the point when the Founders’ Reward expires, at block height 1046400. On Testnet, there will be a shortened -Founders' Reward address period prior to Canopy activation. +Founders’ Reward address period prior to Canopy activation. Deferred Development Fund Chain Value Pool Balance -------------------------------------------------- -Full node implementations MUST track an additional -:math:`\mathsf{ChainValuePoolBalance^{Deferred}}` chain value pool balance, -in addition to the Sprout, Sapling, and Orchard chain value pool balances. +As of `Revision 1`_ of this specification, full node implementations MUST track +an additional $\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 --------------- Prior to activation of the Canopy network upgrade, the existing consensus rule -for payment of the original Founders' Reward is enforced. [#protocol-foundersreward]_ +for payment of the original Founders’ Reward is enforced. [#protocol-foundersreward]_ Once the Canopy network upgrade activates: -- The existing consensus rule for payment of the Founders' Reward [#protocol-foundersreward]_ - is no longer active. - (This would be the case under the preexisting consensus rules for Mainnet, but - not for Testnet.) +1. The existing consensus rule for payment of the Founders’ Reward + [#protocol-foundersreward]_ is no longer active. (This would be the case + under the preexisting consensus rules for Mainnet, but not for Testnet.) + +2. The coinbase transaction in each block MUST contain at least one output per + active funding stream that pays the stream's value in the prescribed way to + the stream's recipient address for the block's height. + +3. $\mathsf{fs.Recipient}(\mathsf{height})$ is defined as + $\mathsf{fs.Recipients_{\,fs.RecipientIndex}}(\mathsf{height})$. + +4. The "prescribed way" to pay a transparent multisig P2SH address is to use a + standard P2SH script as specified in [#Bitcoin-Multisig]_. + +5. The "prescribed way" to pay a Sapling address is as defined in [#zip-0213]_. + 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 [#zip-0212]_. -- In each block with coinbase transaction :math:`\mathsf{cb}` at block height - :math:`\mathsf{height}`, for each funding stream :math:`\mathsf{fs}` +Once the NU6 network upgrade activates: + +- Rule 2 above is replaced by: + 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})\!`. +Rule 5 has subsequently been clarified as follows: -- 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 or Orchard address is as defined in + [#zip-0213]_, using the post-Heartwood consensus rules specified for Sapling + and Orchard outputs of coinbase transactions in [#protocol-txnconsensus]_. -- The "prescribed way" to pay a Sapling address is as defined in [#zip-0213]_. - 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 - specified in [#zip-0212]_. +Note: Up to and including NU6.1 there have been no funding streams defined +with a shielded payment address as a recipient. That might change in future, +so implementations are encouraged to support Sapling and Orchard outputs as +recipients, as permitted by [#zip-0213]_. -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 @@ -265,7 +302,7 @@ Deployment This proposal was initially deployed with Canopy. [#zip-0251]_ -Changes to support deferred funding streams are to be deployed with NU6. [#zip-0253]_ +Changes to support deferred funding streams were deployed with NU6. [#zip-0253]_ Backward compatibility @@ -286,28 +323,54 @@ Reference Implementation * https://github.com/zcash/zcash/pull/4830 +Change History +============== + +2025-08-19 +---------- + +- Defined Revision 0 and Revision 1 explicitly. + +2024-10-31 +---------- + +- Released Revision 1. + +2024-09-26 +---------- + +- Applied ZIP 2001 [#zip-2001]_ to this ZIP (implicitly defining Revision 1). + +2020-05-30 +---------- + +- Released Revision 0 (status changed from Draft to Proposed). + + 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 2025.6.0 [NU6.1 proposal] or later `_ +.. [#protocol-subsidyconcepts] `Zcash Protocol Specification, Version 2025.6.0 [NU6.1 proposal]. Section 3.10: Block Subsidy and Founders’ Reward `_ +.. [#protocol-networks] `Zcash Protocol Specification, Version 2025.6.0 [NU6.1 proposal]. Section 3.12: Mainnet and Testnet `_ +.. [#protocol-constants] `Zcash Protocol Specification, Version 2025.6.0 [NU6.1 proposal]. Section 5.3: Constants `_ +.. [#protocol-transparentaddrencoding] `Zcash Protocol Specification, Version 2025.6.0 [NU6.1 proposal]. Section 5.6.1.1: Transparent Addresses `_ +.. [#protocol-saplingpaymentaddrencoding] `Zcash Protocol Specification, Version 2025.6.0 [NU6.1 proposal]. Section 5.6.3.1: Sapling Payment Addresses `_ +.. [#protocol-txnconsensus] `Zcash Protocol Specification, Version 2025.6.0 [NU6.1 proposal]. Section 7.1.2: Transaction Consensus Rules `_ +.. [#protocol-diffadjustment] `Zcash Protocol Specification, Version 2025.6.0 [NU6.1 proposal]. Section 7.7.3: Difficulty adjustment `_ +.. [#protocol-subsidies] `Zcash Protocol Specification, Version 2025.6.0 [NU6.1 proposal]. Section 7.8: Calculation of Block Subsidy, Funding Streams, and Founders’ Reward `_ +.. [#protocol-foundersreward] `Zcash Protocol Specification, Version 2025.6.0 [NU6.1 proposal]. Section 7.9: Payment of Founders’ Reward `_ +.. [#protocol-fundingstreams] `Zcash Protocol Specification, Version 2025.6.0 [NU6.1 proposal]. Section 7.10: Payment of Funding Streams, Deferred Lockbox, and Lockbox Disbursement `_ +.. [#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 `_ +.. [#Bitcoin-Multisig] `Bitcoin Developer Documentation — Pay To Script Hash (P2SH) — Multisig `_ diff --git a/zips/zip-0208.rst b/zips/zip-0208.rst index cf9840f27..c81865370 100644 --- a/zips/zip-0208.rst +++ b/zips/zip-0208.rst @@ -2,9 +2,8 @@ ZIP: 208 Title: Shorter Block Target Spacing - Owners: Daira-Emma Hopwood - Original-Authors: Daira-Emma Hopwood - Simon Liu + Owners: Daira-Emma Hopwood + Original-Authors: Simon Liu Status: Final Category: Consensus Created: 2019-01-10 @@ -71,112 +70,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 +199,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 +335,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 +399,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-0209.rst b/zips/zip-0209.rst index ffb35f6fd..17aa3ab5d 100644 --- a/zips/zip-0209.rst +++ b/zips/zip-0209.rst @@ -2,8 +2,8 @@ ZIP: 209 Title: Prohibit Negative Shielded Chain Value Pool Balances - Owners: Sean Bowe - Daira-Emma Hopwood + Owners: Sean Bowe + Daira-Emma Hopwood Status: Final Category: Consensus Created: 2019-02-25 diff --git a/zips/zip-0210.rst b/zips/zip-0210.rst index bee141a97..a069f4adf 100644 --- a/zips/zip-0210.rst +++ b/zips/zip-0210.rst @@ -2,7 +2,7 @@ ZIP: 210 Title: Sapling Anchor Deduplication within Transactions - Owners: Jack Grigg + Owners: Jack Grigg Status: Withdrawn Category: Consensus Created: 2019-03-27 diff --git a/zips/zip-0211.rst b/zips/zip-0211.rst index f857af188..ceef694fa 100644 --- a/zips/zip-0211.rst +++ b/zips/zip-0211.rst @@ -2,7 +2,7 @@ ZIP: 211 Title: Disabling Addition of New Value to the Sprout Chain Value Pool - Owners: Daira-Emma Hopwood + Owners: Daira-Emma Hopwood Credits: Sean Bowe Status: Final Category: Consensus diff --git a/zips/zip-0212.rst b/zips/zip-0212.rst index 0669e8f60..fb292d3a2 100644 --- a/zips/zip-0212.rst +++ b/zips/zip-0212.rst @@ -2,7 +2,8 @@ ZIP: 212 Title: Allow Recipient to Derive Ephemeral Secret from Note Plaintext - Owners: Sean Bowe + Owners: Sean Bowe + Daira-Emma Hopwood Status: Final Category: Consensus Created: 2019-03-31 @@ -19,17 +20,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 +55,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 +85,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 +96,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 +122,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 +140,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. @@ -164,36 +165,36 @@ Changes to the process of sending Sapling or Orchard notes The process of sending notes is described in section 4.7.2 of the Zcash 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 +a note is described in section 4.20.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 @@ -204,12 +205,13 @@ where :math:`\underline{\text{ρ}} = \mathsf{I2LEOSP}_{256}(\mathsf{nf^{old}}` f Changes to the process of receiving Sapling or Orchard notes ------------------------------------------------------------ -The process of receiving notes in Sapling is described in sections 4.19.2 and -4.19.3 of the Zcash Protocol Specification. [#protocol-decryptivk]_ -[#protocol-decryptovk]_ +The process of receiving notes in Sapling or Orchard is described in sections +4.20.2 and 4.20.3 of the Zcash Protocol Specification. [#protocol-decryptivk]_ +[#protocol-decryptovk]_ (Only Sapling was deployed at the initial activation of +this ZIP, but it now applies to both Sapling and Orchard.) 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 +228,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 +241,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 +255,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 +278,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 +296,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 +317,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 @@ -354,20 +356,20 @@ 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 2023.4.0 or later `_ -.. [#protocol-abstractprfs] `Zcash Protocol Specification, Version 2023.4.0. Section 4.1.2: Pseudo Random Functions `_ -.. [#protocol-abstractcommit] `Zcash Protocol Specification, Version 2023.4.0. Section 4.1.8: Commitment `_ -.. [#protocol-saplingkeycomponents] `Zcash Protocol Specification, Version 2023.4.0. Section 4.2.2: Sapling Key Components `_ -.. [#protocol-orchardkeycomponents] `Zcash Protocol Specification, Version 2023.4.0. Section 4.2.3: Orchard Key Components `_ -.. [#protocol-saplingsend] `Zcash Protocol Specification, Version 2023.4.0. Section 4.7.2: Sending Notes (Sapling) `_ -.. [#protocol-orchardsend] `Zcash Protocol Specification, Version 2023.4.0. Section 4.7.3: Sending Notes (Orchard) `_ -.. [#protocol-saplingandorchardencrypt] `Zcash Protocol Specification, Version 2023.4.0. Section 4.19.1: Encryption (Sapling and Orchard) `_ -.. [#protocol-decryptivk] `Zcash Protocol Specification, Version 2023.4.0. Section 4.19.2: Decryption using an Incoming Viewing Key (Sapling and Orchard) `_ -.. [#protocol-decryptovk] `Zcash Protocol Specification, Version 2023.4.0. Section 4.19.3: Decryption using a Full Viewing Key (Sapling and Orchard) `_ -.. [#protocol-concretediversifyhash] `Zcash Protocol Specification, Version 2023.4.0. Section 5.4.1.6: DiversifyHash^Sapling and DiversifyHash^Orchard Hash Functions `_ -.. [#protocol-concretesaplingkeyagreement] `Zcash Protocol Specification, Version 2023.4.0. Section 5.4.5.3 Sapling Key Agreement `_ -.. [#protocol-concreteorchardkeyagreement] `Zcash Protocol Specification, Version 2023.4.0. Section 5.4.5.5 Orchard Key Agreement `_ -.. [#protocol-notept] `Zcash Protocol Specification, Version 2023.4.0. Section 5.5: Encodings of Note Plaintexts and Memo Fields `_ -.. [#zip-0207] `ZIP 207: Split Founders' Reward `_ +.. [#protocol-abstractprfs] `Zcash Protocol Specification, Version 2025.6.1 [NU6.1]. Section 4.1.2: Pseudo Random Functions `_ +.. [#protocol-abstractcommit] `Zcash Protocol Specification, Version 2025.6.1 [NU6.1]. Section 4.1.8: Commitment `_ +.. [#protocol-saplingkeycomponents] `Zcash Protocol Specification, Version 2025.6.1 [NU6.1]. Section 4.2.2: Sapling Key Components `_ +.. [#protocol-orchardkeycomponents] `Zcash Protocol Specification, Version 2025.6.1 [NU6.1]. Section 4.2.3: Orchard Key Components `_ +.. [#protocol-saplingsend] `Zcash Protocol Specification, Version 2025.6.1 [NU6.1]. Section 4.7.2: Sending Notes (Sapling) `_ +.. [#protocol-orchardsend] `Zcash Protocol Specification, Version 2025.6.1 [NU6.1]. Section 4.7.3: Sending Notes (Orchard) `_ +.. [#protocol-saplingandorchardencrypt] `Zcash Protocol Specification, Version 2025.6.1 [NU6.1]. Section 4.20.1: Encryption (Sapling and Orchard) `_ +.. [#protocol-decryptivk] `Zcash Protocol Specification, Version 2025.6.1 [NU6.1]. Section 4.20.2: Decryption using an Incoming Viewing Key (Sapling and Orchard) `_ +.. [#protocol-decryptovk] `Zcash Protocol Specification, Version 2025.6.1 [NU6.1]. Section 4.20.3: Decryption using an Outgoing Viewing Key (Sapling and Orchard) `_ +.. [#protocol-concretediversifyhash] `Zcash Protocol Specification, Version 2025.6.1 [NU6.1]. Section 5.4.1.6: DiversifyHash^Sapling and DiversifyHash^Orchard Hash Functions `_ +.. [#protocol-concretesaplingkeyagreement] `Zcash Protocol Specification, Version 2025.6.1 [NU6.1]. Section 5.4.5.3 Sapling Key Agreement `_ +.. [#protocol-concreteorchardkeyagreement] `Zcash Protocol Specification, Version 2025.6.1 [NU6.1]. Section 5.4.5.5 Orchard Key Agreement `_ +.. [#protocol-notept] `Zcash Protocol Specification, Version 2025.6.1 [NU6.1]. Section 5.5: Encodings of Note Plaintexts and Memo Fields `_ +.. [#zip-0207] `ZIP 207: Funding Streams `_ .. [#zip-0213] `ZIP 213: Shielded Coinbase `_ .. [#zip-0251] `ZIP 251: Deployment of the Canopy Network Upgrade `_ .. [#zip-0252] `ZIP 252: Deployment of the NU5 Network Upgrade `_ diff --git a/zips/zip-0213.rst b/zips/zip-0213.rst index 5914317a9..181427d96 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]_). @@ -130,9 +130,9 @@ be shielded immediately. Enforcing coinbase maturity at the consensus level for Sapling outputs would incur significant complexity in the consensus rules, because it would require special-casing coinbase note commitments in the Sapling commitment tree. The standard recommendation when -spending a note is to select an anchor 10 blocks back from the current chain tip, which -acts as a de-facto 10-block maturity on all notes, coinbase included. This might be -proposed as a consensus rule in future. +spending a note is to select an anchor 3 blocks back from the current chain tip (see ZIP +315 [#zip-0315-anchor-selection]_), which acts as a de-facto 3-block maturity on all notes, coinbase +included. This might be proposed as a consensus rule in future. There is another reason for shielded coinbase maturity being unnecessary: shielded coinbase outputs have the same effect on economic activity as regular shielded outputs. @@ -202,6 +202,7 @@ 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" `_ .. [#zip-0200] `ZIP 200: Network Upgrade Mechanism `_ .. [#zip-0205] `ZIP 205: Deployment of the Sapling Network Upgrade `_ -.. [#zip-0207] `ZIP 207: Split Founders' Reward `_ +.. [#zip-0207] `ZIP 207: Funding Streams `_ .. [#zip-0250] `ZIP 250: Deployment of the Heartwood Network Upgrade `_ .. [#zip-0252] `ZIP 252: Deployment of the NU5 Network Upgrade `_ +.. [#zip-0315-anchor-selection] `ZIP 315: Best Practices for Wallet Implementations — Anchor selection `_ diff --git a/zips/zip-0214.rst b/zips/zip-0214.rst index d4fa10c96..ebe89aa23 100644 --- a/zips/zip-0214.rst +++ b/zips/zip-0214.rst @@ -2,11 +2,12 @@ ZIP: 214 Title: Consensus rules for a Zcash Development Fund - Owners: Daira-Emma Hopwood + Owners: Daira-Emma Hopwood Kris Nuttycombe - Status: Revision 0: Final, Revision 1: Draft + Status: [Revision 0: Canopy, Revision 1: NU6] Final, [Revision 2: NU6.1] Proposed Category: Consensus Created: 2020-02-28 + Last-Updated: 2025-10-14 License: MIT Discussions-To: @@ -24,15 +25,15 @@ agreement) while that agreement is in effect. On termination of that agreement, the term "Zcash" will refer to the continuations of the same Mainnet and Testnet block chains as determined by social consensus. -The term "network upgrade" in this document is to be interpreted as -described in ZIP 200 [#zip-0200]_ and the Zcash Trademark Donation and License -Agreement ([#trademark]_ or successor agreement). +The term "network upgrade" in this document is to be interpreted as described +in ZIP 200 [#zip-0200]_, and the Zcash Trademark Donation and License Agreement +([#trademark]_ or successor agreement) while that agreement is in effect. The term "block subsidy" in this document is to be interpreted as described in section 3.10 of the Zcash Protocol Specification [#protocol-subsidyconcepts]_. -The term "halving" in this document are to be interpreted as described in -sections 7.8 of the Zcash Protocol Specification [#protocol-subsidies]_. +The term "halving" in this document is to be interpreted as described in +section 7.8 of the Zcash Protocol Specification [#protocol-subsidies]_. The terms "Bootstrap Project" (or "BP"), "Electric Coin Company" (or "ECC"), "Zcash Foundation" (or "ZF"), "Major Grants", "BP slice", "ZF slice", and @@ -61,9 +62,12 @@ 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. +`Revision 2`_ of this ZIP describes consensus rule changes related to funding +of Zcash development via block subsidies, to be enacted at Network Upgrade 6.1 +and lasting for 3 years. Applicability ============= @@ -121,6 +125,12 @@ Revisions * Revision 1: Funding streams defined to start at Zcash's second halving, and last for one year, as agreed upon in ZIP 1015 [#zip-1015]_. +.. _`Revision 2`: + +* Revision 2: Funding streams defined to start at the end height of the + `Revision 2`_ funding streams, and last for three years, as agreed upon + in ZIP 1016 [#zip-1016]_. + Activation ---------- @@ -133,7 +143,7 @@ the activation height of Canopy on Mainnet therefore SHALL be 1046400. `Revision 0`_ of ZIP 207 [#zip-0207]_ SHALL be activated in Canopy. -Since ZIP 1015 specifies that the specified funding streams start at the second +Since ZIP 1015 specifies that the specified funding streams start at the second halving, the activation height of NU6 on Mainnet therefore SHALL be 2726400. `Revision 1`_ of ZIP 207 [#zip-0207]_ SHALL be activated in NU6. @@ -147,23 +157,23 @@ Funding Streams As of `Revision 0`_, the following funding streams are defined for Mainnet: - ================= =========== ============= ============== ============ - Stream Numerator Denominator Start height End height - ================= =========== ============= ============== ============ - ``FS_ZIP214_BP`` 7 100 1046400 2726400 - ``FS_ZIP214_ZF`` 5 100 1046400 2726400 - ``FS_ZIP214_MG`` 8 100 1046400 2726400 - ================= =========== ============= ============== ============ +================= =========== ============= ============== ============ + Stream Numerator Denominator Start height End height +================= =========== ============= ============== ============ +``FS_ZIP214_BP`` 7 100 1046400 2726400 +``FS_ZIP214_ZF`` 5 100 1046400 2726400 +``FS_ZIP214_MG`` 8 100 1046400 2726400 +================= =========== ============= ============== ============ As of `Revision 0`_, the following funding streams are defined for Testnet: - ================= =========== ============= ============== ============ - Stream Numerator Denominator Start height End height - ================= =========== ============= ============== ============ - ``FS_ZIP214_BP`` 7 100 1028500 2796000 - ``FS_ZIP214_ZF`` 5 100 1028500 2796000 - ``FS_ZIP214_MG`` 8 100 1028500 2796000 - ================= =========== ============= ============== ============ +================= =========== ============= ============== ============ + Stream Numerator Denominator Start height End height +================= =========== ============= ============== ============ +``FS_ZIP214_BP`` 7 100 1028500 2796000 +``FS_ZIP214_ZF`` 5 100 1028500 2796000 +``FS_ZIP214_MG`` 8 100 1028500 2796000 +================= =========== ============= ============== ============ As of `Revision 1`_, the following additional streams are defined for Mainnet: @@ -183,6 +193,24 @@ As of `Revision 1`_, the following additional streams are defined for Testnet: ``FS_DEFERRED`` 12 100 2976000 3396000 ================= =========== ============= ============== ============ +As of `Revision 2`_, the following additional streams are defined for Mainnet: + +================= =========== ============= ============== ============ + Stream Numerator Denominator Start height End height +================= =========== ============= ============== ============ +``FS_FPF_ZCG_H3`` 8 100 3146400 4406400 +``FS_CCF_H3`` 12 100 3146400 4406400 +================= =========== ============= ============== ============ + +As of `Revision 2`_, the following additional streams are defined for Testnet: + +================= =========== ============= ============== ============ + Stream Numerator Denominator Start height End height +================= =========== ============= ============== ============ +``FS_FPF_ZCG_H3`` 8 100 3536500 4476000 +``FS_CCF_H3`` 12 100 3536500 4476000 +================= =========== ============= ============== ============ + Notes for `Revision 0`_: * The block heights of halvings are different between Testnet and Mainnet, as a @@ -198,7 +226,7 @@ Notes for `Revision 0`_: Notes for `Revision 1`_: -* The new funding streams begin at the second halving for Mainnet, but the second +* The new funding streams begin at the second halving for Mainnet, but the second halving on Testnet occurred prior to the introduction of the new funding streams. For both new funding streams on each network, the associated duration corresponds to approximately one year's worth of blocks. @@ -297,10 +325,21 @@ Mainnet Recipient Addresses for `Revision 0`_ (i.e. ``FS_ZIP214_ZF.AddressList`` and ``FS_ZIP214_MG.AddressList`` for Mainnet each consist of 48 repetitions of the same address). -Mainnet Recipient Addresses for `Revision 1`_ ---------------------------------------------- +Mainnet Recipients for `Revision 1`_ +------------------------------------ + +:: FS_FPF_ZCG.AddressList[0..11] = ["t3cFfPt1Bcvgez9ZbMBFWeZsskxTkPzGCow"] * 12 + FS_DEFERRED = DEFERRED_POOL as defined in ZIP 207 + +Mainnet Recipients for `Revision 2`_ +------------------------------------ + +:: + + FS_FPF_ZCG_H3.AddressList[0..35] = ["t3cFfPt1Bcvgez9ZbMBFWeZsskxTkPzGCow"] * 36 + FS_CCF_H3 = DEFERRED_POOL as defined in ZIP 207 Testnet Recipient Addresses for `Revision 0`_ --------------------------------------------- @@ -368,11 +407,21 @@ Testnet Recipient Addresses for `Revision 0`_ (i.e. ``FS_ZIP214_ZF.AddressList`` and ``FS_ZIP214_MG.AddressList`` for Testnet each consist of 51 repetitions of the same address). -Testnet Recipient Addresses for `Revision 1`_ ---------------------------------------------- +Testnet Recipients for `Revision 1`_ +------------------------------------ + +:: FS_FPF_ZCG.AddressList[0..12] = ["t2HifwjUj9uyxr9bknR8LFuQbc98c3vkXtu"] * 13 + FS_DEFERRED = DEFERRED_POOL as defined in ZIP 207 + +Testnet Recipients for `Revision 2`_ +------------------------------------ + +:: + FS_FPF_ZCG_H3.AddressList[0..26] = ["t2HifwjUj9uyxr9bknR8LFuQbc98c3vkXtu"] * 27 + FS_CCF_H3 = DEFERRED_POOL as defined in ZIP 207 Rationale for `Revision 0`_ =========================== @@ -394,17 +443,58 @@ Deployment ========== `Revision 0`_ of this proposal was deployed with Canopy. [#zip-0251]_ -`Revision 1`_ of this proposal is intended to be deployed with NU6. [#zip-0253]_ +`Revision 1`_ of this proposal was deployed with NU6. [#zip-0253]_ + +`Revision 2`_ of this proposal is intended to be deployed with NU6.1. [#zip-0255]_ + + +Change History +============== + +2025-10-14 +---------- + +- Updated Revision 2 to set the `FS_FPF_ZCG_H3` mainnet address. + +2025-08-19 +---------- + +- Released Revision 2. + +2024-10-31 +---------- + +- Released Revision 1. + +2024-09-26 +---------- + +- Updated Revision 1 to set the `FS_FPF_ZCG` mainnet address. + +2024-08-26 +---------- + +- Added draft of Revision 1. + +2020-11-03 +---------- + +- Updated Revision 0 to set the mainnet Funding Stream addresses. + +2020-05-30 +---------- + +- Released Revision 0. 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, Funding Streams, and Founders' Reward `_ -.. [#protocol-networks] `Zcash Protocol Specification, Version 2024.5.1 [NU6]. Section 3.12: Mainnet and Testnet `_ -.. [#protocol-subsidies] `Zcash Protocol Specification, Version 2024.5.1 [NU6]. Section 7.8: Calculation of Block Subsidy, Funding Streams, and Founders' Reward `_ +.. [#protocol] `Zcash Protocol Specification, Version 2025.6.0 [NU6.1 proposal] or later `_ +.. [#protocol-subsidyconcepts] `Zcash Protocol Specification, Version 2025.6.0 [NU6.1 proposal]. Section 3.10: Block Subsidy, Funding Streams, and Founders’ Reward `_ +.. [#protocol-networks] `Zcash Protocol Specification, Version 2025.6.0 [NU6.1 proposal]. Section 3.12: Mainnet and Testnet `_ +.. [#protocol-subsidies] `Zcash Protocol Specification, Version 2025.6.0 [NU6.1 proposal]. Section 7.8: Calculating Block Subsidy, Funding Streams, Lockbox Disbursement, and Founders’ Reward `_ .. [#trademark] `Zcash Trademark Donation and License Agreement `_ .. [#osd] `The Open Source Definition `_ .. [#zip-0200] `ZIP 200: Network Upgrade Mechanism `_ @@ -412,5 +502,7 @@ References .. [#zip-0208] `ZIP 208: Shorter Block Target Spacing `_ .. [#zip-0251] `ZIP 251: Deployment of the Canopy Network Upgrade `_ .. [#zip-0253] `ZIP 253: Deployment of the NU6 Network Upgrade `_ +.. [#zip-0255] `ZIP 255: Deployment of the NU6.1 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 `_ +.. [#zip-1016] `ZIP 1016: Community and Coinholder Funding Model `_ 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..0f62bd065 100644 --- a/zips/zip-0216.rst +++ b/zips/zip-0216.rst @@ -2,8 +2,8 @@ ZIP: 216 Title: Require Canonical Jubjub Point Encodings - Owners: Jack Grigg - Daira-Emma Hopwood + Owners: Jack Grigg + Daira-Emma Hopwood Status: Final Category: Consensus Created: 2021-02-11 @@ -20,12 +20,18 @@ 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 terms "settled" and "full validator" in this document are to be interpreted as +described in [#protocol-blockchain]_. + +The terms "Mainnet" and "Testnet" in this document are to be interpreted as described +in [#protocol-networks]_. + Abstract ======== This ZIP fixes an oversight in the implementation of the Sapling consensus rules, by -rejecting all non-canonical representations of Jubjub points. +rejecting all non‑canonical representations of Jubjub points. Motivation @@ -39,7 +45,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,17 +57,17 @@ 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`. +Each of these has a single non‑canonical encoding in which the value of the sign bit is +$1$. -This creates a consensus issue because (unlike other non-canonical point encodings that +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 +*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`). @@ -69,163 +75,278 @@ 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. +prohibit small‑order points, and this incidentally prohibits non‑canonical encodings. Adjustments to the protocol specification were made in versions 2020.1.8, 2020.1.9, -2020.1.15, and 2021.1.17 to match the `zcashd` implementation. (The fact that this -required 4 specification revisions to get right, conclusively demonstrates the problem.) +2020.1.15, 2021.1.17, and 2023.4.0 to match the `zcashd` implementation. Further +changes were also made in version 2025.6.0. The fact that this required six +specification revisions to get right, conclusively demonstrates the problem. 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`. +Define a non‑canonical compressed encoding of a Jubjub point to be a sequence of +$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)`. -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. +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)$. +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 $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. +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 $\mathsf{C^{out}}$ field of a +Sapling transmitted note ciphertext (encrypted in [#protocol-saplingandorchardencrypt]_ +and decrypted in [#protocol-decryptovk]_): + + - $\mathsf{pk\star_d}$. -In the plaintext obtained by decrypting the :math:`\mathsf{C^{out}}` field of a -Sapling transmitted note ciphertext [#protocol-decryptovk]_: +$\mathsf{pk\star_d}$ also MUST be considered invalid if it encodes the zero point +$\mathcal{O}_{\mathbb{J}}$. - - :math:`\mathsf{pk}\star_{\mathsf{d}}`. +These requirements on $\mathsf{pk\star_d}$ affect the decryption of +$\mathsf{C^{out}}$ in all cases, but are consensus-critical only in the case +of decrypting $\mathsf{C^{out}}$ for a Sapling shielded coinbase output. +[#protocol-txnconsensus]_ [#zip-0213]_ -(This affects decryption of :math:`\mathsf{C^{out}}` in all cases, but is -consensus-critical only in the case of a shielded coinbase output. -[#protocol-txnencoding]_) +Note: When a Sapling transmitted note ciphertext is decrypted using an incoming +viewing key [#protocol-decryptivk]_, $\mathsf{pk_d}$ is computed as +$\mathsf{KA^{Sapling}.DerivePublic}(\mathsf{ivk}, \mathsf{g_d}) =$ $[\mathsf{ivk}]\,\mathsf{g_d}$. +Since $\mathsf{g_d}$ is an output of +$\mathsf{DiversifyHash^{Sapling}} \;{\small ⦂}\; \mathbb{B}^{[\ell_d]} \rightarrow \mathbb{J}^{(r)*} \cup \{\bot\}$, +it cannot be $\mathcal{O}_{\mathbb{J}}$. $\mathsf{ivk}$ cannot be $0$ for a validly +constructed Sapling incoming viewing key [#protocol-saplingkeycomponents]_, and +so the computed value of $\mathsf{pk_d}$ cannot be $\mathcal{O}_{\mathbb{J}}$. +An implementation MAY redundantly enforce that the computed value of $\mathsf{pk_d}$ +is not $\mathcal{O}_{\mathbb{J}}$. There are some additional fields in the consensus protocol that encode Jubjub points, -but where non-canonical encodings MUST already be rejected as a side-effect of +but where non‑canonical encodings MUST already be rejected as a side effect of 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. +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 +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 :math:`\mathbb{J}^{(r)}`. These requirements -\MAY be enforced in advance of NU5 activation. +imported if they contain non‑canonical Jubjub point encodings, or encodings of points +that are not in the prime‑order subgroup $\mathbb{J}^{(r)}$. These requirements +\MAY be enforced in advance of NU5 activation. This affects the fields listed below. -In Sapling addresses [#protocol-saplingpaymentaddrencoding]_: +In Sapling payment 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}`. - -(:math:`\mathsf{ak}` also MUST NOT encode the zero point :math:`\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. + - the encoding of $\mathsf{ak}$ + - the encoding of $\mathsf{nk}$. + +$\mathsf{pk_d}$ and $\mathsf{ak}$ also MUST be considered invalid if they encode the +zero point $\mathcal{O}_{\mathbb{J}}$. + +The fields mentioned in this Specification are 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. + +Note: Some versions of the Zcash protocol specification mistakenly allowed $\mathsf{pk_d}$ +in a Sapling payment address, or $\mathsf{pk\star_d}$ in a decrypted $\mathsf{C^{out}}$, +to encode the zero point. The history is explained in a note added in version 2023.4.0 of +the protocol specification [#protocol-2023.4.0]_: + + A previous version of this specification did not have the requirement for the decoded point + $\mathsf{pk_d}$ of a Sapling note to be in the set of prime‑order points $\mathbb{J}^{(r)*}$ + (i.e. "if ... $\mathsf{pk_d} \not\in \mathbb{J}^{(r)*}$, return $\bot\!$"). + That did not match the implementation in `zcashd`. In fact the history is a little more + complicated. The current specification matches the implementation in `librustzcash` as of + [#librustzcash-pr109]_, which has been used in `zcashd` since v2.1.2. However, there was + another implementation of Sapling note decryption used in `zcashd` for consensus checks, + specifically the check that a shielded coinbase output decrypts successfully with the + zero $\mathsf{ovk}$. This was corrected to enforce the same restriction on the decrypted + $\mathsf{pk_d}$ in `zcashd` v5.5.0, originally set to activate in a soft fork at block + height 2121200 on both Mainnet and Testnet [#zcashd-pr6459]_. (On Testnet this height was + in the past as of the `zcashd` v5.5.0 release, and so the change would have been immediately + enforced on upgrade.) Since the soft fork was observed to be retrospectively valid after + that height, the implementation was simplified in [#zcashd-pr6725]_ to use the + `librustzcash` implementation in all cases, which reflects the specification above. + `zebra` always used the `librustzcash` implementation. + +The protocol specification was further updated in version 2025.6.0 [#protocol-2025.6.0]_, +to tighten the type of $\mathsf{ivk}$ in Sapling to +$\{ 1\,..\, 2^{\ell^{\mathsf{Sapling}}_{\mathsf{ivk}}}\!-1 \}$ and the type of $\mathsf{pk_d}$ +in both Sapling and Orchard to $\mathsf{KA^{protocol}.PublicPrimeOrder}$, in order to make +the exclusion of the zero point more obvious [#zips-issue664]_. This also has the effect +that a Sapling incoming viewing key [#protocol-saplinginviewingkeyencoding]_ or a Sapling +IVK Encoding in a Unified Incoming Viewing Key [#zip-0316]_ that encodes the zero +$\mathsf{ivk}$ MUST be considered invalid when imported. Another note was also added +explicitly covering the encoding of $\mathsf{pk_d}$ in Sapling payment addresses +[#protocol-saplingpaymentaddrencoding]_: + + The restriction on $\mathsf{pk_d}$ reflects its current type + $\mathsf{KA^{Sapling}.PublicPrimeOrder} = \mathbb{J}^{(r)*}$. In versions of this + specification prior to 2025.6.0, $\mathsf{pk_d}$ had type + $\mathsf{KA^{Sapling}.PublicPrimeSubgroup} = \mathbb{J}^{(r)}$, i.e. including + $\mathcal{O}_{\mathbb{J}}$. Implementations of consumers for this encoding may need + to be updated to exclude $\mathcal{O}_{\mathbb{J}}$, and should be checked for + consistency with the current version of [ZIP-216]. + +Retroactive applicability +------------------------- + +As originally specified, this ZIP required that the new validity rules be applied only +after NU5 activation. This was necessary because a transaction containing a non‑canonical +Jubjub point encoding could have been included in any block before NU5 activation. + +However, now that NU5 is a settled upgrade on the Zcash Mainnet and Testnet chains +[#protocol-blockchain]_ [#protocol-networks]_, it can be observed that there were no such +non‑canonical encodings in publically visible transaction fields before the Mainnet and +Testnet NU5 activations. Therefore, a full validator MAY enforce the above specification +retroactively. + +It remains possible that there could be non‑canonical $\mathsf{pk\star_d}$ encodings in +plaintexts obtained by decrypting the $\mathsf{C^{out}}$ field of a Sapling transmitted +note ciphertext. Such encodings MUST be rejected by the decryption procedure in +[#protocol-decryptovk]_ as currently specified. In version 2025.6.0 of the protocol +specification [#protocol-2025.6.0]_ this procedure has been changed to reject them +unconditionally, not only after NU5 activation. (This has no effect on consensus relative +to the previous version, because only small‑order Jubjub curve points have non‑canonical +encodings, and so the check that returns $\bot$ if $\mathsf{pk_d} ∉ \mathbb{J}^{(r)*}$ +would catch all such cases.) + +Rejecting non‑canonical $\mathsf{pk\star_d}$ encodings cannot lead to loss of funds +sent to a Sapling address that has been correctly generated as specified in +[#protocol-saplingkeycomponents]_, because such an address cannot have $\mathsf{ivk} = 0$, +which is the only case in which $\mathsf{pk\star_d}$ could be non‑canonical. +They are rejected in wallet rescanning by current `zcashd` and by `librustzcash`-based +light wallets. + +Note: There are no such non‑canonical $\mathsf{pk\star_d}$ encodings in the +$\mathsf{C^{out}}$ components of shielded coinbase outputs (which are required by +consensus to be decryptable by an all-zero $\mathsf{ovk}$ [#protocol-txnconsensus]_). Rationale ========= -Zcash previously had a similar issue with non-canonical representations of points in +Zcash previously had a similar issue with non‑canonical representations of points in Ed25519 public keys and signatures. In that case, given the prevalence of Ed25519 signatures in the wider ecosystem, the decision was made in ZIP 215 [#zip-0215]_ (which -activated with the Canopy network upgrade [#zip-0251]_) to allow non-canonical +activated with the Canopy network upgrade [#zip-0251]_) to allow non‑canonical representations of points. -In Sapling, we are motivated instead to reject these non-canonical points: +In Sapling, we are motivated instead to reject these non‑canonical points: - The chance of the identity occurring anywhere within the Sapling components of transactions from implementations following the standard protocol is cryptographically negligible. - This re-enables the aforementioned simpler security analysis of the Sapling protocol. -- The Jubjub curve has a vastly-smaller scope of usage in the general cryptographic +- The Jubjub curve has a vastly smaller scope of usage in the general cryptographic ecosystem than Curve25519 and Ed25519. 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. +Encodings of elliptic curve points on the Pallas and Vesta curves [#protocol-pallasandvesta]_ +used by the Orchard shielded protocol are also not affected. Security and Privacy Considerations =================================== This ZIP eliminates a potential source of consensus divergence between differing full node -implementations. At the time of writing (February 2021), no such divergence exists for any -production implementation of Zcash, but the alpha-stage `zebrad` node implementation would -be susceptible to this issue. +implementations. From February 2023 onward, no known divergence of this type exists for +any production implementation of Zcash, but an early alpha version of the `zebrad` node +implementation would have been susceptible to this issue. Deployment ========== -This ZIP is proposed to activate with Network Upgrade 5. Requirements on points encoded in -payment addresses and full viewing keys MAY be enforced in advance of NU5 activation. +This ZIP activated with Network Upgrade 5. Requirements on points encoded in payment +addresses and full viewing keys MAY be enforced in advance of NU5 activation. + +`zcashd` PRs #6000 [#zcashd-pr6000]_, #6399 [#zcashd-pr6399]_, #6459 [#zcashd-pr6459]_, +and #6725 [#zcashd-pr6725]_ retroactively enforce canonical encoding of Jubjub points +for the entire chain history, as described in the `Retroactive applicability`_ section. 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 2021.2.16 or later [NU5 proposal] `_ -.. [#protocol-spenddesc] `Zcash Protocol Specification, Version 2021.2.16 [NU5 proposal]. Section 4.4: Spend Descriptions `_ -.. [#protocol-outputdesc] `Zcash Protocol Specification, Version 2021.2.16 [NU5 proposal]. Section 4.5: Output Descriptions `_ -.. [#protocol-decryptovk] `Zcash Protocol Specification, Version 2021.2.16 [NU5 proposal]. Section 4.19.3 Decryption using a Full Viewing Key (Sapling and Orchard) `_ -.. [#protocol-jubjub] `Zcash Protocol Specification, Version 2021.2.16 [NU5 proposal]. Section 5.4.9.3: Jubjub `_ -.. [#protocol-pallasandvesta] `Zcash Protocol Specification, Version 2021.2.16 [NU5 proposal]. Section 5.4.9.6: Pallas and Vesta `_ -.. [#protocol-saplingpaymentaddrencoding] `Zcash Protocol Specification, Version 2021.2.16 [NU5 proposal]. Section 5.6.3.1: Sapling Payment Addresses `_ -.. [#protocol-saplingfullviewingkeyencoding] `Zcash Protocol Specification, Version 2021.2.16 [NU5 proposal]. Section 5.6.3.3: Sapling Full Viewing Keys `_ -.. [#protocol-txnencoding] `Zcash Protocol Specification, Version 2021.2.16 [NU5 proposal]. Section 7.1: Transaction Encoding and Consensus `_ +.. [#protocol] `Zcash Protocol Specification, Version 2025.6.1 [NU6.1] or later `_ +.. [#protocol-blockchain] `Zcash Protocol Specification, Version 2025.6.1 [NU6.1]. Section 3.3: The Block Chain `_ +.. [#protocol-networks] `Zcash Protocol Specification, Version 2025.6.1 [NU6.1]. Section 3.12: Mainnet and Testnet `_ +.. [#protocol-saplingkeycomponents] `Zcash Protocol Specification, Version 2025.6.1 [NU6.1]. Section 4.2.2: Sapling Key Components `_ +.. [#protocol-spenddesc] `Zcash Protocol Specification, Version 2025.6.1 [NU6.1]. Section 4.4: Spend Descriptions `_ +.. [#protocol-outputdesc] `Zcash Protocol Specification, Version 2025.6.1 [NU6.1]. Section 4.5: Output Descriptions `_ +.. [#protocol-saplingandorchardencrypt] `Zcash Protocol Specification, Version 2025.6.1 [NU6.1]. Section 4.20.1: Encryption (Sapling and Orchard) `_ +.. [#protocol-decryptivk] `Zcash Protocol Specification, Version 2025.6.1 [NU6.1]. Section 4.20.2: Decryption using an Incoming Viewing Key (Sapling and Orchard) `_ +.. [#protocol-decryptovk] `Zcash Protocol Specification, Version 2025.6.1 [NU6.1]. Section 4.20.3: Decryption using an Outgoing Viewing Key (Sapling and Orchard) `_ +.. [#protocol-jubjub] `Zcash Protocol Specification, Version 2025.6.1 [NU6.1]. Section 5.4.9.3: Jubjub `_ +.. [#protocol-pallasandvesta] `Zcash Protocol Specification, Version 2025.6.1 [NU6.1]. Section 5.4.9.6: Pallas and Vesta `_ +.. [#protocol-saplingpaymentaddrencoding] `Zcash Protocol Specification, Version 2025.6.1 [NU6.1]. Section 5.6.3.1: Sapling Payment Addresses `_ +.. [#protocol-saplinginviewingkeyencoding] `Zcash Protocol Specification, Version 2025.6.1 [NU6.1]. Section 5.6.3.2: Sapling Incoming Viewing Keys `_ +.. [#protocol-saplingfullviewingkeyencoding] `Zcash Protocol Specification, Version 2025.6.1 [NU6.1]. Section 5.6.3.3: Sapling Full Viewing Keys `_ +.. [#protocol-txnencoding] `Zcash Protocol Specification, Version 2025.6.1 [NU6.1]. Section 7.1: Transaction Encoding and Consensus `_ +.. [#protocol-txnconsensus] `Zcash Protocol Specification, Version 2025.6.1 [NU6.1]. Section 7.1.2: Transaction Consensus Rules `_ +.. [#protocol-2023.4.0] `Zcash Protocol Specification, Version 2023.4.0. Section 10: Change History — 2023.4.0 `_ +.. [#protocol-2025.6.0] `Zcash Protocol Specification, Version 2025.6.1 [NU6.1]. Section 10: Change History — 2025.6.0 `_ .. [#zip-0032-extfvk] `ZIP 32: Shielded Hierarchical Deterministic Wallets. Sapling extended full viewing keys `_ .. [#zip-0200] `ZIP 200: Network Upgrade Mechanism `_ +.. [#zip-0213] `ZIP 213: Shielded Coinbase `_ .. [#zip-0215] `ZIP 215: Explicitly Defining and Modifying Ed25519 Validation Rules `_ .. [#zip-0251] `ZIP 251: Deployment of the Canopy Network Upgrade `_ +.. [#zip-0316] `ZIP 316: Unified Addresses and Unified Viewing Keys `_ .. [#jubjub-crate] `jubjub Rust crate `_ +.. [#zcashd-pr6000] `zcash/zcash PR 6000: Enable ZIP 216 for blocks prior to NU5 activation `_ +.. [#zcashd-pr6399] `zcash/zcash PR 6399: Retroactively enable ZIP 216 before NU5 activation `_ +.. [#zcashd-pr6459] `zcash/zcash PR 6459: Migrate to zcash_primitives 0.10 `_ +.. [#zcashd-pr6725] `zcash/zcash PR 6725: Retroactively use Rust to decrypt shielded coinbase before soft fork `_ +.. [#librustzcash-pr109] `zcash/librustzcash PR 109: PaymentAddress encapsulation `_ +.. [#zips-issue664] `zcash/zips issue 664: Sapling pk\_d should not allow the zero point `_ diff --git a/zips/zip-0217.rst b/zips/zip-0217.rst index 4562d86fc..835d85cfd 100644 --- a/zips/zip-0217.rst +++ b/zips/zip-0217.rst @@ -2,7 +2,7 @@ ZIP: 217 Title: Aggregate Signatures - Owners: Daira-Emma Hopwood + Owners: Daira-Emma Hopwood Status: Reserved Category: Consensus - Discussions-To: + Discussions-To: diff --git a/zips/zip-0218.md b/zips/zip-0218.md new file mode 100644 index 000000000..9492341a4 --- /dev/null +++ b/zips/zip-0218.md @@ -0,0 +1,618 @@ + + ZIP: 218 + Title: 25-second Block Target Spacing + Owners: Dev Ojha + Evan Forbes + Status: Draft + Category: Consensus + Created: 2026-03-13 + License: MIT + Discussions-To: + + +# Terminology + +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 terms "block chain", "consensus rule change", "consensus branch", +and "network upgrade" are to be interpreted as defined in ZIP 200. +[^zip-0200] + +The term "block target spacing" means the time interval between blocks +targeted by the difficulty adjustment algorithm in a given consensus +branch. It is normally measured in seconds. (This is also sometimes +called the "target block time", but "block target spacing" is the term +used in the Zcash Protocol Specification [^protocol-diffadjustment].) + +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 + +This proposal specifies a change in the block target spacing from 75 +seconds to 25 seconds in NU7, and introduces per-pool action limits for +the Sapling and Orchard shielded protocols. + +This solves three problems. +- Significantly improves the UX for actors who need 1 or 2 conf's. (Near Intents, small payments) The user-latency goes down 3x. +- Increases consensus bandwidth, which amplifies the scaling impact of a future shielded pool which does not require shielded sync. +- Introduces action limits. These provide limits of the number of actions that can go into a block. There is a global limit across all pools, and per pool limits. It is configured to more than double the Orchard TPS (2.9 → 6.1 TPS), while lowering the impact a DoS attacker can impose on wallets; for example, maximum shielded sync bandwidth for light clients is reduced by 42% (270.5 → 156.83 MB/day). + +The action limits significantly decrease the number of Sprout and Sapling pool +outputs available per block, to lower the maximum shielded sync burden under +attempted DoS. + +The emission schedule of mined ZEC will be the same in terms of ZEC/day, +but this requires the emission per block to be adjusted +to take account of the changed block target spacing. + +# Motivation + +The motivations for decreasing the block target spacing are: + +- **Reduced transaction latency.** Currently, users must wait + 75 seconds on average for even a single confirmation, regardless + of network utilization. This creates friction for point-of-sale + payments, exchange deposits, and cross-chain bridge operations. A + 25-second target spacing reduces the expected wait for a first + confirmation to 25 seconds on average. + +- **Greater throughput.** With 3× as many blocks per day and the same + 2 MB block size limit, we will have allocated higher consensus bandwidth + capacity. Short term, when paired with the action limits, we will more than + double the Orchard TPS for 2-action transactions. Longer term, when we get a + shielded pool with no shielded sync burden, we will have 3x higher throughput. + +- **Complementary to finality improvements.** This proposal is + complementary to, and does not compete with, finality mechanisms + such as Crosslink [^crosslink]. Faster block times improve the + responsiveness of the base layer regardless of whether an additional finality + gadget is also deployed. + +The throughput goal on its own could be achieved via a block size increase. +However the goal of this proposal is to foremost improve the transaction +latency. + +It is estimated that this reduction in blocktime would increase the stale rate from today's 0.4% to 1.3%. For reference, Ethereum operated at 5.4% stale rate. + +There are multiple threat models for rollback attacks. Loosely speaking, +lowering block time while keeping it significantly lower than block propagation +delay helps improve finality time. This is because more honest +miners quickly build on the block, and the block propagation constraint ensures +stale rates have not significantly increased. See [^slowfastblocks] for +analysis in various attack models. As this proposal meets the constraint of +keeping stale rates low, this should under the "X% of hashpower is byzantine" +threat model improve user confirmation times by a factor slightly under 3x. +Under the post's "Economic" threat model, where the user requires the block +rewards built on-top of their payment to exceed the value of the payment, this +significantly improves the variance in confirmation latency (but makes the +mean latency a bit higher due to stale rate). As noted there, this attack model +is not applied at sizable transactions. It is only potentially applied for small-valued +transactions, where the granularity of block times likely lowers time +until sufficient finality. We do not argue for reducing block confirmation counts in this ZIP. +However, we do expect many classes of users to be able to reduce their expected +time until funds are considered to have been received under threat modelling +consistent with block confirmation counts they choose today. + +Zcash has a second cost imposed by scaling, the shielded sync. Every +shielded transaction induces a bandwidth overhead for every wallet +and an extra trial decryption, so we must carefully understand the impact a DOS +attacker can cause. Today the worst-case DoS attack can induce 270.5 +MB of wallet sync download to clients per day, and 4.8M trial decryptions per +day. We propose introducing global action limits and per-pool action limits as follows: + +- A maximum of 306 actions per block across all pools + +- A maximum of 306 Orchard actions per block + +- A maximum of 300 Sapling inputs + outputs. (Total inputs + outputs < 300) + +- A maximum of 25 Sprout JoinSplits per block. + +With these limits, the worst case becomes 156.83 MB bandwidth and 2.1M trial decrypts per day. This +is a 42% improvement in worst case wallet sync bandwidth despite 3x more blocks. +This yields a 2x in Orchard TPS, and keeps Sapling TPS at a higher level than +today's Orchard TPS. + +However, every wallet does have to download every compact block header, which +is 90 bytes. This leads to an extra 200kb of wallet bandwidth per day in +exchange for the improved UX. + +The reduced Sapling and Sprout per-block limits are justified by the +current distribution of shielded funds across pools. As of March 2026: + +| Pool | Balance | Share of shielded supply | +|------|---------|--------------------------| +| Orchard | 4,511,193 ZEC | 87.5% | +| Sapling | 616,131 ZEC | 12.0% | +| Sprout | 25,480 ZEC | 0.5% | + +The vast majority of shielded activity is already in Orchard, and this +trend is expected to continue. The Sapling and Sprout limits are set +generously relative to their current usage while substantially reducing +their potential for DoS. + +## Stale block rate + +The stale rate is the percentage of blocks that get orphaned, which relates to +mining centralization risk, block propagation delay, and block verification +times. Today the stale rate is 0.4%, but this may be lower than what pure block +propagation delay may imply due to hashpower centralization in mining pools. + +At 25-second block target spacing, the theoretical stale block rate is +approximately 3.26%, derived from measured Zcash network propagation +delays. A devnet experiment with 99 geographically-distributed Zebra +nodes producing 2MB blocks at 25-second target spacing measured a stale +block rate of 4.86% and a fork rate of 0.37%. Both observed figures are +below the 5.4% safety threshold set by Ethereum's historical proof-of-work +stale rate. [^forum-proposal] The only modification required to achieve +these rates was tuning TCP configuration (more details in the linked +footnote). The devnet's node distribution was significantly more +decentralized than today's mainnet, so these figures represent a +near worst-case scenario. [^devnet-blocktime-test] + + +## Block processing time + +A prerequisite for reducing the target block spacing is that block validation +and propagation must remain small relative to the target spacing. The per-pool +propagation remain small relative to the target spacing. The per-pool +action limits introduced by this proposal ensure that worst-case +*per-block* processing time is lower than today's. The fact that there +are three times as many blocks in unit time does mean that the *overall* +worst-case proportion of time taken for processing, and the worst cost of +sync after a given time offline for full nodes will increase. We accept this +trade-off. These computational limits parallelize well. The max bandwidth requirement from the chain is 655kbps, so syncing with 10mbps bandwidth still has a 15x advantage factor over full blocks on mainnet. + +**Current worst case:** A full 2 MB block today can contain up to ~617 +Orchard actions or ~2,090 Sapling outputs, with no per-pool limits. A fully +packed Orchard block requires verifying all action proofs and spend +authorization signatures for those ~617 actions. + +**Proposed worst case:** With the action limits, a block contains at +most 306 actions across pools. There is separately, limits per pool. We propose per-pool limits of: + +- 306 Orchard actions +- 300 Sapling inputs+outputs. +- 25 Sprout JoinSplits. + +This means the new worst case block processing time, if Orchard dominant, would be half of today's worst case, and Sapling's would be one sixth. The per-block verification work is therefore substantially reduced. + +**Batch verification.** Orchard transaction verification benefits from +batch validation, where proof and signature verification is amortized +across multiple transactions. In Zebra, Orchard +transactions are batch-verified in groups of up to 64 transactions +(each worst case being a single action). Zebra has performed batch +verification during live network syncing since version 3.0.0. With the +action limits, a worst-case block's Orchard bundle can be fully +batch-verified in a small number of batches. + +**Estimated timing.** In local benchmarks on a modern AMD laptop CPU +limited to 4 threads, availability verification for an Orchard-heavy +block at the action limits completed in 529.00--554.30 ms, and +availability verification for a Sapling-heavy block at the action +limits completed in 1.1017--1.1329 s. +When transactions have already been pre-verified upon +entering the mempool, which is the typical case for a node that has +been online, block validation reduces to checking signatures and +state updates, which is even cheaper. + + +# Specification + +The changes described in this section are to be made in the Zcash +Protocol Specification [^protocol], relative to the specification as of +the activation of this proposal. + +## Consensus changes + +### Block target spacing + +In § 2 'Notation', add $\mathsf{NU7ActivationHeight}$ +and $\mathsf{PostNU7PoWTargetSpacing}$ to the list of +integer constants. + +In § 5.3 'Constants', define: + +$$\mathsf{PostNU7PoWTargetSpacing} := 25 \text{ seconds}$$ + +For a given network (production or test), define +$\mathsf{NU7ActivationHeight}$ as the height at which +this network upgrade activates on that network, as specified in a +separate deployment ZIP. + +Define: + +$$\mathsf{NU7PoWTargetSpacingRatio} := \mathsf{PostBlossomPoWTargetSpacing} \;/\; \mathsf{PostNU7PoWTargetSpacing} = 3$$ + +Define $\mathsf{IsNU7Activated}(\mathsf{height})$ to +return true if +$\mathsf{height} \geq \mathsf{NU7ActivationHeight}$, +otherwise false. + +In § 7.7.3 'Difficulty adjustment', redefine $\mathsf{PoWTargetSpacing}$ +as: + +$$ +\mathsf{PoWTargetSpacing}(\mathsf{height}) := + \begin{cases} + \mathsf{PreBlossomPoWTargetSpacing}, &\text{if not } \mathsf{IsBlossomActivated}(\mathsf{height}) \\\\ + \mathsf{PostBlossomPoWTargetSpacing}, &\text{if } \mathsf{IsBlossomActivated}(\mathsf{height}) \text{ and not } \mathsf{IsNU7Activated}(\mathsf{height}) \\\\ + \mathsf{PostNU7PoWTargetSpacing} &\text{otherwise} + \end{cases} +$$ + +### Halving interval and block subsidy + +Define: + +$$\mathsf{PostNU7HalvingInterval} := \lfloor \mathsf{PostBlossomHalvingInterval} \cdot \mathsf{NU7PoWTargetSpacingRatio} \rfloor = 5{,}040{,}000$$ + +Redefine the $\mathsf{Halving}$ function as: + +$$ +\mathsf{Halving}(\mathsf{height}) := + \begin{cases} + \left\lfloor \dfrac{\mathsf{height} - \mathsf{SlowStartShift}}{\mathsf{PreBlossomHalvingInterval}} \right\rfloor, + &\text{if not } \mathsf{IsBlossomActivated}(\mathsf{height}) \\\\[1.5ex] + \left\lfloor \dfrac{\mathsf{BlossomActivationHeight} - \mathsf{SlowStartShift}}{\mathsf{PreBlossomHalvingInterval}} + + \dfrac{\mathsf{height} - \mathsf{BlossomActivationHeight}}{\mathsf{PostBlossomHalvingInterval}} \right\rfloor, + &\text{if } \mathsf{IsBlossomActivated}(\mathsf{height}) \text{ and not } \mathsf{IsNU7Activated}(\mathsf{height}) \\\\[1.5ex] + \left\lfloor \dfrac{\mathsf{BlossomActivationHeight} - \mathsf{SlowStartShift}}{\mathsf{PreBlossomHalvingInterval}} + + \dfrac{\mathsf{NU7ActivationHeight} - \mathsf{BlossomActivationHeight}}{\mathsf{PostBlossomHalvingInterval}} + + \dfrac{\mathsf{height} - \mathsf{NU7ActivationHeight}}{\mathsf{PostNU7HalvingInterval}} \right\rfloor, + &\text{otherwise} + \end{cases} +$$ + +Redefine $\mathsf{BlockSubsidy}$ to add a case for post-activation +heights. The prior Blossom case in § 7.8 'Calculation of Block Subsidy +and Founders' Reward', currently written as "otherwise", must be +amended to "if $\mathsf{IsBlossomActivated}(\mathsf{height})$ and not +$\mathsf{IsNU7Activated}(\mathsf{height})$": + +$$ +\mathsf{BlockSubsidy}(\mathsf{height}) := + \begin{cases} + \ldots &\text{(prior cases, with the Blossom case amended as above)} \\\\[1ex] + \mathsf{floor}\left(\dfrac{\mathsf{MaxBlockSubsidy}}{\mathsf{BlossomPoWTargetSpacingRatio} \cdot \mathsf{NU7PoWTargetSpacingRatio} \cdot 2^{\mathsf{Halving}(\mathsf{height})}}\right), + &\text{if } \mathsf{IsNU7Activated}(\mathsf{height}) + \end{cases} +$$ + +This divides the per-block subsidy by an additional factor of 3 relative +to the post-Blossom subsidy, so that the total issuance per unit of wall +clock time remains the same. + +Note: the current post-Blossom block subsidy of 1.5625 ZEC does not +divide evenly by 3. The post-NU7 subsidy is +$\mathsf{floor}(156250000 / 6) = 26041666$ zatoshi (0.26041666 ZEC), +losing approximately 0.33 zatoshi per block to rounding. Over a full +halving interval of 5,040,000 blocks this amounts to less than 0.017 ZEC +of total underpaid issuance, a negligible amount. Should ZIP 234 be accepted, +the difference will eventually be reissued. + +### Shielded pool action limits + +Define the following constants in § 5.3 'Constants': + +$$\mathsf{GlobalShieldedBudget} := 306$$ +$$\mathsf{OrchardBlockActionLimit} := 306$$ +$$\mathsf{SaplingBlockIOLimit} := 300$$ +$$\mathsf{SproutBlockJoinSplitLimit} := 25$$ + +For each block at height $\mathsf{height}$ where +$\mathsf{IsNU7Activated}(\mathsf{height})$, the following limits MUST +be satisfied: + +**Per-pool limits:** + +- The total number of Orchard actions across all transactions in the + block MUST NOT exceed $\mathsf{OrchardBlockActionLimit}$. That is, + $\sum_{\mathit{tx} \in \mathit{block}} \mathit{nActionsOrchard}(\mathit{tx}) \leq 306$. + +- The total number of Sapling inputs and outputs across all + transactions in the block MUST NOT exceed + $\mathsf{SaplingBlockIOLimit}$. That is, + $\sum_{\mathit{tx} \in \mathit{block}} (\mathit{nSpendsSapling}(\mathit{tx}) + \mathit{nOutputsSapling}(\mathit{tx})) \leq 300$. + +- The total number of Sprout JoinSplits across all transactions in + the block MUST NOT exceed $\mathsf{SproutBlockJoinSplitLimit}$. That + is, + $\sum_{\mathit{tx} \in \mathit{block}} \mathit{nJoinSplit}(\mathit{tx}) \leq 25$. + +**Global shielded budget:** + +In addition to the per-pool limits, the total shielded cost across all +pools in a block MUST NOT exceed $\mathsf{GlobalShieldedBudget}$. The +shielded cost of a block is defined as: + +$$\sum_{\mathit{tx}} \mathit{nActionsOrchard}(\mathit{tx}) \;+\; \sum_{\mathit{tx}} (\mathit{nSpendsSapling}(\mathit{tx}) + \mathit{nOutputsSapling}(\mathit{tx})) \;+\; 2 \times \sum_{\mathit{tx}} \mathit{nJoinSplit}(\mathit{tx}) \;\leq\; 306$$ + +where the factor of 2 for Sprout JoinSplits reflects that each +JoinSplit produces 2 shielded outputs. + +This global budget ensures that the worst-case shielded sync bandwidth +per block is bounded regardless of which combination of pools is used. + +These limits do not apply to the transparent components of +transactions. The overall 2 MB block size limit continues to apply as +before. + +#### Rationale: Compact sync bandwidth per action + +The limits above are chosen to bound the worst-case bandwidth that +lightweight wallets must download for shielded sync. The compact +representation used for syncing has the following per-note costs: + +**Orchard:** 148 bytes per action, consisting of: + +| Field | Size | +|-------|------| +| cmx (note commitment) | 32 bytes | +| nullifier | 32 bytes | +| ephemeral public key | 32 bytes | +| truncated note plaintext | 52 bytes | +| **Total** | **148 bytes** | + +**Sapling:** 32 bytes per spend (input) and 116 bytes per output, +consisting of: + +| Field | Size | +|-------|------| +| *Per spend:* nullifier | 32 bytes | +| *Per output:* cmu (note commitment) | 32 bytes | +| *Per output:* ephemeral public key | 32 bytes | +| *Per output:* truncated note plaintext | 52 bytes | +| **Per spend total** | **32 bytes** | +| **Per output total** | **116 bytes** | + +With these limits, the worst-case compact sync bandwidth per block is: + +- **Orchard:** $306 \times 148 = 45{,}288$ bytes +- **Sapling:** at most $300 \times 116 = 34{,}800$ bytes (all-output + pathological case) + +Due to the global shielded budget, these cannot stack: a block that +uses 306 Orchard actions has zero budget remaining for Sapling or +Sprout. The worst-case compact sync bandwidth per block is therefore +always bounded by the Orchard case at 45,288 bytes. + +See the [Rationale](#rationale) section for the full daily bandwidth +analysis. + +## Effect on difficulty adjustment + +As with the Blossom activation [^zip-0208], the difficulty adjustment +parameters $\mathsf{PoWAveragingWindow}$ and +$\mathsf{PoWMedianBlockSpan}$ refer to numbers of blocks and do *not* +change at activation. 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. + +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, the minimum-difficulty block threshold defined in ZIP 205 +[^zip-0205] and modified by ZIP 208 [^zip-0208] continues to use +$6 \cdot \mathsf{PoWTargetSpacing}(\mathsf{height})$ seconds. +After activation, this threshold becomes $6 \times 25 = 150$ seconds. + +## Non-consensus node behaviour + +### Default expiry delta + +When not overridden by the `-txexpirydelta` option, node +implementations that create transactions use a default expiry delta. +The current default of 40 blocks (approximately 50 minutes at 75-second +spacing) SHOULD change to +$\mathsf{NU7PoWTargetSpacingRatio} \times 40 = 120$ +blocks after activation, to maintain the approximate expiry time of +50 minutes. + +If the `-txexpirydelta` option is set, then the set value SHOULD be +used both before and after activation. + +### Block-count-based constants + +The following constants, measured in number of blocks, were reviewed. +Implementations SHOULD scale by $\mathsf{NU7PoWTargetSpacingRatio}$ +those constants that represent a time duration (marked "Scale by 3" +below), and SHOULD NOT scale those whose semantics are intrinsically +measured in blocks (marked "No change"): + +| Constant | Current | Post-activation | Notes | +|---------------------------------------------|---------|-----------------|-------| +| `COINBASE_MATURITY` | 100 | 100 | No change; security measured in blocks | +| `MAX_REORG_LENGTH` | 99 | 99 | No change; follows `COINBASE_MATURITY` | +| `TX_EXPIRING_SOON_THRESHOLD` | 3 | 3 | No change; | +| `MAX_BLOCKS_IN_TRANSIT_PER_PEER` | 16 | 48 | Scale by 3 | +| `BLOCK_DOWNLOAD_WINDOW` | 1024 | 3072 | Scale by 3 | +| `MIN_BLOCKS_TO_KEEP` | 288 | 864 | Scale by 3; keep 6 hours worth of blocks | +| `NETWORK_UPGRADE_PEER_PREFERENCE_BLOCK_PERIOD` | 1728 | 1728 | No change; | + +### Anchor selection depth + +ZIP 315 [^zip-0315], recommends selecting an anchor 3 blocks back from +the chain tip when constructing shielded transactions. The recommended +anchor depth SHOULD remain at 3 blocks after activation, reducing the average +wall-clock anchor delay from ~3.75 minutes to ~1.25 minutes. This +follows the same precedent set by the Blossom upgrade (ZIP 208 +[^zip-0208]), which did not update the anchor depth and therefore halved delay. + +| Parameter | Current | Post-activation | Notes | +|-----------|---------|-----------------|-------| +| Recommended anchor depth | 3 blocks (~3.75 min) | 3 blocks (~1.25 min) | No change; follows Blossom precedent | + +The increased likelihood of forking due to block time reduction should not be +concerning here. For an issue to occur when anchor depth is 3 blocks back, you +must have a 4 block re-org. In the many years of Ethereum PoW, a 4 block re-org +has never been observed [^lovejoy-reorg]. So we are not practically at risk of +inherent randomness causing a re-org. In other POW chains, re-orgs of 4+ +blocks resulted from a consensus split of some form, including the recent +Litecoin attack, or an attack from a surge in hashpower. +Anchor height depth is not intended to protect against those two vectors. + +# Rationale + +## Shielded sync bandwidth analysis + +The per-pool block space limits are chosen so that the worst-case daily +bandwidth for lightweight wallet syncing does not increase relative to +the current protocol. This section presents the analysis. + +### Parameters + +| Parameter | Value | +|-----------|-------| +| Block size limit | 2,000,000 bytes | +| Block target spacing | 25 seconds | +| Blocks per day | $ 86{,}400 / 25 = 3{,}456$ | +| Compact block header size | ~90 bytes | + +**Orchard pool:** + +| Parameter | Value | +|-----------|-------| +| $\mathsf{OrchardBlockActionLimit}$ | 306 actions | +| Compact sync bandwidth per action | 148 bytes | +| Compact bandwidth per block | $306 \times 148 = 45{,}288$ bytes | + +**Sapling pool:** + +| Parameter | Value | +|-----------|-------| +| $\mathsf{SaplingBlockIOLimit}$ | 300 (inputs + outputs) | +| Compact sync bandwidth per spend | 32 bytes | +| Compact sync bandwidth per output | 116 bytes | +| Compact bandwidth per block (worst case, all outputs) | $300 \times 116 = 34{,}800$ bytes | + +### Daily bandwidth comparison + +| Metric | Current (75s, no pool limits) | Proposed (25s, action limits) | +|--------|-------------------------------|-------------------------------| +| Blocks per day | 1,152 | 3,456 | +| Max Orchard actions/block | ~617 (block-size limited) | 306 | +| Max Sapling IOs/block | ~2,140 (block-size limited) | 300 | +| Orchard compact BW/day | ~105.2 MB | 156.52 MB | +| Sapling compact BW/day | ~270.38 MB | 120.27 MB | +| Compact block headers/day | ~0.10 MB | 0.31 MB | +| **Worst-case total BW/day** | **~270.5 MB** | **156.83 MB** | +| Worst-case trial decrypts/day | ~4.8M | ~2.1M | + +The worst-case compact sync bandwidth is **156.83 MB/day**, a reduction +of **42%** from today's worst case of approximately 270.5 MB/day. This +is despite a 3× increase in block frequency and overall throughput +capacity. + +The binding constraint is Orchard at 306 actions per block: +$306 \times 148 \times 3{,}456 + 90 \times 3{,}456 = 156.83\text{ MB/day}$. + +The trial decryption count also decreases significantly, since the +per-block action limits more than offset the 3× increase in block count. + +Note that the trial decrypt count is 2× the number of shielded +outputs/actions, because wallets must attempt decryption with both the +internal and external incoming viewing keys (IVKs). The internal IVK +detects change outputs sent back to the wallet, while the external IVK +detects incoming payments. In principle, wallets could avoid trial decrypts +with their IVK assuming other sync trade-offs are taken, but current Sapling and +Orchard wallets always attempt both. + +### Normal transaction throughput + +For standard 2-action Orchard transactions, the action limit of 306 +allows $\lfloor 306 / 2 \rfloor = 153$ transactions per block, giving: + +$$\mathsf{orchard\_tps} = 153 \;/\; 25 = 6.12 \text{ TPS}$$ + +For comparison, the current protocol (75s blocks, block-size limited) +supports approximately 2.9 TPS for 2-action Orchard transactions. This +is a **2.1× increase** in normal Orchard throughput. + +**Sapling throughput.** For standard Sapling transactions (2 spends + 2 +outputs = 4 IOs), the limit of 300 IOs allows $\lfloor 300 / 4 \rfloor += 75$ transactions per block, giving $75 / 25 = 3.0$ TPS. Even with +the reduced Sapling limit, the post-NU7 Sapling TPS (3.0) still +exceeds the current pre-NU7 Orchard TPS (2.9). + +### Fee incentives and DoS resistance + +A concern with per-pool limits is that a DoS attacker could fill +the Sapling or Sprout budget to crowd out Orchard transactions (or vice +versa). The global shielded budget prevents this from being worse than +filling any single pool, but it is worth examining whether fee +incentives create an asymmetry. + +Under ZIP 317 [^zip-0317], the conventional fee is based on *logical +actions*: each Sapling output or spend counts as one logical action, and +each Orchard action counts as one logical action. The marginal fee per +logical action is the same regardless of pool. Therefore, an attacker +gains no fee advantage by spamming Sapling instead of Orchard (or vice +versa). The cost per unit of shielded budget consumed is identical. + +Furthermore, because the global shielded budget is shared, filling +the Sapling budget necessarily reduces the Orchard budget by the same +amount. An attacker who spends their entire budget on Sapling spam at +300 IOs leaves only 6 Orchard actions available in that block. But +this attack is no cheaper than filling 306 Orchard actions directly, +since the per-action fee is the same. The global budget ensures that +the total shielded sync cost per block is bounded to 306 units +regardless of the attacker's pool choice. + +The Orchard per-pool cap of 306 also guarantees that legitimate Orchard +transactions always have access to the full Orchard budget when Sapling +and Sprout are not used, which is the expected common case going +forward. + + +# Deployment + +This proposal is intended to be deployed as part of NU7, should tokenholder polling and developer consensus agree on it. A separate ZIP will specify the deployment details including +activation heights and consensus branch IDs. + + +# 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"](https://www.rfc-editor.org/info/bcp14) + +[^protocol]: [Zcash Protocol Specification, Version 2025.6.3 or later](protocol/protocol.pdf) + +[^protocol-networks]: [Zcash Protocol Specification, Version 2025.6.3. Section 3.12: Mainnet and Testnet](protocol/protocol.pdf#networks) + +[^protocol-constants]: [Zcash Protocol Specification, Version 2025.6.3. Section 5.3: Constants](protocol/protocol.pdf#constants) + +[^protocol-diffadjustment]: [Zcash Protocol Specification, Version 2025.6.3. Section 7.7.3: Difficulty adjustment](protocol/protocol.pdf#diffadjustment) + +[^protocol-txnencoding]: [Zcash Protocol Specification, Version 2025.6.3. Section 7.1: Transaction Encoding and Consensus](protocol/protocol.pdf#txnencoding) + +[^zip-0200]: [ZIP 200: Network Upgrade Mechanism](zip-0200.rst) + +[^zip-0205]: [ZIP 205: Deployment of the Sapling Network Upgrade](zip-0205.rst) + +[^zip-0206]: [ZIP 206: Deployment of the Blossom Network Upgrade](zip-0206.rst) + +[^zip-0208]: [ZIP 208: Shorter Block Target Spacing](zip-0208.rst) + +[^zip-0315]: [ZIP 315: Best Practices for Wallet Implementations](zip-0315.rst) + +[^zip-0317]: [ZIP 317: Proportional Transfer Fee Mechanism](zip-0317.rst) + +[^crosslink]: [Crosslink — a Zcash Finality Protocol](https://electric-coin-company.github.io/zcash-crosslink/) + +[^slowfastblocks]: [On Slow and Fast Block Times](https://blog.ethereum.org/2015/09/14/on-slow-and-fast-block-times/) + +[^lovejoy-reorg]: [Lovejoy, James P. (2020). *An Empirical Analysis of Chain Reorganizations and Double-Spend Attacks on Proof-of-Work Cryptocurrencies.* M.Eng. thesis, Massachusetts Institute of Technology, Department of Electrical Engineering and Computer Science.](https://static1.squarespace.com/static/6675a0d5fc9e317c60db9b37/t/66eb3560532516773c4f7ece/1726690657755/LovejoyJamesP-meng-eecs-2020+%281%29.pdf) + +[^forum-proposal]: [Forum: Proposal — Lower Zcash Block Target Spacing to 25s](https://forum.zcashcommunity.com/t/proposal-lower-zcash-block-target-spacing-to-25s/54577) + +[^devnet-blocktime-test]: [Forum: Zcash Block Time Reduction Appears Safe for NU7 w/ Zebra-only Devnet](https://forum.zcashcommunity.com/t/zcash-block-time-reduction-appears-safe-for-nu7-w-zebra-only-devnet/55586) diff --git a/zips/zip-0219.rst b/zips/zip-0219.rst index 313032e95..931e90639 100644 --- a/zips/zip-0219.rst +++ b/zips/zip-0219.rst @@ -2,7 +2,7 @@ ZIP: 219 Title: Disabling Addition of New Value to the Sapling Chain Value Pool - Owners: Daira-Emma Hopwood + Owners: Daira-Emma Hopwood Status: Reserved Category: Consensus Discussions-To: diff --git a/zips/zip-0220.rst b/zips/zip-0220.rst index 5b9b8ee00..5ea14b140 100644 --- a/zips/zip-0220.rst +++ b/zips/zip-0220.rst @@ -2,8 +2,8 @@ ZIP: 220 Title: Zcash Shielded Assets - Owners: Jack Grigg - Daira-Emma Hopwood + Owners: Jack Grigg + Daira-Emma Hopwood Status: Withdrawn Category: Consensus Discussions-To: diff --git a/zips/zip-0221.rst b/zips/zip-0221.rst index 74b42e15e..4ee35acce 100644 --- a/zips/zip-0221.rst +++ b/zips/zip-0221.rst @@ -2,7 +2,7 @@ ZIP: 221 Title: FlyClient - Consensus-Layer Changes - Owners: Jack Grigg + Owners: Jack Grigg Original-Authors: Ying Tong Lai James Prestwich Georgios Konstantopoulos @@ -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-0222.rst b/zips/zip-0222.rst index 440ec86e0..b206f230c 100644 --- a/zips/zip-0222.rst +++ b/zips/zip-0222.rst @@ -2,8 +2,8 @@ ZIP: 222 Title: Transparent Zcash Extensions - Owners: Jack Grigg - Kris Nuttycombe + Owners: Jack Grigg + Kris Nuttycombe Credits: Zaki Manian Daira-Emma Hopwood Sean Bowe @@ -11,6 +11,7 @@ Category: Consensus Created: 2019-07-01 License: MIT + Discussions-To: Terminology diff --git a/zips/zip-0224.rst b/zips/zip-0224.rst index b3b75fa32..cbede7687 100644 --- a/zips/zip-0224.rst +++ b/zips/zip-0224.rst @@ -2,10 +2,10 @@ ZIP: 224 Title: Orchard Shielded Protocol - Owners: Daira-Emma Hopwood - Jack Grigg - Sean Bowe - Kris Nuttycombe + Owners: Daira-Emma Hopwood + Jack Grigg + Sean Bowe + Kris Nuttycombe Original-Authors: Ying Tong Lai Status: Final Category: Consensus @@ -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..e6b4cfb2a 100644 --- a/zips/zip-0225.rst +++ b/zips/zip-0225.rst @@ -2,10 +2,10 @@ ZIP: 225 Title: Version 5 Transaction Format - Owners: Daira-Emma Hopwood - Jack Grigg - Sean Bowe - Kris Nuttycombe + Owners: Daira-Emma Hopwood + Jack Grigg + Sean Bowe + Kris Nuttycombe Original-Authors: Ying Tong Lai Status: Final Category: Consensus @@ -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 descriptions 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 cb939efc8..4c35334a8 100644 --- a/zips/zip-0226.rst +++ b/zips/zip-0226.rst @@ -4,8 +4,8 @@ Title: Transfer and Burn of Zcash Shielded Assets Owners: Pablo Kogan Vivek Arte - Daira-Emma Hopwood - Jack Grigg + Daira-Emma Hopwood + Jack Grigg Credits: Daniel Benarroch Aurelien Nicolas Deirdre Connolly @@ -23,22 +23,26 @@ 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 term "network upgrade" in this document is to be interpreted as described in ZIP 200 [#zip-0200]_. +The term "network upgrade" in this document is to be interpreted as described in ZIP 200. [#zip-0200]_ -The terms "Orchard" and "Action" in this document are to be interpreted as described in ZIP 224 [#zip-0224]_. +The character § is used when referring to sections of the Zcash Protocol Specification. [#protocol]_ -The terms "Asset", "Custom Asset" and "Wrapped Asset" in this document are to be interpreted as described in ZIP 227 [#zip-0227]_. +The terms "Orchard" and "Action" in this document are to be interpreted as described in ZIP 224. [#zip-0224]_ + +The terms "Asset" and "Custom Asset" in this document are to be interpreted as described in ZIP 227. [#zip-0227]_ 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 ======== -This ZIP (ZIP 226) proposes the Zcash Shielded Assets (ZSA) protocol, in conjunction with ZIP 227 [#zip-0227]_. The ZSA protocol is an extension of the Orchard protocol that enables the issuance, transfer and burn of custom Assets on the Zcash chain. The issuance of such Assets is defined in ZIP 227 [#zip-0227]_, while the transfer and burn of such Assets is defined in this ZIP (ZIP 226). -While the proposed ZSA protocol is a modification to the Orchard protocol, it has been designed with adaptation to possible future shielded protocols in mind. +This ZIP (ZIP 226) proposes the Orchard Zcash Shielded Assets (OrchardZSA) protocol, in conjunction with ZIP 227 [#zip-0227]_. The OrchardZSA protocol is an extension of the Orchard protocol that enables the issuance, transfer and burn of custom Assets on the Zcash chain. The issuance of such Assets is defined in ZIP 227 [#zip-0227]_, while the transfer and burn of such Assets is defined in this ZIP (ZIP 226). +While the proposed OrchardZSA protocol is a modification to the Orchard protocol, it has been designed with adaptation to possible future shielded protocols in mind. + +This ZIP is defined relative to the Zcash protocol with the changes specified in ZIP 2005 [#zip-2005]_ applied. ZIP 2005 (Orchard Quantum Recoverability) is expected to deploy before any ZSA activation; the references in this document to $\mathsf{H^{rcm,Orchard}}$, $\mathsf{H^{\text{ψ},Orchard}}$, recoverable note plaintexts, and related constructs are to be interpreted as defined by ZIP 2005's modifications to the protocol specification. Motivation ========== @@ -48,21 +52,38 @@ 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 Orchard-based ZSA 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. When this flag is set to false, it is not possible to perform transactions involving Custom Assets (the Action statement as modified for ZSAs will not be satisfied). +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 $\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, and removing supply of Assets. + +Privacy Implications +==================== + +- After the protocol upgrade, the Orchard shielded pool will be shared by the + Orchard protocol and the OrchardZSA protocol. +- Deploying the OrchardZSA protocol does not necessitate disabling the Orchard + protocol. Both can co-exist and be addressed via different transaction + versions (V5 for Orchard and V6 for OrchardZSA). Due to this, Orchard note + commitments can be distinguished from OrchardZSA note commitments. This holds + whether or not the two protocols are active simultaneously. +- OrchardZSA note commitments for the native asset (ZEC) are indistinguishable + from OrchardZSA note commitments for non-native Assets. +- When including new Assets we would like to maintain the amount and identifiers + of Assets private, which is achieved with the design. Specification ============= @@ -72,140 +93,168 @@ 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 ``````````````````````````````` In future network and protocol upgrades, the same Asset description string can be carried on, potentially mapping into a different shielded pool. In that case, nodes should know how to transform the Asset Identifier, the Asset Digest, and the Asset Base from one shielded pool to another, while ensuring there are no balance violations [#zip-0209]_. -Note Structure & Commitment ---------------------------- +We prevent a potential malleability attack on the Asset Identifier by ensuring +the output notes receive an Asset Base that exists on the global state. -Let :math:`\mathsf{Note^{OrchardZSA}}` be the type of a ZSA note, i.e. -:math:`\mathsf{Note^{OrchardZSA}} := \mathsf{Note^{Orchard}} \times \mathbb{P}^*\!`. +Note Structure and Commitment +----------------------------- -An Orchard ZSA note differs from an Orchard note [#protocol-notes]_ by additionally including the Asset Base, :math:`\mathsf{AssetBase}\!`. So a ZSA note is a tuple :math:`(\mathsf{g_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}, \mathsf{AssetBase}, \text{ρ}, \text{ψ}, \mathsf{rcm})$, 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-assetidentifier]_, 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}^{\mathbb{Y}^{[\ell_{\mathbb{P}}/8]}} := \mathsf{LEBS2OSP}_{\ell_{\mathbb{P}}}(\mathsf{repr}_{\mathbb{P}}(\mathsf{AssetBase}))$. +- The remaining terms are as defined in §3.2 ‘Notes’ [#protocol-notes]_. 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: +Let $\mathsf{Note^{OrchardZSA}}$ be the type of a OrchardZSA note, i.e. + +.. math:: \mathsf{Note^{OrchardZSA}} := \mathbb{B}^{[\ell_{\mathsf{d}}]} \times \mathsf{KA}^{\mathsf{Orchard}}.\mathsf{Public} \times \{0 .. 2^{\ell_{\mathsf{value}}} - 1\} \times \mathbb{P}^* \times \mathbb{F}_{q_{\mathbb{P}}} \times \mathbb{F}_{q_{\mathbb{P}}} \times \mathsf{NoteCommit^{Orchard}.Trapdoor}, + +where $\mathbb{P}^*$ is the Pallas group excluding the identity element, and the other types are as defined in §3.2 ‘Notes’ [#protocol-notes]_. -.. 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} +**Non-normative note:** +The type and definition of the OrchardZSA note reflect that it is a tuple of all the components of an Orchard note, with the addition of the Asset Base into the tuple. -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]_. -This note commitment scheme is instantiated using the Sinsemilla Commitment [#protocol-concretesinsemillacommit]_ as follows: +We define the note commitment scheme $\mathsf{NoteCommit^{OrchardZSA}_{rcm}}$ 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} +* $\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 [#protocol-pallasandvesta]_, and where $\mathsf{NoteCommit^{Orchard}.\{Trapdoor, Output\}}$ are as defined in §4.1.8 ‘Commitment’ [#protocol-abstractcommit]_. +This uses the note commitment scheme defined in §5.4.8.4 ‘Sinsemilla Commitments’ [#protocol-concretesinsemillacommit]_ as follows: + +.. 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 $\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 ‘Constants’ [#protocol-constants]_, and $\mathsf{I2LEBSP}$ is as defined in §5.1 ‘Integers, Bit Sequences, and Endianness’ [#protocol-endian]_. -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. +The nullifier is generated in the same manner as in the Orchard protocol §4.16 ‘Computing ρ values and Nullifiers’ [#protocol-rhoandnullifiers]_. -The nullifier is generated in the same manner as in the Orchard protocol [#protocol-commitmentsandnullifiers]_. +The OrchardZSA note plaintext also includes the Asset Base $\mathsf{asset\_base} : \mathbb{B}^{[\ell_{\mathbb{P}}]}$ in addition to the components in the Orchard note plaintext [#protocol-notept]_. +The explicit encoding of the note plaintext is provided in ZIP 230 [#zip-0230-orchard-note-plaintext]_. -The ZSA note plaintext also includes the Asset Base in addition to the components in the Orchard note plaintext [#protocol-notept]_. -It consists of +When § 4.7.3 'Sending Notes (Orchard)' [#protocol-orchardsend]_ or § 4.8.3 'Dummy Notes (Orchard)' [#protocol-orcharddummynotes]_ are invoked directly or indirectly in the computation of $\text{ρ}$ and $\text{ψ}$ for an OrchardZSA note, $\mathsf{leadByte}$ MUST be set to {{ZSALEADBYTE}}. -.. math:: (\mathsf{leadByte} : \mathbb{B}^{\mathbb{Y}}, \mathsf{d} : \mathbb{B}^{[\ell_{\mathsf{d}}]}, \mathsf{v} : \{0 .. 2^{\ell_{\mathsf{value}}} - 1\}, \mathsf{rseed} : \mathbb{B}^{\mathbb{Y}[32]}, \mathsf{asset\_base} : \mathbb{B}^{[\ell_{\mathbb{P}}]}, \mathsf{memo} : \mathbb{B}^{\mathbb{Y}[512]}) +The explicit order of addition of the note commitments to the note commitment tree is specified in ZIP 227 [#zip-0227-note-commitment-order]_. Rationale for Note Commitment ````````````````````````````` -In the ZSA 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]_. ZSA note commitments will therefore be added to the same Orchard Note Commitment Tree. In essence, we have: +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 ZSA notes. +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. Value Commitment ---------------- -In the case of the Orchard-based ZSA protocol, the value of different Asset Identifiers in a given transaction will be committed using a **different value base point**. The value commitment becomes: +In the case of the OrchardZSA protocol, the value of different Asset Identifiers in a given transaction will be committed using a **different value base point**. The value commitment becomes: .. 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. Burn Mechanism -------------- -The burn mechanism is a transparent extension to the transfer protocol that enables a specific amount of any Asset Identifier to be "destroyed". The burn mechanism does NOT send Assets to a non-spendable address, it simply reduces the total number of units of a given Custom Asset in circulation at the consensus level. It is enforced at the consensus level, by using an extension of the value balance mechanism used for ZEC Assets. -Burning makes it globally provable that a given amount of an Asset has been destroyed. +The burn mechanism is a transparent extension to the transfer protocol that enables a specific amount of any Custom Asset to be "destroyed" by the holder. +The burn mechanism does NOT send Assets to a non-spendable address, it simply reduces the total number of units of a given Custom Asset in circulation. +It is enforced at the consensus level, by using an extension of the value balance mechanism used for ZEC Assets. +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 $\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 define a constant $\mathsf{MAX\_BURN\_VALUE} := 2^{63} - 1$, which denotes the maximum amount of a given Custom Asset that can be burnt in a transaction. +We denote by $L$ the cardinality of the $\mathsf{assetBurn}$ set in a transaction. -The sender includes a :math:`\mathsf{v_{AssetId}}` variable for every Asset Identifier that is being burnt, which represents the amount of that Asset being burnt. As described in the `Orchard-ZSA Transaction Structure`_, this is separate from the regular :math:`\mathsf{valueBalance^{Orchard}}` that is the default transparent value for the ZEC Asset, and represents either the transaction fee, or the amount of ZEC changing pools (e.g. to Sapling or Transparent). +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. -For every Custom Asset that is burnt, we add to the :math:`\mathsf{assetBurn}` set the tuple :math:`(\mathsf{AssetBase_{AssetId}}, \mathsf{v_{AssetId}})` such that the validator of the transaction can compute the value commitment with the corresponding value base point of that Asset. This ensures that the values are all balanced out with respect to the Asset Identifiers in the transfer. +Additional Consensus Rules for the assetBurn set +```````````````````````````````````````````````` -.. math:: \mathsf{assetBurn} := \{ (\mathsf{AssetBase}_{\mathsf{AssetId}} : \mathbb{P}^*, \mathsf{v_{AssetId}} : \{1 .. 2^{\ell_{\mathsf{value}}} - 1\}) \,|\, \mathsf{AssetId} \in \mathsf{AssetIdsToBurn} \} +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} > 0$ and $\mathsf{v} \leq \mathsf{MAX\_BURN\_VALUE}$. +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}$. -We denote by :math:`L` the cardinality of the :math:`\mathsf{assetBurn}` set. +The other consensus rule changes for the OrchardZSA protocol are specified in ZIP 227 [#zip-0227-consensus]_. -Additional Consensus Rules -`````````````````````````` +**Note:** The transparent protocol will not be changed with this ZIP to adapt to a multiple Asset structure. +This means that unless future consensus rules changes do allow it, unshielding will not be possible for Custom Assets. -1. We require that for every :math:`(\mathsf{AssetBase_{AssetId}}, \mathsf{v_{AssetId}}) \in \mathsf{assetBurn}, \mathsf{AssetBase_{AssetId}} \neq \mathcal{V}^{\mathsf{Orchard}}\!`. That is, ZEC or TAZ is not allowed to be burnt by this mechanism. -2. We require that for every :math:`(\mathsf{AssetBase_{AssetId}}, \mathsf{v_{AssetId}}) \in \mathsf{assetBurn}, \mathsf{v_{AssetId}} \neq 0\!`. -3. We require that there be no duplication of Custom Assets in the :math:`\mathsf{assetBurn}` set. That is, every :math:`\mathsf{AssetBase_{AssetId}}` has at most one entry in :math:`\mathsf{assetBurn}\!`. +Rationale for MAX_BURN_VALUE +```````````````````````````` -**Note:** Even if this mechanism allows having transparent ↔ shielded Asset transfers in theory, the transparent protocol will not be changed with this ZIP to adapt to a multiple Asset structure. This means that unless future consensus rules changes do allow it, unshielding will not be possible for Custom Assets. +The maximum amount of any Custom Asset allowed to be burnt in a transaction is set to $\mathsf{MAX\_BURN\_VALUE}$ in order to prevent it from being incompatible with other valueBalance fields, which are signed 64-bit integers. +It will also allow for compatibility with future Custom-asset-specific value balances in subsequent pools that support transferring ZSAs from the Orchard pool via a turnstile. 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: @@ -214,13 +263,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 @@ -228,7 +277,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. @@ -243,55 +292,54 @@ Wallets and other clients have to choose from the following to ensure the Asset 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{ψ}') \bmod q_{\mathbb{P}}]\,\mathcal{K}^\mathsf{Orchard} + \mathsf{cm^{old}} + \mathcal{L}^\mathsf{Orchard}) +.. 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{ψ}'` 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 computed as $\mathsf{ToBase^{Orchard}}\big(\mathsf{PRF^{expand}_{rseed\_nf}}([\mathtt{0x0A}] \,||\, \underline{\text{ρ}^{\mathsf{old}}})\kern-0.1em\big)$ for $\mathsf{rseed\_nf}$ sampled uniformly at random on $\mathbb{B}^{{\kern-0.1em\tiny\mathbb{Y}}[32]}$, $\mathcal{K}^{\mathsf{Orchard}}$ is the Orchard Nullifier Base as defined in §4.16 ‘Computing ρ values and Nullifiers’ [#protocol-rhoandnullifiers]_, and $\mathcal{L}^{\mathsf{Orchard}} := \mathsf{GroupHash^{\mathbb{P}}}(\texttt{“z.cash:Orchard”}, \texttt{“L”})$. The first-byte domain separator $\mathtt{0x0A}$ for $\mathsf{PRF^{expand}}$ is reserved by ZIP 2005 [#zip-2005]_ for this use. 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* [#protocol-orcharddummynotes]_ to the Actions that have not been assigned input notes. -The Orchard technique requires modification for the ZSA 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. +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 ZSA 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. - Circuit Statement ----------------- -Every *ZSA Action statement* is closely similar to the Orchard Action statement [#protocol-actionstatement]_, except for a few additions that ensure the security of the Asset Identifier system. We detail these changes below. +Every *OrchardZSA Action statement* is closely similar to the Orchard Action statement [#protocol-actionstatement]_, except for a few additions that ensure the security of the Asset Identifier system. We detail these changes below. 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}$, 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})$. +- 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})$. -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}$. Asset Identifier Consistency for Split Actions `````````````````````````````````````````````` @@ -299,143 +347,83 @@ 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. -- 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}\!`. -- The Nullifier Integrity will be changed to prevent the identification of notes as defined in the `Split Notes`_ section. - -Backwards Compatibility with ZEC Notes -`````````````````````````````````````` -The input note in the old note commitment integrity check must either include an Asset Base (ZSA note) or not (pre-ZSA Orchard note). If the note is a pre-ZSA Orchard note, the note commitment is computed in the original Orchard fashion [#protocol-abstractcommit]_. If the note is a ZSA note, the note commitment is computed as defined in the `Note Structure & Commitment`_ section. + - Replace the input note value by a generic value, $\mathsf{v}'$, as $\mathsf{cv^{net}} = \mathsf{ValueCommit_rcv^{OrchardZSA}}(\mathsf{AssetBase}, \mathsf{v}' - \mathsf{v^{new}})$ -Orchard-ZSA Transaction Structure -================================= +- 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: -The transaction format for v6 transactions is described in ZIP 230 [#zip-0230]_. - - -TxId Digest -=========== - -The transaction digest algorithm defined in ZIP 244 [#zip-0244]_ is modified by the ZSA protocol to add a new branch for issuance information, along with modifications within the ``orchard_digest`` to account for the inclusion of the Asset Base. -The details of these changes are described in this section, and highlighted using the ``[UPDATED FOR ZSA]`` or ``[ADDED FOR ZSA]`` text label. We omit the details of the sections that do not change for the ZSA protocol. + - 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. -txid_digest ------------ -A BLAKE2b-256 hash of the following values :: - - T.1: header_digest (32-byte hash output) - T.2: transparent_digest (32-byte hash output) - T.3: sapling_digest (32-byte hash output) - T.4: orchard_digest (32-byte hash output) [UPDATED FOR ZSA] - T.5: issuance_digest (32-byte hash output) [ADDED FOR ZSA] - -The personalization field remains the same as in ZIP 244 [#zip-0244]_. - -T.4: orchard_digest -``````````````````` -When Orchard Actions are present in the transaction, this digest is a BLAKE2b-256 hash of the following values :: - - T.4a: orchard_actions_compact_digest (32-byte hash output) [UPDATED FOR ZSA] - T.4b: orchard_actions_memos_digest (32-byte hash output) [UPDATED FOR ZSA] - T.4c: orchard_actions_noncompact_digest (32-byte hash output) [UPDATED FOR ZSA] - T.4d: flagsOrchard (1 byte) - T.4e: valueBalanceOrchard (64-bit signed little-endian) - T.4f: anchorOrchard (32 bytes) - -T.4a: orchard_actions_compact_digest -'''''''''''''''''''''''''''''''''''' - -A BLAKE2b-256 hash of the subset of Orchard Action information intended to be included in -an updated version of the ZIP-307 [#zip-0307]_ ``CompactBlock`` format for all Orchard -Actions belonging to the transaction. For each Action, the following elements are included -in the hash:: - - T.4a.i : nullifier (field encoding bytes) - T.4a.ii : cmx (field encoding bytes) - T.4a.iii: ephemeralKey (field encoding bytes) - T.4a.iv : encCiphertext[..84] (First 84 bytes of field encoding) [UPDATED FOR ZSA] - -The personalization field of this hash is the same as in ZIP 244:: - - "ZTxIdOrcActCHash" - - -T.4b: orchard_actions_memos_digest -'''''''''''''''''''''''''''''''''' - -A BLAKE2b-256 hash of the subset of Orchard shielded memo field data for all Orchard -Actions belonging to the transaction. For each Action, the following elements are included -in the hash:: - - T.4b.i: encCiphertext[84..596] (contents of the encrypted memo field) [UPDATED FOR ZSA] - -The personalization field of this hash remains identical to ZIP 244:: +- The Merkle Path Validity should check the existence of the note commitment as usual (and not like with dummy notes): - "ZTxIdOrcActMHash" + - 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. -T.4c: orchard_actions_noncompact_digest -''''''''''''''''''''''''''''''''''''''' +Backwards Compatibility with ZEC Notes +`````````````````````````````````````` -A BLAKE2b-256 hash of the remaining subset of Orchard Action information **not** intended -for inclusion in an updated version of the the ZIP 307 [#zip-0307]_ ``CompactBlock`` -format, for all Orchard Actions belonging to the transaction. For each Action, -the following elements are included in the hash:: +The input note in the old note commitment integrity check must either include an Asset Base (OrchardZSA note) or not (pre-ZSA Orchard note). If the note is a pre-ZSA Orchard note, the note commitment is computed in the original Orchard fashion [#protocol-abstractcommit]_. If the note is an OrchardZSA note, the note commitment is computed as defined in the `Note Structure and Commitment`_ section. - T.4d.i : cv (field encoding bytes) - T.4d.ii : rk (field encoding bytes) - T.4d.iii: encCiphertext[596..] (post-memo suffix of field encoding) [UPDATED FOR ZSA] - T.4d.iv : outCiphertext (field encoding bytes) +OrchardZSA Transaction Structure +-------------------------------- -The personalization field of this hash is defined identically to ZIP 244:: +The transaction format for v6 transactions is described in ZIP 230 [#zip-0230]_. +The ZSA-related changes in v6 include: - "ZTxIdOrcActNHash" +* updates to the transaction structure [#zip-0230-transaction-format]_ and the + sighash digest computation [#zip-0246]_; +* new note plaintext formats for both Sapling and Orchard outputs [#zip-0230-note-plaintexts]_, + with corresponding changes to the note decryption algorithms for incoming and + outgoing viewing keys [#zip-2005]_. -T.5: issuance_digest -```````````````````` -The details of the computation of this value are in ZIP 227 [#zip-0227-txiddigest]_. +Implications for Wallets +```````````````````````` -Signature Digest and Authorizing Data Commitment -================================================ +The following requirements on wallets are specified and motivated in ZIP 230 +[#zip-0230-implications-for-wallets]_: -The details of the changes to these algorithms are in ZIP 227 [#zip-0227-sigdigest]_ [#zip-0227-authcommitment]_. +* *All* wallets should switch to sending only v6 transactions once NU7 has activated. + The main consequence of not doing so relevant to ZSAs, is that users would not obtain + the privacy benefit of indistinguishability between native and non-native assets in + the Orchard shielded pool, because v5 transactions can only transact in the native + ZEC asset. For other consequences see ZIP 230. -Security and Privacy Considerations -=================================== +* *All* wallets should be ready to receive funds in outputs of v6 transactions as soon + as ZSAs activate. The consequence of not doing so would be that funds sent to Orchard + addresses of a wallet without this support could be temporarily inaccessible, until + the wallet is upgraded to fully support v6 and to rescan outputs since v6 activation. -- After the protocol upgrade, the Orchard shielded pool will be shared by the Orchard protocol and the Orchard-ZSA protocol. -- Deploying the Orchard-ZSA protocol does not necessitate disabling the Orchard protocol. Both can co-exist and be addressed via different transaction versions (V5 for Orchard and V6 for Orchard-ZSA). Due to this, Orchard note commitments can be distinguished from Orchard-ZSA note commitments. This holds whether or not the two protocols are active simultaneously. -- Orchard-ZSA note commitments for the native asset (ZEC) are indistinguishable from Orchard-ZSA note commitments for non-native Assets. -- When including new Assets we would like to maintain the amount and identifiers of Assets private, which is achieved with the design. -- We prevent a potential malleability attack on the Asset Identifier by ensuring the output notes receive an Asset Base that exists on the global state. +Sighash modifications relative to ZIP 244 [#zip-0244]_ +------------------------------------------------------ -Other Considerations -==================== +Relative to the sighash algorithm defined in ZIP 244 [#zip-0244]_, the sighash algorithm +that applies to v6 transactions differs by altering the Orchard bundle within +the tree hash to match the corresponding OrchardZSA changes. See ZIP 246 [#zip-0246]_ +for details. Transaction Fees ---------------- -The fee mechanism for the upgrades proposed in this ZIP will follow the mechanism described in ZIP 317 for the ZSA protocol upgrade [#zip-0317b]_. +The fee mechanism for the upgrades proposed in this ZIP will follow the mechanism described in ZIP 317 for the OrchardZSA protocol upgrade, and are described in ZIP 227 [#zip-0227-orchardzsa-fee-calculation]_. Backward Compatibility ---------------------- -In order to have backward compatibility with the ZEC notes, we have designed the circuit to support both ZEC and ZSA notes. As we specify above, there are three main reasons we can do this: +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. -- The existing Orchard shielded pool will continue to be used for the new ZSA notes post the upgrade. +- 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 ZSA-based Actions will include split input notes and will not include dummy input notes. +- 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. Deployment ------------ -The Zcash Shielded Assets protocol will be deployed in a subsequent Network Upgrade. +========== + +The Zcash Shielded Assets protocol is scheduled to be deployed in Network Upgrade 7 (NU7). +This ZIP currently assumes that this will be the case. Test Vectors ============ @@ -454,33 +442,43 @@ 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" `_ -.. [#zip-0200] `ZIP 200: Network Upgrade Mechanism `_ -.. [#zip-0209] `ZIP 209: Prohibit Negative Shielded Chain Value Pool Balances `_ -.. [#zip-0224] `ZIP 224: Orchard `_ -.. [#zip-0227] `ZIP 227: Issuance of Zcash Shielded Assets `_ -.. [#zip-0227-assetidentifier] `ZIP 227: Issuance of Zcash Shielded Assets: Specification: Asset Identifier `_ -.. [#zip-0227-txiddigest] `ZIP 227: Issuance of Zcash Shielded Assets: TxId Digest - Issuance `_ -.. [#zip-0227-sigdigest] `ZIP 227: Issuance of Zcash Shielded Assets: Signature Digest `_ -.. [#zip-0227-authcommitment] `ZIP 227: Issuance of Zcash Shielded Assets: Authorizing Data Commitment `_ -.. [#zip-0230] `ZIP 230: Version 6 Transaction Format `_ -.. [#zip-0244] `ZIP 244: Transaction Identifier Non-Malleability `_ +.. [#zip-0200] `ZIP 200: Network Upgrade Mechanism `_ +.. [#zip-0209] `ZIP 209: Prohibit Negative Shielded Chain Value Pool Balances `_ +.. [#zip-0224] `ZIP 224: Orchard `_ +.. [#zip-0227] `ZIP 227: Issuance of Zcash Shielded Assets `_ +.. [#zip-0227-specification-global-issuance-state] `ZIP 227: Issuance of Zcash Shielded Assets — Specification: Global Issuance State `_ +.. [#zip-0227-assetidentifier] `ZIP 227: Issuance of Zcash Shielded Assets — Specification: Asset Identifier `_ +.. [#zip-0227-consensus] `ZIP 227: Issuance of Zcash Shielded Assets — Specification: Consensus Rule Changes `_ +.. [#zip-0227-note-commitment-order] `ZIP 227: Issuance of Zcash Shielded Assets — Addition to the Note Commitment Tree `_ +.. [#zip-0227-txiddigest] `ZIP 227: Issuance of Zcash Shielded Assets — TxId Digest - Issuance `_ +.. [#zip-0227-authcommitment] `ZIP 227: Issuance of Zcash Shielded Assets — Authorizing Data Commitment `_ +.. [#zip-0227-orchardzsa-fee-calculation] `ZIP 227: Issuance of Zcash Shielded Assets — OrchardZSA Fee Calculation `_ +.. [#zip-0230] `ZIP 230: Version 6 Transaction Format `_ +.. [#zip-0230-transaction-format] `ZIP 230: Version 6 Transaction Format — Transaction Format `_ +.. [#zip-0230-note-plaintexts] `ZIP 230: Version 6 Transaction Format — Note Plaintexts `_ +.. [#zip-0230-orchard-note-plaintext] `ZIP 230: Version 6 Transaction Format — Orchard Note Plaintext `_ +.. [#zip-0230-implications-for-wallets] `ZIP 230: Version 6 Transaction Format — Implications for Wallets `_ +.. [#zip-0244] `ZIP 244: Transaction Identifier Non-Malleability `_ +.. [#zip-0246] `ZIP 246: Digests for the Version 6 Transaction Format `_ .. [#zip-0307] `ZIP 307: Light Client Protocol for Payment Detection `_ -.. [#zip-0317b] `ZIP 317: Proportional Transfer Fee Mechanism - Pull Request #667 for ZSA Protocol ZIPs `_ -.. [#protocol-notes] `Zcash Protocol Specification, Version 2023.4.0. Section 3.2: Notes `_ -.. [#protocol-actions] `Zcash Protocol Specification, Version 2023.4.0. Section 3.7: Action Transfers and their Descriptions `_ -.. [#protocol-abstractcommit] `Zcash Protocol Specification, Version 2023.4.0. Section 4.1.8: Commitment `_ -.. [#protocol-orcharddummynotes] `Zcash Protocol Specification, Version 2023.4.0. Section 4.8.3: Dummy Notes (Orchard) `_ -.. [#protocol-orchardbalance] `Zcash Protocol Specification, Version 2023.4.0. Section 4.14: Balance and Binding Signature (Orchard) `_ -.. [#protocol-commitmentsandnullifiers] `Zcash Protocol Specification, Version 2023.4.0. Section 4.16: Note Commitments and Nullifiers `_ -.. [#protocol-actionstatement] `Zcash Protocol Specification, Version 2023.4.0. Section 4.17.4: Action Statement (Orchard) `_ -.. [#protocol-endian] `Zcash Protocol Specification, Version 2023.4.0. Section 5.1: Integers, Bit Sequences, and Endianness `_ -.. [#protocol-constants] `Zcash Protocol Specification, Version 2023.4.0. Section 5.3: Constants `_ -.. [#protocol-concretesinsemillahash] `Zcash Protocol Specification, Version 2023.4.0. Section 5.4.1.9: Sinsemilla hash function `_ -.. [#protocol-concretehomomorphiccommit] `Zcash Protocol Specification, Version 2023.4.0. Section 5.4.8.3: Homomorphic Pedersen commitments (Sapling and Orchard) `_ -.. [#protocol-concretesinsemillacommit] `Zcash Protocol Specification, Version 2023.4.0. Section 5.4.8.4: Sinsemilla commitments `_ -.. [#protocol-pallasandvesta] `Zcash Protocol Specification, Version 2023.4.0. Section 5.4.9.6: Pallas and Vesta `_ -.. [#protocol-notept] `Zcash Protocol Specification, Version 2023.4.0. Section 5.5: Encodings of Note Plaintexts and Memo Fields `_ -.. [#protocol-actionencodingandconsensus] `Zcash Protocol Specification, Version 2023.4.0. Section 7.5: Action Description Encoding and Consensus `_ +.. [#zip-2005] `ZIP 2005: Orchard Quantum Recoverability `_ +.. [#protocol] `Zcash Protocol Specification, Version 2025.6.2 [NU6.1] or later. `_ +.. [#protocol-notes] `Zcash Protocol Specification, Version 2025.6.2 [NU6.1]. Section 3.2: Notes `_ +.. [#protocol-actions] `Zcash Protocol Specification, Version 2025.6.2 [NU6.1]. Section 3.7: Action Transfers and their Descriptions `_ +.. [#protocol-abstractcommit] `Zcash Protocol Specification, Version 2025.6.2 [NU6.1]. Section 4.1.8: Commitment `_ +.. [#protocol-orchardsend] `Zcash Protocol Specification, Version 2025.6.2 [NU6.1]. Section 4.7.3: Sending Notes (Orchard) `_ +.. [#protocol-orcharddummynotes] `Zcash Protocol Specification, Version 2025.6.2 [NU6.1]. Section 4.8.3: Dummy Notes (Orchard) `_ +.. [#protocol-orchardbalance] `Zcash Protocol Specification, Version 2025.6.2 [NU6.1]. Section 4.14: Balance and Binding Signature (Orchard) `_ +.. [#protocol-rhoandnullifiers] `Zcash Protocol Specification, Version 2025.6.2 [NU6.1]. Section 4.16: Computing ρ values and Nullifiers `_ +.. [#protocol-actionstatement] `Zcash Protocol Specification, Version 2025.6.2 [NU6.1]. Section 4.18.4: Action Statement (Orchard) `_ +.. [#protocol-endian] `Zcash Protocol Specification, Version 2025.6.2 [NU6.1]. Section 5.1: Integers, Bit Sequences, and Endianness `_ +.. [#protocol-constants] `Zcash Protocol Specification, Version 2025.6.2 [NU6.1]. Section 5.3: Constants `_ +.. [#protocol-concretesinsemillahash] `Zcash Protocol Specification, Version 2025.6.2 [NU6.1]. Section 5.4.1.9: Sinsemilla hash function `_ +.. [#protocol-concretehomomorphiccommit] `Zcash Protocol Specification, Version 2025.6.2 [NU6.1]. Section 5.4.8.3: Homomorphic Pedersen commitments (Sapling and Orchard) `_ +.. [#protocol-concretesinsemillacommit] `Zcash Protocol Specification, Version 2025.6.2 [NU6.1]. Section 5.4.8.4: Sinsemilla commitments `_ +.. [#protocol-pallasandvesta] `Zcash Protocol Specification, Version 2025.6.2 [NU6.1]. Section 5.4.9.6: Pallas and Vesta `_ +.. [#protocol-notept] `Zcash Protocol Specification, Version 2025.6.2 [NU6.1]. Section 5.5: Encodings of Note Plaintexts and Memo Fields `_ +.. [#protocol-actionencodingandconsensus] `Zcash Protocol Specification, Version 2025.6.2 [NU6.1]. Section 7.5: Action Description Encoding and Consensus `_ .. [#initial-zsa-issue] `User-Defined Assets and Wrapped Assets `_ .. [#generalized-value-commitments] `Comment on Generalized Value Commitments `_ -.. [#circuit-modifications] `Modifications to the Orchard circuit for the ZSA Protocol `_ +.. [#circuit-modifications] `Modifications to the Orchard circuit for the OrchardZSA Protocol `_ diff --git a/zips/zip-0227-asset-identifier-relation-orchard-zsa.svg b/zips/zip-0227-asset-identifier-relation-orchard-zsa.svg new file mode 100644 index 000000000..897586a4d --- /dev/null +++ b/zips/zip-0227-asset-identifier-relation-orchard-zsa.svg @@ -0,0 +1,471 @@ + + + +image/svg+xmlassetDescHashAssetDigestAssetIdasset_descAssetBaseAssetIdissuer[33 bytes]AssetId[32 bytes][64 bytes][32 bytes][66 bytes] diff --git a/zips/zip-0227-key-components-zsa.svg b/zips/zip-0227-key-components-zsa.svg index eb38e4dcb..4f30b6b0a 100644 --- a/zips/zip-0227-key-components-zsa.svg +++ b/zips/zip-0227-key-components-zsa.svg @@ -26,7 +26,7 @@ inkscape:pageopacity="0.0" inkscape:pageshadow="2" inkscape:zoom="0.80392436" - inkscape:cx="183.47497" + inkscape:cx="220.16997" inkscape:cy="176.63353" inkscape:document-units="px" inkscape:current-layer="layer1" @@ -34,7 +34,7 @@ inkscape:window-width="1068" inkscape:window-height="916" inkscape:window-x="222" - inkscape:window-y="102" + inkscape:window-y="38" inkscape:window-maximized="0" inkscape:showpageshadow="2" inkscape:pagecheckerboard="0" @@ -167,13 +167,13 @@ inkscape:export-filename="zip-0227-key-components-zsa.png" inkscape:export-xdpi="179.99957" inkscape:export-ydpi="179.99957" />iskikik Vivek Arte - Daira-Emma Hopwood - Jack Grigg + Daira-Emma Hopwood + Jack Grigg Credits: Daniel Benarroch Aurelien Nicolas Deirdre Connolly @@ -25,26 +25,26 @@ The key words "MUST", "MUST NOT", "SHOULD", "RECOMMENDED", and "MAY" in this doc 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 "Orchard" and "Action" in this document are to be interpreted as described in ZIP 224 [#zip-0224]_. We define the following additional terms: -- Asset: A type of note that can be transferred on the Zcash blockchain. Each Asset is identified by an Asset Identifier `Specification: Asset Identifier`_. +- Asset: A type of note that can be transferred on the Zcash blockchain. Each Asset is identified by an Asset Identifier `Specification: Asset Identifier, Asset Digest, and Asset Base`_. - ZEC is the default (and currently the only defined) Asset for the Zcash mainnet. - TAZ is the default (and currently the only defined) Asset for the Zcash testnet. - We use the term "Custom Asset" to refer to any Asset other than ZEC and TAZ. -- Native Asset: a Custom Asset with issuance defined on the Zcash blockchain. -- Wrapped Asset: a Custom Asset with native issuance defined outside the Zcash blockchain. - Issuance Action: an instance of a single issuance of a Zcash Shielded Asset. It defines the issuance of a single Asset Identifier. - Issuance Bundle: the bundle in the transaction that contains all the issuance actions of that transaction. Abstract ======== -This ZIP (ZIP 227) proposes the Zcash Shielded Assets (ZSA) protocol, in conjunction with ZIP 226 [#zip-0226]_. This protocol is an extension of the Orchard protocol that enables the creation, transfer and burn of Custom Assets on the Zcash chain. The creation of such Assets is defined in this ZIP (ZIP 227), while the transfer and burn of such Assets is defined in ZIP 226 [#zip-0226]_. This ZIP must only be implemented in conjunction with ZIP 226 [#zip-0226]_. The proposed issuance mechanism is only valid for the Orchard-ZSA transfer protocol, because it produces notes that can only be transferred under ZSA. +This ZIP (ZIP 227) proposes the Orchard Zcash Shielded Assets (OrchardZSA) protocol, in conjunction with ZIP 226 [#zip-0226]_. This protocol is an extension of the Orchard protocol that enables the creation, transfer and burn of Custom Assets on the Zcash chain. The creation of such Assets is defined in this ZIP (ZIP 227), while the transfer and burn of such Assets is defined in ZIP 226 [#zip-0226]_. This ZIP must only be implemented in conjunction with ZIP 226 [#zip-0226]_. The proposed issuance mechanism is only valid for the OrchardZSA transfer protocol, because it produces notes that can only be transferred via this protocol. Motivation ========== @@ -53,7 +53,7 @@ This ZIP introduces the issuance mechanism for Custom Assets on the Zcash chain. This ZIP only enables *transparent* issuance. As a first step, transparency will allow for proper testing of the applications that will be most used in the Zcash ecosystem, and will enable the supply of Assets to be tracked. -The issuance mechanism described in this ZIP is broad enough for issuers to either create Assets on Zcash (i.e. Assets that originate on the Zcash blockchain), as well as for institutions to create bridges from other chains and import Wrapped Assets. This enables what we hope will be a useful set of applications. +The issuance mechanism described in this ZIP is broad enough for issuers to either create Assets on Zcash (i.e. Assets that originate on the Zcash blockchain), as well as for institutions to create bridges from other chains and issue Assets that wrap tokens from those chains. This enables what we hope will be a useful set of applications. Use Cases ========= @@ -75,17 +75,20 @@ 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, Issuer Identifier, and Issuance Authorization Signature Scheme +============================================================================================ -Specification: Issuance Keys and Issuance Authorization Signature Scheme -======================================================================== +Issuance Keys +------------- -The Orchard-ZSA Protocol adds the following keys to the key components [#protocol-addressesandkeys]_ [#protocol-orchardkeycomponents]_: +The OrchardZSA Protocol adds the following keys used for issuance: -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. The relations between these keys are shown in the following diagram: @@ -94,26 +97,42 @@ The relations between these keys are shown in the following diagram: :align: center :figclass: align-center - Diagram of Issuance Key Components for the Orchard-ZSA Protocol + Diagram of Issuance Key Components for the OrchardZSA Protocol + + +Issuer Identifier +----------------- + +The identifier for a particular issuer is denoted by $\mathsf{issuer}$. This identifier 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. + +$\mathsf{issuer}$ is equal to the encoding $\mathsf{ik\_encoding}$ (specified below in `Derivation of issuance validating key`_) of the issuance validating key $\mathsf{ik}$ used to validate the issuance of Asset Identifiers by that issuer. + +Note: the equality of $\mathsf{issuer}$ and $\mathsf{ik\_encoding}$ might not hold in future when key rotation is specified for issuance key pairs. 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]_. +The issuance authorization signature, encoded in the ``issueAuthSig`` field of an issuance bundle, is used to authorize the issuance of Custom Assets by the issuer. + +The issuance authorization signature scheme, $\mathsf{IssueAuthSig}$, comprises all the associated types and algorithms required for a signature scheme in §4.1.7 ‘Signature’ [#protocol-abstractsig]_. -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. +Orchard ZSA Issuance Authorization Signature Scheme +``````````````````````````````````````````````````` + +In the OrchardZSA protocol, we instantiate the issuance authorization signature scheme $\mathsf{IssueAuthSig}$ as a BIP-340 Schnorr signature over the secp256k1 curve. 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, which are identical to BIP 340, 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. @@ -123,171 +142,254 @@ Issuance Key Derivation Issuance authorizing key generation for hierarchical deterministic wallets `````````````````````````````````````````````````````````````````````````` -The issuance authorizing key is generated using the Orchard master key derivation procedure defined in ZIP 32 [#zip-0032-orchard-master]_. We reuse the functions defined there in what follows in this section. +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 $\mathsf{Issuance}$ context, we define the following constants: + +- $\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{MasterKeyGen}(\texttt{"ZIP32ZSAIssue_V1"}, 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)$. -As in ZIP 32 for Orchard [#zip-0032-orchard-child-key-derivation]_, we only use hardened child key derivation for the issuance authorizing key. -We reuse the :math:`\mathsf{CDKsk}` function for Orchard child key derivation from ZIP 32. +We use hardened-only child key derivation as defined in ZIP 32 [#zip-0032-hardened-only-child-key-derivation]_ for the issuance authorizing key. -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: +$\mathsf{CKDsk}((\mathsf{sk}_{par},\mathsf{c}_{par}), i) \rightarrow (\mathsf{sk}_{i}, \mathsf{c}_{i})$ : -- :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\!`. +- Return $\mathsf{CKDh}^{\mathsf{Issuance}}((\mathsf{sk}_{par},\mathsf{c}_{par}), i)$ -From the generated :math:`(\mathsf{sk}, \mathsf{c})\!`, we set the issuance authorizing key to be :math:`\mathsf{isk} := \mathsf{sk}\!`. +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: + +- $\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 $(\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: + +* $\mathsf{ik} := \textit{PubKey}(\mathsf{isk})$ +* Return $\bot$ if the $\textit{PubKey}$ algorithm invocation fails, otherwise return $\mathsf{ik}$. -* :math:`\mathsf{ik} := \textit{PubKey}(\mathsf{isk})` -* Return :math:`\bot` if the :math:`\textit{PubKey}` algorithm invocation fails, otherwise return :math:`\mathsf{ik}\!`. +where the $\textit{PubKey}$ algorithm is defined in BIP 340 [#bip-0340]_, and the output of the algorithm is in big-endian order as defined in BIP 340. -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. +The encoding of this validating key, $\mathsf{ik\_encoding}$, includes an initial byte indicating the signature scheme, which MUST be $\mathtt{0x00}$ indicating BIP 340. +That is, $\mathsf{ik\_encoding} = [\mathtt{0x00}] \,||\, \mathsf{ik}$. This enables future ZIPs to specify alternative signature schemes. +Note that this encoding currently only appears in the ``issuer`` field of an issuance bundle. -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. +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, use a multi-signature protocol) while the rest of the keys remain safe in the wallet. 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)$ with auxiliary data $a$. +* 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 [#bip-0340]_. +Note that $\mathsf{IssueAuthSig.Sign}$ could return $\bot$ with very low probability. +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: -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: +* Return $0$ if $\text{σ} = \bot$. +* Return $1$ if $\mathsf{Verify}(\mathsf{key}, M, \text{σ})$ succeeds, otherwise $0$. -* Return :math:`0` if :math:`\text{σ} = \bot\!`. -* Return :math:`1` if :math:`\mathsf{Verify}(\mathsf{ik}, M, \text{σ})` succeeds, otherwise :math:`0\!`. +where the $\mathsf{Verify}$ algorithm is defined in BIP 340 [#bip-0340]_. -where the :math:`\mathsf{Verify}` algorithm is defined in BIP 340 [#bip-0340]_. +The $\mathtt{issueAuthSig}$ field of an issuance bundle encodes the signature with an initial byte indicating the signature scheme, which MUST be $\mathtt{0x00}$ indicating BIP 340. +That is, $\mathtt{issueAuthSig} = [\mathtt{0x00}] \,||\, \text{σ}$. This enables future ZIPs to specify alternative signature schemes. -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. +Specification: Asset Identifier, Asset Digest, and Asset Base +============================================================= -A given Asset Identifier is used across all Zcash protocols that support ZSAs -- that is, the Orchard-ZSA 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. -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. +The definition of the Asset Identifier, and that of the Asset Digest and Asset Base for a given Asset Identifier, will be described in this section. +For context, the relations between the Asset Identifier, Asset Digest, and Asset Base are shown in the following diagram: -Let +.. figure:: ../rendered/assets/images/zip-0227-asset-identifier-relation.png + :width: 600px + :align: center + :figclass: align-center -- :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. + Diagram relating the Asset Identifier, Asset Digest, and Asset Base. -Define :math:`\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. +**Note:** To keep notations light and concise, we may omit $\mathsf{AssetId}$ in the subscript when the Asset Identifier is clear from the context. -Define :math:`\mathsf{AssetBase_{AssetId}} := \mathsf{ZSAValueBase}(\mathsf{AssetDigest_{AssetId}})` -In the case of the Orchard-ZSA 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]_. +Asset Identifier +---------------- -The relations between the Asset Identifier, Asset Digest, and Asset Base are shown in the following diagram: +Every Asset has a globally-unique Asset Identifier, denoted $\mathsf{AssetId}$. A given +Asset Identifier is used across all Zcash protocols that support ZSAs -- that is, the +OrchardZSA protocol and potentially future Zcash shielded protocols. -.. figure:: ../rendered/assets/images/zip-0227-asset-identifier-relation.png - :width: 600px +ZIP 227 Asset Identifiers +````````````````````````` + +Assets issued using the protocol specified in this ZIP are scoped to the $\mathsf{issuer}$ +that issued them. Within that scope, Asset Identifier uniqueness is obtained by way of an +asset description, $\mathsf{asset\_desc}$, which includes any information pertaining to +the issuance. $\mathsf{asset\_desc}$ is a non-empty byte sequence which SHOULD be a +well-formed UTF-8 code unit sequence according to Unicode 15.0.0 or later. + +Define + +.. math:: + + \mathsf{assetDescHash} := \textsf{BLAKE2b-256}(\texttt{“ZSA-AssetDescCRH”},\; \mathsf{asset\_desc}), + +We define Asset Identifiers for Assets issued under this ZIP as + +.. math:: + + \mathsf{AssetId} := (\mathsf{issuer}, \mathsf{assetDescHash}) + +and define their canonical encoding as + +.. math:: + + \mathsf{EncodeAssetId}(\mathsf{AssetId}) = \mathsf{EncodeAssetId}((\mathsf{issuer}, \mathsf{assetDescHash})) := [\mathtt{0x00}] \,||\, \mathsf{issuer}\,||\,\mathsf{assetDescHash} + +Note that the initial $\mathtt{0x00}$ byte is a version byte, enabling future ZIPs to specify alternative issuance protocols and Asset Identifiers. (This should not be confused with the first byte of $\mathsf{issuer}$, currently equal to the first byte of $\mathsf{ik\_encoding}$, that indicates the issuance signature scheme.) + +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 [#petnames]_. 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 byte sequence to uniquely determine an Asset, and wallets could support clients scanning QR codes to load Asset information into their wallets. + +Asset Digests +------------- + +From the Asset Identifier, we derive an Asset Digest + +.. math:: + + \mathsf{AssetDigest_{AssetId}} := \textsf{BLAKE2b-512}(\texttt{“ZSA-Asset-Digest”},\; \mathsf{EncodeAssetId}(\mathsf{AssetId})), + +where $\mathsf{EncodeAssetId}(\mathsf{AssetId})$ is the canonical encoding scheme for the +Asset Identifier. + +Asset Bases +----------- + +From the Asset Digest, we derive a specific Asset Base that represents the Custom Asset +within each shielded protocol: + +.. math:: + + \mathsf{AssetBase_{AssetId}} := \mathsf{ZSAValueBase}(\mathsf{AssetDigest_{AssetId}}) + +This Asset Base is included in shielded notes within the shielded protocol. + +OrchardZSA Asset Bases +`````````````````````` + +In the case of the OrchardZSA protocol, we define + +.. math:: + + \mathsf{ZSAValueBase}(\mathsf{AssetDigest}) := \mathsf{GroupHash}^\mathbb{P}(\texttt{"z.cash:OrchardZSA"}, \mathsf{AssetDigest}) + +where $\mathsf{GroupHash}^\mathbb{P}$ is defined as in [#protocol-concretegrouphashpallasandvesta]_. + +.. figure:: ../rendered/assets/images/zip-0227-asset-identifier-relation-orchard-zsa.png + :width: 800px :align: center :figclass: align-center - Diagram relating the Asset Identifier, Asset Digest, and Asset Base in the ZSA Protocol + Diagram relating the Issuer identifier, asset description, asset description hash, Asset Identifier, Asset Digest, and Asset Base for 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. +Specification: Issue Note, Issuance Action, Issuance Bundle and Issuance Protocol +================================================================================= -Wallets MUST NOT display just the :math:`\mathsf{asset\_desc}` string to their users as the name of the Asset. Some possible alternatives include: +Issue Note +---------- -- 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. +Let $\ell_{\mathsf{value}}$ be as defined in §5.3 ‘Constants’ [#protocol-constants]_. +An Issue Note represents that a value $\mathsf{v} : \{0 .. 2^{\ell_{\mathsf{value}}} - 1\}$ of a specific Custom Asset is issued to a recipient. +An Issue Note is a tuple $(\mathsf{d}, \mathsf{pk_d}, \mathsf{v}, \mathsf{AssetBase}, \text{ρ}, \mathsf{rseed})$, where: -Specification: Global Issuance State -==================================== +- $\mathsf{d}: \mathbb{B}^{[\ell_{\mathsf{d}}]}$ is the diversifier of the recipient's shielded payment address, as in §3.2 ‘Notes’ [#protocol-notes]_. +- $\mathsf{pk_d}: \mathsf{KA}^{\mathsf{Orchard}}.\mathsf{Public}$ is the recipient's diversified transmission key, as in §3.2 ‘Notes’ [#protocol-notes]_. +- $\mathsf{v} : \{0 .. 2^{\ell_{\mathsf{value}}} - 1\}$ is the value of the note in terms of the number of Asset tokens. +- $\mathsf{AssetBase}: \mathbb{P}^*$ is the Asset Base corresponding to the ZSA being issued in the Issue Note. +- $\text{ρ}: \mathbb{F}_{q_{\mathbb{P}}}$ is used to derive the nullifier of the note, and is computed as in `Computation of ρ`_. +- $\mathsf{rseed}: \mathbb{B}^{[\mathbb{Y}^{32}]}$ MUST be sampled uniformly at random by the issuer. -Issuance requires the following additions to the global state defined at block boundaries: +ZIP 230 [#zip-0230-issue-note]_ defines, in ``IssueNoteDescription``, field encodings which together with +$\mathsf{issuer}$ from the parent `Issuance Bundle`_ and $\mathsf{AssetDescHash}$ from the parent +`Issuance Action`_, specify an Issue Note. -- :math:`\mathsf{previously\_finalized}\!`, a set of :math:`\mathsf{AssetId}` that have been finalized (i.e.: the :math:`\mathsf{finalize}` flag has been set to :math:`1` in some issuance transaction preceding the block boundary). +Let $\mathsf{Note^{Issue}}$ be the type of an Issue Note, i.e. +.. math:: -Specification: Issuance Action, Issuance Bundle and Issuance Protocol -===================================================================== + \mathsf{Note^{Issue}} := \mathbb{B}^{[\ell_{\mathsf{d}}]} \times \mathsf{KA}^{\mathsf{Orchard}}.\mathsf{Public} \times \{0 .. 2^{\ell_{\mathsf{value}}} - 1\} \times \mathbb{P}^* \times \mathbb{F}_{q_{\mathbb{P}}} \times \mathbb{B}^{[\mathbb{Y}^{32}]}. -Issuance Action Description ---------------------------- +The note commitments of Issue Notes are computed in the same manner as for OrchardZSA Notes. +They will be added to the note commitment tree as any other shielded note when the transaction issuing the Asset is included on chain. +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 Action +--------------- 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\!`, stored in two bytes. -- ``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. - -An asset's :math:`\mathsf{AssetDigest}` is added to the :math:`\mathsf{previously\_finalized}` set after a block that contains any issuance transaction for that asset with :math:`\mathsf{finalize} = 1\!`. It then cannot be removed from this set. For Assets with :math:`\mathsf{AssetDigest} \in \mathsf{previously\_finalized}\!`, no further tokens can be issued, so as seen below, the validators will reject the transaction. For Assets with :math:`\mathsf{AssetDigest} \not\in \mathsf{previously\_finalized}\!`, new issuance actions can be issued in future transactions. These must use the same Asset description, :math:`\mathsf{asset\_desc}\!`, and can either maintain :math:`\mathsf{finalize} = 0` or change it to :math:`\mathsf{finalize} = 1\!`, denoting that this Custom Asset cannot be issued after the containing block. - - -+-----------------------------+--------------------------+-------------------------------------------+---------------------------------------------------------------------+ -| Bytes | Name | Data Type | Description | -+=============================+==========================+===========================================+=====================================================================+ -|``2`` |``assetDescSize`` |``byte`` |The length of the ``asset_desc`` string in bytes. | -+-----------------------------+--------------------------+-------------------------------------------+---------------------------------------------------------------------+ -|``assetDescSize`` |``asset_desc`` |``byte[assetDescSize]`` |A byte sequence of length ``assetDescSize`` bytes which SHOULD be a | -| | | |well-formed UTF-8 code unit sequence according to Unicode 15.0.0 | -| | | |or later. | -+-----------------------------+--------------------------+-------------------------------------------+---------------------------------------------------------------------+ -|``varies`` |``nNotes`` |``compactSize`` |The number of notes in the issuance action. | -+-----------------------------+--------------------------+-------------------------------------------+---------------------------------------------------------------------+ -|``noteSize * nNotes`` |``vNotes`` |``Note[nNotes]`` |A sequence of note descriptions within the issuance action, | -| | | |where ``noteSize`` is the size, in bytes, of a Note. | -+-----------------------------+--------------------------+-------------------------------------------+---------------------------------------------------------------------+ -|``1`` |``flagsIssuance`` |``byte`` |An 8-bit value representing a set of flags. Ordered from LSB to MSB: | -| | | | * :math:`\mathsf{finalize}` | -| | | | * The remaining bits are set to :math:`0\!`. | -+-----------------------------+--------------------------+-------------------------------------------+---------------------------------------------------------------------+ - -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. +- ``assetDescHash``: the hash of the Asset description, as defined in the `ZIP 227 Asset Identifiers`_ section. +- ``vNotes``: an array of Issue Notes containing the unencrypted output notes to the recipients of the Asset. +- ``flagsIssuance``: a byte that stores the $\mathsf{finalize}$ boolean that defines whether the issuance of that specific Custom Asset is finalized or not. + +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]_. + Issuance Bundle --------------- -An issuance bundle, ``IssueBundle``, is the aggregate of all the issuance-related information. +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. +- ``issuer``: the issuer identifier, 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. - -The issuance bundle is then added within the transaction format as a new bundle. That is, issuance requires the addition of the following information to the transaction format [#protocol-txnencoding]_. - -+------------------------------------+--------------------------+-------------------------------------------+---------------------------------------------------------------------------+ -| Bytes | Name | Data Type | Description | -+====================================+==========================+===========================================+===========================================================================+ -|``varies`` |``nIssueActions`` |``compactSize`` |The number of issuance actions in the bundle. | -+------------------------------------+--------------------------+-------------------------------------------+---------------------------------------------------------------------------+ -|``IssueActionSize * nIssueActions`` |``vIssueActions`` |``IssueAction[nIssueActions]`` |A sequence of issuance action descriptions, where IssueActionSize is | -| | | |the size, in bytes, of an IssueAction description. | -+------------------------------------+--------------------------+-------------------------------------------+---------------------------------------------------------------------------+ -|``32`` |``ik`` |``byte[32]`` |The issuance validating key of the issuer, used to validate the signature. | -+------------------------------------+--------------------------+-------------------------------------------+---------------------------------------------------------------------------+ -|``64`` |``issueAuthSig`` |``byte[64]`` |The signature of the transaction SIGHASH, signed by the issuer, | -| | | |validated as in `Issuance Authorization Signature Scheme`_. | -+------------------------------------+--------------------------+-------------------------------------------+---------------------------------------------------------------------------+ +- ``issueAuthSig``: the encoding of a 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]_. + +Computation of ρ +---------------- + +We define a function $\mathsf{DeriveIssuedRho} : \mathbb{F}_{q_{\mathbb{P}}} \times \{0 .. 2^{32} - 1\} \times \{0 .. 2^{32} - 1\} \to \mathbb{F}_{q_{\mathbb{P}}}$ for Issue Notes in the OrchardZSA Protocol as follows: + +.. math:: + + \mathsf{DeriveIssuedRho}(\mathsf{nf}, \mathsf{i_{A}}, \mathsf{i_{N}}) := \mathsf{ToBase}^{\mathsf{Orchard}}\big(\mathsf{PRF}^{\mathsf{expand}}\big(\mathsf{I2LEOSP}_{256}(\mathsf{nf}), [\mathtt{0x84}] \,||\, \mathsf{I2LEOSP}_{32}(\mathsf{i_{A}}) \,||\, \mathsf{I2LEOSP}_{32}(\mathsf{i_{N}})\big)\big), + +where $\mathsf{ToBase}^{\mathsf{Orchard}}$ is defined in §4.2.3 ‘Orchard Key Components’ [#protocol-orchardkeycomponents]_, and $\mathsf{PRF}^{\mathsf{expand}}$ is defined in §5.4.2 ‘Pseudo Random Functions’ [#protocol-concreteprfs]_. + +The $\text{ρ}$ field of an Issue Note is computed as + +.. math:: + + \text{ρ} := \mathsf{DeriveIssuedRho}(\mathsf{nf}_{0,0}, \mathsf{index_{Action}}, \mathsf{index_{Note}}), + +where $\mathsf{nf}_{0,0}$ is the nullifier for the input note in the first Action in the first Action Group of the OrchardZSA Bundle of the transaction, $\mathsf{index_{Action}}$ is the zero-based index of the Issuance Action in the Issuance Bundle, and $\mathsf{index_{Note}}$ is the zero-based index of the Issue Note in the Issuance Action. + +**NOTE:** This implicitly requires that there always is an Action Group in the OrchardZSA bundle of the transaction. +This is enforced by a consensus rule in the `Specification: Consensus Rule Changes`_ section. Issuance Protocol ----------------- @@ -295,252 +397,237 @@ 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. +- compute $\mathsf{assetDescHash}$ +- compute $\mathsf{AssetDigest}$ from the issuer identifier $\mathsf{issuer}$ and $\mathsf{assetDescHash}$ as decribed in the `Specification: Asset Identifier, Asset Digest, and Asset Base`_ section. +- compute $\mathsf{AssetBase}$ from $\mathsf{AssetDigest}$ as decribed in the `Specification: Asset Identifier, Asset Digest, and Asset Base`_ 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 Orchard-ZSA 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 an Issue Note, $\mathsf{note}_i = (\mathsf{d}_i, \mathsf{pk}_{\mathsf{d}_i}, \mathsf{v}_i, \mathsf{AssetBase}, \text{ρ}_i, \mathsf{rseed}_i)$. + - encode the $\mathsf{note}_i$ into the vector ``vNotes`` of the ``IssueAction``. - encode the ``IssueAction`` into the vector ``vIssueActions`` of the bundle. -For the ``IssueBundle``: +For the ``IssueBundle`` (see “ZSA Issuance Bundle Fields” in [#zip-0230-transaction-format]_): - 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. +- fill the ``issuerLength`` and ``issuer`` fields using $\mathsf{issuer}$. +- 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. +**Note:** The note 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. +Specification: Reference Notes and Global Issuance State +======================================================== -Specification: Consensus Rule Changes -===================================== - -For the ``IssueBundle``: - -- Validate the issuance authorization signature, :math:`\mathsf{issueAuthSig}\!`, on the SIGHASH transaction hash, :math:`\mathsf{SigHash}\!`, by invoking :math:`\mathsf{IssueAuthSig}.\!\mathsf{Validate}(\mathsf{ik}, \mathsf{SigHash}, \mathsf{issueAuthSig})\!`. - -For each ``IssueAction`` in ``IssueBundle``: +Reference Notes +--------------- -- check that :math:`0 < \mathtt{assetDescSize} \leq 512\!`. -- check that :math:`\mathsf{asset\_desc}` is a string of length :math:`\mathtt{assetDescSize}` bytes. +A reference note for a Custom Asset MUST be included by the issuer as the first Note in the Action of the Issuance Bundle where that Custom Asset is being issued for the first time. -- retrieve :math:`\mathsf{AssetBase}` from the first note in the sequence and check that :math:`\mathsf{AssetBase}` is derived from the issuance validating key :math:`\mathsf{ik}` and :math:`\mathsf{asset\_desc}` as described in the `Specification: Asset Identifier`_ section. -- check that the :math:`\mathsf{AssetDigest}` does not exist in the :math:`\mathsf{previously\_finalized}` set in the global state. -- check that every note in the ``IssueAction`` contains the same :math:`\mathsf{AssetBase}` and is properly constructed as :math:`\mathsf{note} = (\mathsf{g_d}, \mathsf{pk_d}, \mathsf{v}, \text{ρ}, \mathsf{rseed}, \mathsf{AssetBase})\!`. +A reference note for a Custom Asset is an Issue Note where the value $\mathsf{v}$ is set to $0$, the Asset Base ($\mathsf{AssetBase}$) corresponds to that of the Custom Asset, and the recipient address $(\mathsf{d}, \mathsf{pk}_{\mathsf{d}})$ is set to the default diversified payment address (i.e. the diversified payment address with diversifier index $0$) derived from the all-zero Orchard spending key using the algorithm specified in §4.2.3 ‘Orchard Key Components’ [#protocol-orchardkeycomponents]_. This corresponds to a 43-byte ``u8`` array with the following entries:: -If all of the above checks pass, do the following: + [ + 204, 54, 96, 25, 89, 33, 59, 107, 12, 219, 150, 167, 92, 23, 195, 166, 104, 169, 127, 13, 106, + 140, 92, 225, 100, 165, 24, 234, 155, 169, 165, 14, 167, 81, 145, 253, 134, 27, 15, 241, 14, + 98, 176, + ] -- For each note, compute the note commitment as :math:`\mathsf{cm} = \mathsf{NoteCommit^{OrchardZSA}_{rcm}}(\mathsf{repr}_{\mathbb{P}}(\mathsf{g_d}), \mathsf{repr}_{\mathbb{P}}(\mathsf{pk_d}), \mathsf{v}, \text{ρ}, \text{ψ}, \mathsf{AssetBase})` as defined in the Note Structure and Commitment section of ZIP 226 [#zip-0226-notestructure]_ and -- Add :math:`\mathsf{cm}` to the Merkle tree of note commitments. -- If :math:`\mathsf{finalize} = 1\!`, add :math:`\mathsf{AssetDigest}` to the :math:`\mathsf{previously\_finalized}` set immediately after the block in which this transaction occurs. -- (Replay Protection) If issue bundle is present, the fees MUST be greater than zero. +Global Issuance State +--------------------- +The maximum total supply of any issued Custom Asset is denoted by the constant $\mathsf{MAX\_ISSUE} := 2^{64} - 1$. -Rationale -========= -The following is a list of rationale for different decisions made in the proposal: +Issuance requires the following additions to the global state: -- The issuance key structure is independent of the original key tree, but derived in an analogous manner (via ZIP 32). This is in order to keep the issuance details and the Asset Identifiers consistent across multiple shielded pools. -- The design decision is not to have a chosen name to describe the Custom Asset, but to delegate it to an off-chain mapping, as this would imply a land-grab “war”. -- 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: +A map, $\mathsf{issued\_assets} : \mathbb{P}^* \to \{0 .. \mathsf{MAX\_ISSUE}\} \times \mathbb{B} \times \mathsf{Note^{Issue}}$, from the Asset Base, $\mathsf{AssetBase} : \mathbb{P}^*$, to a tuple $(\mathsf{balance}, \mathsf{final}, \mathsf{note_{ref}})$, for every Asset that has been issued. +We use the notation $\mathsf{issued\_assets}(\mathsf{AssetBase}).\mathsf{balance}$, $\mathsf{issued\_assets}(\mathsf{AssetBase}).\mathsf{final}$, and $\mathsf{issued\_assets}(\mathsf{AssetBase}).\mathsf{note_{ref}}$ 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$, $\mathsf{issued\_assets}(\mathsf{AssetBase}).\mathsf{final} = 0$, and $\mathsf{issued\_assets}(\mathsf{AssetBase}).\mathsf{note_{ref}} = \bot$. - - 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. +For any Asset represented by $\mathsf{AssetBase}$: -- We require a check whether the :math:`\mathsf{finalize}` flag only has been set in a previous block rather than a previous transaction in the same block. In other words, we only update the :math:`\mathsf{previously\_finalized}`` set at the block boundary. This is in keeping with the current property which allows for a miner to reorder transactions in a block without changing the meaning, which we aim to preserve. -- 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. +- $\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$. +- $\mathsf{issued\_assets}(\mathsf{AssetBase}).\mathsf{note_{ref}} : \mathsf{Note^{Issue}}$ stores the reference note for the Asset, as defined in the `Reference Notes`_ section. -Concrete Applications ---------------------- -**Asset Features** +Management of the Global Issuance State +--------------------------------------- -- 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, +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: - - 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. +- The input issuance state for the activation block of the OrchardZSA protocol is the empty map. +- The input issuance state for the first transaction of a block is the final issuance state of the immediately preceding block. +- The input issuance state of each subsequent transaction in the block is the output issuance state of the immediately preceding transaction. +- The final issuance state of a block is the output issuance state of the last transaction in the block. -- Issuers can also stop the existing supply production of any Asset associated to their issuer keys. This could be done by +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}}$ to denote the input issuance state and output issuance state for a transaction, respectively. - - 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). - - Note in the above cases, that the setting of the :math:`\mathsf{finalize}` flag will take effect at the block boundary, that is, after all the transactions in the block. -- 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. +Specification: Consensus Rule Changes +===================================== -- 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. +Let $\mathsf{SigHash}$ be the SIGHASH transaction hash of this transaction, as defined in §4.10 ‘SIGHASH Transaction Hashing’ [#protocol-sighash]_ with the modifications described in ZIP 226 [#zip-0226-txiddigest]_, using $\mathsf{SIGHASH\_ALL}$. +For every transaction: +- The ``nActionGroupsOrchard`` field MUST have a value of either ``0`` or ``1`` and the ``nAGExpiryHeight`` field MUST have a value of ``0``. +- 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}$. -TxId Digest - Issuance -====================== +If the transaction contains an issuance bundle: -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 Orchard-ZSA protocol can be found in ZIP 226 [#zip-0226-txiddigest]_. -As in ZIP 244 [#zip-0244]_, 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. +- It MUST also contain at least one OrchardZSA Action Group. +- The encoding $\mathsf{ik\_encoding}$ of the issuance key $\mathsf{ik}$ used to validate the issuance authorization signature MUST be taken from the ``issuer`` field, and MUST start with the byte value $\mathtt{0x00}$ indicating a BIP 340 public key. +- 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: -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:: + - Every ``IssueNoteDescription`` in the ``IssueAction`` MUST be a valid field encoding as defined in ZIP 230 [#zip-0230-issue-note]_. + - Let an Issue Note (with type $\mathsf{Note^{Issue}}$) be constructed from the fields of each ``IssueNoteDescription``, with the $\mathsf{AssetBase}$ derived from the ``assetDescHash`` field of the ``IssueAction`` and the ``issuer`` field of the issuance bundle, as described in the `Specification: Asset Identifier, Asset Digest, and Asset Base`_ section. + - It MUST be the case that $\mathsf{issued\_assets}_{\mathsf{OUT}}(\mathsf{AssetBase}).\mathsf{final} \neq 1$. + - If $\mathsf{issued\_assets}_{\mathsf{OUT}}(\mathsf{AssetBase}).\mathsf{note_{ref}} = \bot$, then let $\mathsf{new\_note_{ref}}$ be the first Issue Note in the Issuance Action. - issuance_digest - ├── issue_actions_digest - │   ├── issue_notes_digest - │   ├── assetDescription - │   └── flagsIssuance - └── issuanceValidatingKey + - The recipient address $(\mathsf{d}, \mathsf{pk}_{\mathsf{d}})$ of $\mathsf{new\_note_{ref}}$ MUST be the default diversified payment address derived from the all-zero Orchard spending key, as described in the `Reference Notes`_ section. + - The value of $\mathsf{new\_note_{ref}}$ MUST be $0$. + - The node MUST update $\mathsf{issued\_assets}_{\mathsf{OUT}}(\mathsf{AssetBase}).\mathsf{note_{ref}} = \mathsf{new\_note_{ref}}$. -In the specification below, nodes of the tree are presented in depth-first order. + - For every Issue Note, $\mathsf{note}_j$ for $1 \leq j \leq \mathtt{nNotes}$ in ``IssueAction``: -T.5: issuance_digest --------------------- -A BLAKE2b-256 hash of the following values :: + - The $\text{ρ}$ field of the issue note MUST have been computed as described in the `Computation of ρ`_ section. + - It MUST be the case that $\mathsf{issued\_assets}_{\mathsf{OUT}}.\mathsf{balance} + \mathsf{v}_j \leq \mathsf{MAX\_ISSUE}$, where $\mathsf{v}_j$ is the value of $\mathsf{note}_j$. The node then MUST update $\mathsf{issued\_assets}_{\mathsf{OUT}}.\mathsf{balance} = \mathsf{issued\_assets}_{\mathsf{OUT}}.\mathsf{balance} + \mathsf{v}_j$. + - 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-note-structure-and-commitment]_. + - If $\mathsf{finalize} = 1$ within the ``flagsIssuance`` field of ``IssueAction``, the node MUST set $\mathsf{issued\_assets}_{\mathsf{OUT}}(\mathsf{AssetBase}).\mathsf{final} = 1$. - T.5a: issue_actions_digest (32-byte hash output) - T.5b: issuanceValidatingKey (32 bytes) +Addition to the Note Commitment Tree +------------------------------------ -The personalization field of this hash is set to:: +If the transaction is added to the block chain, the note commitments of all the OrchardZSA Notes and the Issue Notes in the transaction are added to the note commitment tree of the associated treestate. +The order of addition to the tree is as specified below: - "ZTxIdSAIssueHash" +- For each Action Group in the OrchardZSA Bundle: -In case the transaction has no issuance components, ''issue_actions_digest'' is:: + - For every Action in the Action Group, append the note commitment of every new OrchardZSA note in the Action to the note commitment tree. - BLAKE2b-256("ZTxIdSAIssueHash", []) +- For each Issue Action in the Issue Bundle: -T.5a: issue_actions_digest -`````````````````````````` -A BLAKE2b-256 hash of Issue Action information for all Issuance Actions belonging to the transaction. For each Action, the following elements are included in the hash:: + - For every Issue Note in the Issue Action, append the note commitment of the Issue Note to the note commitment tree. - T.5a.i : notes_digest (32-byte hash output) - T.5a.ii : assetDescription (field encoding bytes) - T.5a.iii: flagsIssuance (1 byte) +Rationale +========= +The following is a list of rationale for different decisions made in the proposal: -The personalization field of this hash is set to:: +- 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 issuer identifier and an asset description string, to preclude the possibility of two different issuers creating colliding Custom Assets. +- The requirement of at least one OrchardZSA Action Group in the presence of an issue bundle is both to allow for the computation of the $\text{ρ}$ field of the issue notes, as well as to prevent replay attacks. 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. - "ZTxIdIssuActHash" +Hash of the asset description +----------------------------- -T.5a.i: issue_notes_digest -'''''''''''''''''''''''''' -A BLAKE2b-256 hash of Note information for all Notes belonging to the Issuance Action. For each Note, the following elements are included in the hash:: +In an earlier version of this ZIP, the asset description was a direct component of the +Asset Identifier, and was stored on-chain in each issuance transaction. The Asset +Identifier and issuance transactions now instead include a collision-resistant hash of the +asset description, for the following reasons: - T.5a.i.1: recipient (field encoding bytes) - T.5a.i.2: value (field encoding bytes) - T.5a.i.3: assetBase (field encoding bytes) - T.5a.i.4: rho (field encoding bytes) - T.5a.i.5: rseed (field encoding bytes) +- A hash output (32 bytes per Issue Action) incurs lower average bandwidth costs in + issuance transactions than the asset description (previously up to 512 bytes). -The personalization field of this hash is set to:: +- The asset description can be longer than 512 bytes without incurring chain costs. - "ZTxIdIAcNoteHash" +- Including an asset description byte string directly in issuance transactions does not + ensure that the "user-visible" asset description is consensus-visible, because the byte + string could itself be a hash of another off-chain description (even if the consensus + rules had required it to be a Unicode string instead of only recommending it). -T.5a.i.1: recipient -................... -This is the raw encoding of an Orchard shielded payment address as defined in the protocol specification [#protocol-orchardpaymentaddrencoding]_. +- The lack of key rotation in this issuance protocol means that it is not sufficient to + mark an $\mathsf{issuer}$ as trusted and then accept whatever asset descriptions are issued + by it. Each Asset Identifier needs to be independently verified, which requires some + out-of-band protocol that can also convey the corresponding asset description. -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. +- If issuance transactions include the asset descriptions directly, wallets will discover + them during scanning. This is an "attractive nuisance" because it would result in + wallets being more likely to expose the asset description directly to users without any + verification that the received asset has the value that a user might expect from that + description. By instead using a collision-resistant hash of an asset description, + wallets are forced to look up the corresponding asset description when a payment is + received in an unknown asset. That lookup can be mediated by a trusted party or common + trusted registry of known assets, or else will need to be approved directly by a user + who can personally assert their interest in that specific asset. -T.5a.i.3: assetBase -................... -Asset Base encoded as the 32-byte representation of a point on the Pallas curve. +Rationale for Global Issuance State +----------------------------------- -T.5a.i.4: rho -............. -Nullifier encoded as 32-byte representation of a point on the Pallas curve. +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 [#zip-0209]_. +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 case we specify a consensus rule to reject the transaction or block. -T.5a.i.5: rseed -............... -The ZIP 212 32-byte seed randomness for a note. +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. -T.5a.ii: assetDescription -''''''''''''''''''''''''' -The Asset description byte string. +Nodes also need to reject transactions that issue Custom Assets that have been previously finalized. +The $\mathsf{issued\_assets}$ map allows nodes to store whether or not a given Asset has been finalized. -T.5a.iii: flagsIssuance -''''''''''''''''''''''' -An 8-bit value representing a set of flags. Ordered from LSB to MSB: -- :math:`\mathsf{finalize}` -- The remaining bits are set to `0\!`. +Concrete Applications +--------------------- +**Asset Features** -T.5b: issuanceValidatingKey -``````````````````````````` -A byte encoding of issuance validating key for the bundle as defined in the `Issuance Key Derivation`_ section. +- 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, -Signature Digest -================ + - 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. -The per-input transaction digest algorithm to generate the signature digest in ZIP 244 [#zip-0244-sigdigest]_ 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. +- Issuers can also stop the existing supply production of any Asset associated to their issuer keys. This could be done by -The overall structure of the hash is as follows. We highlight the changes for the Orchard-ZSA protocol via the ``[ADDED FOR ZSA]`` text label, and we omit the descriptions of the sections that do not change for the Orchard-ZSA protocol:: + - 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). - signature_digest - ├── header_digest - ├── transparent_sig_digest - ├── sapling_digest - ├── orchard_digest - └── issuance_digest [ADDED FOR ZSA] +- 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. -signature_digest ----------------- -A BLAKE2b-256 hash of the following values :: +- 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. - S.1: header_digest (32-byte hash output) - S.2: transparent_sig_digest (32-byte hash output) - 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 [#zip-0244]_. -S.5: issuance_digest -```````````````````` -Identical to that specified for the transaction identifier. +Modifications relative to ZIP 244 [#zip-0244]_ +============================================== -Authorizing Data Commitment -=========================== +Relative to the sighash algorithm defined in ZIP 244, the sighash algorithm +that applies to v6 transactions differs by including the issuance bundle +components within the tree hash. See ZIP 246 [#zip-0246]_ for details. -The transaction digest algorithm defined in ZIP 244 [#zip-0244-authcommitment]_ which commits to the authorizing data of a transaction is modified by the Orchard-ZSA protocol to have the following structure. -We highlight the changes for the Orchard-ZSA protocol via the ``[ADDED FOR ZSA]`` text label, and we omit the descriptions of the sections that do not change for the Orchard-ZSA protocol:: - auth_digest - ├── transparent_scripts_digest - ├── sapling_auth_digest - ├── orchard_auth_digest - └── issuance_auth_digest [ADDED FOR ZSA] +Changes to ZIP 317 [#zip-0317]_ +=============================== -The pair (Transaction Identifier, Auth Commitment) constitutes a commitment to all the data of a serialized transaction that may be included in a block. +The conventional fee in ZEC is altered to take into account both the presence of +issuance actions within a transaction, and the creation of new Custom Assets +within the global chain state. See the Fee calculation section of ZIP 317 +[#zip-0317-fee-calculation]_ for details. -auth_digest ------------ -A BLAKE2b-256 hash of the following values :: - A.1: transparent_scripts_digest (32-byte hash output) - A.2: sapling_auth_digest (32-byte hash output) - A.3: orchard_auth_digest (32-byte hash output) - A.4: issuance_auth_digest (32-byte hash output) [ADDED FOR ZSA] +Rationale for paying fees in ZEC +-------------------------------- -The personalization field of this hash remains the same as in ZIP 244. +.. raw:: html -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:: +
    + Click to show/hide - A.4a: issueAuthSig (field encoding bytes) +We choose to maintain the native ZEC Asset as the primary token for the Zcash blockchain, similar to how ETH is needed for ERC20 transactions to the benefit of the Ethereum ecosystem. -The personalization field of this hash is set to:: +An alternative proposal for the OrchardZSA fee mechanism that was not adopted was to adopt a new type of fee, denominated in the custom Asset being issued or transferred. +In the context of transparent transactions, such a fee allows miners to “tap into” the ZSA value of the transactions, rather than the ZEC value of transactions. +However when transactions are shielded, any design that lifts value from the transaction would also leak information about it. - "ZTxAuthZSAOrHash" +.. raw:: html -In the case that the transaction has no Orchard Actions, ``issuance_auth_digest`` is :: +
    - BLAKE2b-256("ZTxAuthZSAOrHash", []) Security and Privacy Considerations =================================== @@ -548,19 +635,19 @@ Security and Privacy Considerations Displaying Asset Identifier information to users ------------------------------------------------ -Wallets need to communicate the names of the Assets in a non-confusing way to users, since the byte representation of the Asset Identifier would be hard to read for an end user. Possible solutions are provided in the `Specification: Asset Identifier`_ section. +Wallets need to communicate the names of the Assets in a non-confusing way to users, since the byte representation of the Asset Identifier would be hard to read for an end user. Possible solutions are provided in the `Specification: Asset Identifier, Asset Digest, and Asset Base`_ section. 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 issuer identifier is compromised, the $\mathsf{finalize}$ boolean for all the Assets issued with that key should be set to $1$; then the issuer should change to a new issuance authorizing key (hence a new issuer identifier), and issue new Assets, each with a new $\mathsf{AssetId}$. Bridging Assets --------------- -For bridging purposes, the secure method of off-boarding Assets is to burn an Asset with the burning mechanism in ZIP 226 [#zip-0226]_. 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 [#zip-0226]_. 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 Asset. Other Considerations ==================== @@ -568,12 +655,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. - -Fee Structures --------------- - -The fee mechanism described in this ZIP will follow the mechanism described in ZIP 317 [#zip-0317b]_. +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. Test Vectors @@ -597,24 +679,37 @@ 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" `_ -.. [#zip-0032] `ZIP 32: Shielded Hierarchical Deterministic Wallets `_ -.. [#zip-0032-orchard-master] `ZIP 32: Shielded Hierarchical Deterministic Wallets - Orchard master key generation `_ -.. [#zip-0032-orchard-child-key-derivation] `ZIP 32: Shielded Hierarchical Deterministic Wallets - Orchard child key derivation `_ -.. [#zip-0032-key-path-levels] `ZIP 32: Shielded Hierarchical Deterministic Wallets - Key path levels `_ -.. [#zip-0032-orchard-key-path] `ZIP 32: Shielded Hierarchical Deterministic Wallets - Orchard key path `_ -.. [#zip-0200] `ZIP 200: Network Upgrade Mechanism `_ -.. [#zip-0224] `ZIP 224: Orchard `_ -.. [#zip-0226] `ZIP 226: Transfer and Burn of Zcash Shielded Assets `_ -.. [#zip-0226-notestructure] `ZIP 226: Transfer and Burn of Zcash Shielded Assets - Note Structure & Commitment `_ -.. [#zip-0226-txiddigest] `ZIP 226: Transfer and Burn of Zcash Shielded Assets - TxId Digest `_ -.. [#zip-0244] `ZIP 244: Transaction Identifier Non-Malleability `_ -.. [#zip-0244-sigdigest] `ZIP 244: Transaction Identifier Non-Malleability: Signature Digest `_ -.. [#zip-0244-authcommitment] `ZIP 244: Transaction Identifier Non-Malleability: Authorizing Data Commitment `_ -.. [#zip-0317b] `ZIP 317: Proportional Transfer Fee Mechanism `_ +.. [#zip-0032] `ZIP 32: Shielded Hierarchical Deterministic Wallets `_ +.. [#zip-0032-hardened-only-key-derivation] `ZIP 32: Shielded Hierarchical Deterministic Wallets — Specification: Hardened-only key derivation `_ +.. [#zip-0032-hardened-only-child-key-derivation] `ZIP 32: Shielded Hierarchical Deterministic Wallets — Hardened-only child key derivation `_ +.. [#zip-0032-key-path-levels] `ZIP 32: Shielded Hierarchical Deterministic Wallets — Key path levels `_ +.. [#zip-0032-orchard-key-path] `ZIP 32: Shielded Hierarchical Deterministic Wallets — Orchard key path `_ +.. [#zip-0200] `ZIP 200: Network Upgrade Mechanism `_ +.. [#zip-0209] `ZIP 209: Prohibit Negative Shielded Chain Value Pool Balances `_ +.. [#zip-0224] `ZIP 224: Orchard `_ +.. [#zip-0226] `ZIP 226: Transfer and Burn of Zcash Shielded Assets `_ +.. [#zip-0226-note-structure-and-commitment] `ZIP 226: Transfer and Burn of Zcash Shielded Assets — Note Structure and Commitment `_ +.. [#zip-0226-assetburn] `ZIP 226: Transfer and Burn of Zcash Shielded Assets — Additional Consensus Rules for the assetBurn set `_ +.. [#zip-0226-txiddigest] `ZIP 226: Transfer and Burn of Zcash Shielded Assets — TxId Digest `_ +.. [#zip-0226-authcommitment] `ZIP 226: Transfer and Burn of Zcash Shielded Assets — Authorizing Data Commitment `_ +.. [#zip-0230-issuance-action-description] `ZIP 230: Version 6 Transaction Format — Issuance Action Description (IssueAction) `_ +.. [#zip-0230-issue-note] `ZIP 230: Version 6 Transaction Format — Issue Note Description (IssueNoteDescription) `_ +.. [#zip-0230-transaction-format] `ZIP 230: Version 6 Transaction Format — Transaction Format `_ +.. [#zip-0244] `ZIP 244: Transaction Identifier Non-Malleability `_ +.. [#zip-0246] `ZIP 246: Digests for the Version 6 Transaction Format `_ +.. [#zip-0317] `ZIP 317: Proportional Transfer Fee Mechanism `_ +.. [#zip-0317-fee-calculation] `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 2023.4.0. Section 2: Notation `_ -.. [#protocol-addressesandkeys] `Zcash Protocol Specification, Version 2023.4.0. Section 3.1: Payment Addresses and Keys `_ -.. [#protocol-orchardkeycomponents] `Zcash Protocol Specification, Version 2023.4.0. Section 4.2.3: Orchard Key Components `_ -.. [#protocol-concretegrouphashpallasandvesta] `Zcash Protocol Specification, Version 2023.4.0. Section 5.4.9.8: Group Hash into Pallas and Vesta `_ -.. [#protocol-orchardpaymentaddrencoding] `Zcash Protocol Specification, Version 2023.4.0. Section 5.6.4.2: Orchard Raw Payment Addresses `_ -.. [#protocol-txnencoding] `Zcash Protocol Specification, Version 2023.4.0. Section 7.1: Transaction Encoding and Consensus (Transaction Version 5) `_ +.. [#protocol] `Zcash Protocol Specification, Version 2025.6.2 [NU6.1] or later. `_ +.. [#protocol-notation] `Zcash Protocol Specification, Version 2025.6.2 [NU6.1]. Section 2: Notation `_ +.. [#protocol-notes] `Zcash Protocol Specification, Version 2025.6.2 [NU6.1]. Section 3.2: Notes `_ +.. [#protocol-abstractsig] `Zcash Protocol Specification, Version 2025.6.2 [NU6.1]. Section 4.1.7: Signature `_ +.. [#protocol-orchardkeycomponents] `Zcash Protocol Specification, Version 2025.6.2 [NU6.1]. Section 4.2.3: Orchard Key Components `_ +.. [#protocol-sighash] `Zcash Protocol Specification, Version 2025.6.2 [NU6.1]. Section 4.10: SIGHASH Transaction Hashing `_ +.. [#protocol-constants] `Zcash Protocol Specification, Version 2025.6.2 [NU6.1]. Section 5.3: Constants `_ +.. [#protocol-concreteprfs] `Zcash Protocol Specification, Version 2025.6.2 [NU6.1]. Section 5.4.2: Pseudo Random Functions `_ +.. [#protocol-concretegrouphashpallasandvesta] `Zcash Protocol Specification, Version 2025.6.2 [NU6.1]. Section 5.4.9.8: Group Hash into Pallas and Vesta `_ +.. [#protocol-orchardpaymentaddrencoding] `Zcash Protocol Specification, Version 2025.6.2 [NU6.1]. Section 5.6.4.2: Orchard Raw Payment Addresses `_ +.. [#protocol-txnencoding] `Zcash Protocol Specification, Version 2025.6.2 [NU6.1]. Section 7.1: Transaction Encoding and Consensus `_ +.. [#petnames] `An Introduction to Petname Systems. Marc Stiegler, updated June 2010. `_ diff --git a/zips/zip-0228.rst b/zips/zip-0228.rst index c1c19c70e..b43648fe4 100644 --- a/zips/zip-0228.rst +++ b/zips/zip-0228.rst @@ -4,8 +4,8 @@ Title: Asset Swaps for Zcash Shielded Assets Owners: Pablo Kogan Vivek Arte - Daira-Emma Hopwood - Jack Grigg + Daira-Emma Hopwood + Jack Grigg Credits: Daniel Benarroch Aurelien Nicolas Status: Reserved diff --git a/zips/zip-0230.rst b/zips/zip-0230.rst index a4f4b8b4a..e5c016b1e 100644 --- a/zips/zip-0230.rst +++ b/zips/zip-0230.rst @@ -1,17 +1,17 @@ :: ZIP: 230 - Title: Version 6 Transaction Format - Owners: Daira-Emma Hopwood - Jack Grigg - Sean Bowe - Kris Nuttycombe + Title: Withdrawn Version 6 Transaction Format + Owners: Daira-Emma Hopwood + Jack Grigg + Sean Bowe + Kris Nuttycombe Pablo Kogan Vivek Arte Original-Authors: Greg Pfeil Deirdre Connolly Credits: Ying Tong Lai - Status: Draft + Status: Withdrawn Category: Consensus Created: 2023-04-18 License: MIT @@ -24,6 +24,10 @@ Terminology The key words "MUST", "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 terms "Zcash Shielded Asset", "OrchardZSA", "ZSA" and "Asset" in this document are to be interpreted as described in ZIP 226 [#zip-0226]_. + +The term "Issuance" and "Issuance Action" in this document are to be interpreted as described in ZIP 227 [#zip-0227]_. + The character § is used when referring to sections of the Zcash Protocol Specification [#protocol]_. @@ -31,31 +35,34 @@ The character § is used when referring to sections of the Zcash Protocol Specif Abstract ======== -This proposal defines a new Zcash peer-to-peer transaction format, which includes -data that supports the Orchard-ZSA 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. +.. warning:: + This ZIP has been obsoleted by ZIP 248 [#zip-0248]_, and will not be deployed. Transaction + version number 6 is now defined by ZIP 248. -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 [#zip-0244]_. + Occurrences of the note plaintext lead byte constant it introduced (originally $\mathtt{0x03}$) + have been changed to "{{LEADBYTE}}", to clarify that this ZIP does not reserve that lead byte + value, and to avoid confusion with the different specification of lead byte $\mathtt{0x03}$ in + ZIP 2005 [#zip-2005]_. + +This proposal defines a new Zcash peer-to-peer transaction format, which supports the +changes being deployed in Network Upgrade 7 [#draft-arya-deploy-nu7]_. It follows the same design +pattern as the v5 transaction format [#zip-0225]_. Motivation ========== -The Orchard-ZSA protocol requires serialized data elements that are distinct from +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, +Thus, this ZIP defines a format that can easily accommodate future extensions, where elements or a given pool are kept separate. Requirements ============ -The new format must fully support the Orchard-ZSA protocol. +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. @@ -84,121 +91,113 @@ The Zcash transaction format for transaction version 6 is as follows: Transaction Format ------------------ -+------------------------------------+--------------------------+----------------------------------------+---------------------------------------------------------------------------+ -| Bytes | Name | Data Type | Description | -+====================================+==========================+========================================+===========================================================================+ -| **Common Transaction Fields** | -+------------------------------------+--------------------------+----------------------------------------+---------------------------------------------------------------------------+ -|``4`` |``header`` |``uint32`` |Contains: | -| | | | * ``fOverwintered`` flag (bit 31, always set) | -| | | | * ``version`` (bits 30 .. 0) – transaction version. | -+------------------------------------+--------------------------+----------------------------------------+---------------------------------------------------------------------------+ -|``4`` |``nVersionGroupId`` |``uint32`` |Version group ID (nonzero). | -+------------------------------------+--------------------------+----------------------------------------+---------------------------------------------------------------------------+ -|``4`` |``nConsensusBranchId`` |``uint32`` |Consensus branch ID (nonzero). | -+------------------------------------+--------------------------+----------------------------------------+---------------------------------------------------------------------------+ -|``4`` |``lock_time`` |``uint32`` |Unix-epoch UTC time or block height, encoded as in Bitcoin. | -+------------------------------------+--------------------------+----------------------------------------+---------------------------------------------------------------------------+ -|``4`` |``nExpiryHeight`` |``uint32`` |A block height in the range {1 .. 499999999} after which | -| | | |the transaction will expire, or 0 to disable expiry. | -| | | |[ZIP-203] | -+------------------------------------+--------------------------+----------------------------------------+---------------------------------------------------------------------------+ -|``8`` |``fee`` |``int64`` |The fee to be paid by this transaction, in zatoshis. | -+------------------------------------+--------------------------+----------------------------------------+---------------------------------------------------------------------------+ -| **Transparent Transaction Fields** | -+------------------------------------+--------------------------+----------------------------------------+---------------------------------------------------------------------------+ -|``varies`` |``tx_in_count`` |``compactSize`` |Number of transparent inputs in ``tx_in``. | -+------------------------------------+--------------------------+----------------------------------------+---------------------------------------------------------------------------+ -|``varies`` |``tx_in`` |``tx_in`` |Transparent inputs, encoded as in Bitcoin. | -+------------------------------------+--------------------------+----------------------------------------+---------------------------------------------------------------------------+ -|``varies`` |``tx_out_count`` |``compactSize`` |Number of transparent outputs in ``tx_out``. | -+------------------------------------+--------------------------+----------------------------------------+---------------------------------------------------------------------------+ -|``varies`` |``tx_out`` |``tx_out`` |Transparent outputs, encoded as in Bitcoin. | -+------------------------------------+--------------------------+----------------------------------------+---------------------------------------------------------------------------+ -| **Sapling Transaction Fields** | -+------------------------------------+--------------------------+----------------------------------------+---------------------------------------------------------------------------+ -|``varies`` |``nSpendsSapling`` |``compactSize`` |Number of Sapling Spend descriptions in ``vSpendsSapling``. | -+------------------------------------+--------------------------+----------------------------------------+---------------------------------------------------------------------------+ -|``96 * nSpendsSapling`` |``vSpendsSapling`` |``SpendDescriptionV6[nSpendsSapling]`` |A sequence of Sapling Spend descriptions, encoded per | -| | | |protocol §7.3 ‘Spend Description Encoding and Consensus’. | -+------------------------------------+--------------------------+----------------------------------------+---------------------------------------------------------------------------+ -|``varies`` |``nOutputsSapling`` |``compactSize`` |Number of Sapling Output Decriptions in ``vOutputsSapling``. | -+------------------------------------+--------------------------+----------------------------------------+---------------------------------------------------------------------------+ -|``756 * nOutputsSapling`` |``vOutputsSapling`` |``OutputDescriptionV6[nOutputsSapling]``|A sequence of Sapling Output descriptions, encoded per | -| | | |protocol §7.4 ‘Output Description Encoding and Consensus’. | -+------------------------------------+--------------------------+----------------------------------------+---------------------------------------------------------------------------+ -|``8`` |``valueBalanceSapling`` |``int64`` |The net value of Sapling Spends minus Outputs | -+------------------------------------+--------------------------+----------------------------------------+---------------------------------------------------------------------------+ -|``32`` |``anchorSapling`` |``byte[32]`` |A root of the Sapling note commitment tree | -| | | |at some block height in the past. | -+------------------------------------+--------------------------+----------------------------------------+---------------------------------------------------------------------------+ -|``192 * nSpendsSapling`` |``vSpendProofsSapling`` |``byte[192 * nSpendsSapling]`` |Encodings of the zk-SNARK proofs for each Sapling Spend. | -+------------------------------------+--------------------------+----------------------------------------+---------------------------------------------------------------------------+ -|``64 * nSpendsSapling`` |``vSpendAuthSigsSapling`` |``byte[64 * nSpendsSapling]`` |Authorizing signatures for each Sapling Spend. | -+------------------------------------+--------------------------+----------------------------------------+---------------------------------------------------------------------------+ -|``192 * nOutputsSapling`` |``vOutputProofsSapling`` |``byte[192 * nOutputsSapling]`` |Encodings of the zk-SNARK proofs for each Sapling Output. | -+------------------------------------+--------------------------+----------------------------------------+---------------------------------------------------------------------------+ -|``64`` |``bindingSigSapling`` |``byte[64]`` |A Sapling binding signature on the SIGHASH transaction hash. | -+------------------------------------+--------------------------+----------------------------------------+---------------------------------------------------------------------------+ -| **Orchard-ZSA Transaction Fields** | -+------------------------------------+--------------------------+----------------------------------------+---------------------------------------------------------------------------+ -|``varies`` |``nActionsOrchard`` |``compactSize`` |The number of Orchard-ZSA Action descriptions in | -| | | |``vActionsOrchard``. | -+------------------------------------+--------------------------+----------------------------------------+---------------------------------------------------------------------------+ -|``852 * nActionsOrchard`` |``vActionsOrchard`` |``OrchardZsaAction[nActionsOrchard]`` |A sequence of Orchard-ZSA Action descriptions, encoded per | -| | | |the `Orchard-ZSA Action Description Encoding`. | -+------------------------------------+--------------------------+----------------------------------------+---------------------------------------------------------------------------+ -|``1`` |``flagsOrchard`` |``byte`` |An 8-bit value representing a set of flags. Ordered from LSB to MSB: | -| | | | * ``enableSpendsOrchard`` | -| | | | * ``enableOutputsOrchard`` | -| | | | * ``enableZSAs`` | -| | | | * The remaining bits are set to :math:`0\!`. | -+------------------------------------+--------------------------+----------------------------------------+---------------------------------------------------------------------------+ -|``8`` |``valueBalanceOrchard`` |``int64`` |The net value of Orchard spends minus outputs. | -+------------------------------------+--------------------------+----------------------------------------+---------------------------------------------------------------------------+ -|``32`` |``anchorOrchard`` |``byte[32]`` |A root of the Orchard note commitment tree at some block | -| | | |height in the past. | -+------------------------------------+--------------------------+----------------------------------------+---------------------------------------------------------------------------+ -|``varies`` |``sizeProofsOrchardZSA`` |``compactSize`` |Length in bytes of ``proofsOrchardZSA``. Value is **(TO UPDATE)** | -| | | |:math:`2720 + 2272 \cdot \mathtt{nActionsOrchard}\!`. | -+------------------------------------+--------------------------+----------------------------------------+---------------------------------------------------------------------------+ -|``sizeProofsOrchardZSA`` |``proofsOrchardZSA`` |``byte[sizeProofsOrchardZSA]`` |Encoding of aggregated zk-SNARK proofs for Orchard-ZSA Actions. | -+------------------------------------+--------------------------+----------------------------------------+---------------------------------------------------------------------------+ -|``64 * nActionsOrchard`` |``vSpendAuthSigsOrchard`` |``byte[64 * nActionsOrchard]`` |Authorizing signatures for each Orchard-ZSA Action. | -+------------------------------------+--------------------------+----------------------------------------+---------------------------------------------------------------------------+ -|``64`` |``bindingSigOrchard`` |``byte[64]`` |An Orchard binding signature on the SIGHASH transaction hash. | -+------------------------------------+--------------------------+----------------------------------------+---------------------------------------------------------------------------+ -| **Orchard-ZSA Burn Fields** | -+------------------------------------+--------------------------+----------------------------------------+---------------------------------------------------------------------------+ -| ``varies`` | ``nAssetBurn`` | ``compactSize`` | The number of Assets burnt. | -+------------------------------------+--------------------------+----------------------------------------+---------------------------------------------------------------------------+ -| ``40 * nAssetBurn`` | ``vAssetBurn`` | ``AssetBurn[nAssetBurn]`` | A sequence of Asset Burn descriptions, | -| | | | encoded per `Orchard-ZSA Asset Burn Description`_. | -+------------------------------------+--------------------------+----------------------------------------+---------------------------------------------------------------------------+ -| **Orchard-ZSA Issuance Fields** | -+------------------------------------+--------------------------+----------------------------------------+---------------------------------------------------------------------------+ -|``varies`` |``nIssueActions`` |``compactSize`` |The number of issuance actions in the bundle. | -+------------------------------------+--------------------------+----------------------------------------+---------------------------------------------------------------------------+ -|``IssueActionSize * nIssueActions`` |``vIssueActions`` |``IssueAction[nIssueActions]`` |A sequence of issuance action descriptions, where IssueActionSize is | -| | | |the size, in bytes, of an IssueAction description. | -+------------------------------------+--------------------------+----------------------------------------+---------------------------------------------------------------------------+ -|``32`` |``ik`` |``byte[32]`` |The issuance validating key of the issuer, used to validate the signature. | -+------------------------------------+--------------------------+----------------------------------------+---------------------------------------------------------------------------+ -|``64`` |``issueAuthSig`` |``byte[64]`` |The signature of the transaction SIGHASH, signed by the issuer, | -| | | |validated as in Issuance Authorization Signature Scheme [#zip-0227]_. | -+------------------------------------+--------------------------+----------------------------------------+---------------------------------------------------------------------------+ ++-----------------------------+------------------------------+------------------------------------------------+---------------------------------------------------------------------+ +| Bytes | Name | Data Type | Description | ++=============================+==============================+================================================+=====================================================================+ +| **Common Transaction Fields** | ++-----------------------------+------------------------------+------------------------------------------------+---------------------------------------------------------------------+ +| 4 |``header`` |``uint32`` |Contains: | +| | | | | +| | | |* ``fOverwintered`` flag (bit 31, always set) | +| | | |* ``version`` (bits 30 .. 0) – transaction version. | ++-----------------------------+------------------------------+------------------------------------------------+---------------------------------------------------------------------+ +| 4 |``nVersionGroupId`` |``uint32`` |Version group ID (nonzero). | ++-----------------------------+------------------------------+------------------------------------------------+---------------------------------------------------------------------+ +| 4 |``nConsensusBranchId`` |``uint32`` |Consensus branch ID (nonzero). | ++-----------------------------+------------------------------+------------------------------------------------+---------------------------------------------------------------------+ +| 4 |``lock_time`` |``uint32`` |Unix-epoch UTC time or block height, encoded as in Bitcoin. | ++-----------------------------+------------------------------+------------------------------------------------+---------------------------------------------------------------------+ +| 4 |``nExpiryHeight`` |``uint32`` |A block height in the range {1 .. 499999999} after which | +| | | |the transaction will expire, or 0 to disable expiry. [#zip-0203]_ | ++-----------------------------+------------------------------+------------------------------------------------+---------------------------------------------------------------------+ +| 8 |``fee`` |``uint64`` |The fee to be paid by this transaction, in zatoshis. | ++-----------------------------+------------------------------+------------------------------------------------+---------------------------------------------------------------------+ +| 8 |``zip233Amount`` |``uint64`` |The value to be removed from circulation in this transaction, in | +| | | |zatoshis. [#zip-0233]_ | ++-----------------------------+------------------------------+------------------------------------------------+---------------------------------------------------------------------+ +| **Transparent Transaction Fields** | ++-----------------------------+------------------------------+------------------------------------------------+---------------------------------------------------------------------+ +| varies |``tx_in_count`` |``compactSize`` |Number of transparent inputs in ``tx_in``. | ++-----------------------------+------------------------------+------------------------------------------------+---------------------------------------------------------------------+ +| varies |``tx_in`` |``tx_in`` |Transparent inputs, encoded as in Bitcoin. | ++-----------------------------+------------------------------+------------------------------------------------+---------------------------------------------------------------------+ +| varies |``tx_out_count`` |``compactSize`` |Number of transparent outputs in ``tx_out``. | ++-----------------------------+------------------------------+------------------------------------------------+---------------------------------------------------------------------+ +| varies |``tx_out`` |``tx_out`` |Transparent outputs, encoded as in Bitcoin. | ++-----------------------------+------------------------------+------------------------------------------------+---------------------------------------------------------------------+ +| varies |``vSighashInfo`` |``TransparentSighashInfo[tx_in_count]`` |Sighash info for each transparent input. | ++-----------------------------+------------------------------+------------------------------------------------+---------------------------------------------------------------------+ +| **Sapling Transaction Fields** | ++-----------------------------+------------------------------+------------------------------------------------+---------------------------------------------------------------------+ +| varies |``nSpendsSapling`` |``compactSize`` |Number of Sapling Spend descriptions in ``vSpendsSapling``. | ++-----------------------------+------------------------------+------------------------------------------------+---------------------------------------------------------------------+ +| 96 × ``nSpendsSapling`` |``vSpendsSapling`` |``SpendDescriptionV5[nSpendsSapling]`` |A sequence of Sapling Spend descriptions, encoded per | +| | | |§7.3 ‘Spend Description Encoding and Consensus’ (unchanged from V5). | ++-----------------------------+------------------------------+------------------------------------------------+---------------------------------------------------------------------+ +| varies |``nOutputsSapling`` |``compactSize`` |Number of Sapling Output Decriptions in ``vOutputsSapling``. | ++-----------------------------+------------------------------+------------------------------------------------+---------------------------------------------------------------------+ +| 276 × ``nOutputsSapling`` |``vOutputsSapling`` |``OutputDescriptionV6[nOutputsSapling]`` |A sequence of Sapling Output descriptions, encoded per | +| | | |§7.4 ‘Output Description Encoding and Consensus’. | ++-----------------------------+------------------------------+------------------------------------------------+---------------------------------------------------------------------+ +| 8 |``valueBalanceSapling`` |``int64`` |The net value of Sapling Spends minus Outputs | ++-----------------------------+------------------------------+------------------------------------------------+---------------------------------------------------------------------+ +| 32 |``anchorSapling`` |``byte[32]`` |A root of the Sapling note commitment tree | +| | | |at some block height in the past. | ++-----------------------------+------------------------------+------------------------------------------------+---------------------------------------------------------------------+ +| 192 × ``nSpendsSapling`` |``vSpendProofsSapling`` |``byte[192 * nSpendsSapling]`` |Encodings of the zk-SNARK proofs for each Sapling Spend. | ++-----------------------------+------------------------------+------------------------------------------------+---------------------------------------------------------------------+ +| varies |``vSpendAuthSigsSapling`` |``SaplingSignature[nSpendsSapling]`` |Authorizing signatures for each Sapling Spend. | ++-----------------------------+------------------------------+------------------------------------------------+---------------------------------------------------------------------+ +| 192 × ``nOutputsSapling`` |``vOutputProofsSapling`` |``byte[192 * nOutputsSapling]`` |Encodings of the zk-SNARK proofs for each Sapling Output. | ++-----------------------------+------------------------------+------------------------------------------------+---------------------------------------------------------------------+ +| varies |``bindingSigSapling`` |``SaplingSignature`` |A Sapling binding signature on the SIGHASH transaction hash. | ++-----------------------------+------------------------------+------------------------------------------------+---------------------------------------------------------------------+ +| **Orchard Transaction Fields** | ++-----------------------------+------------------------------+------------------------------------------------+---------------------------------------------------------------------+ +| varies |``nActionGroupsOrchard`` |``compactSize`` |The number of Action Group descriptions in ``vActionGroupsOrchard``. | ++-----------------------------+------------------------------+------------------------------------------------+---------------------------------------------------------------------+ +| varies |``vActionGroupsOrchard`` |``ActionGroupDescription[nActionGroupsOrchard]``|A sequence of Action Group descriptions, encoded as per the | +| | | |`OrchardZSA Action Group Description`_. | ++-----------------------------+------------------------------+------------------------------------------------+---------------------------------------------------------------------+ +| 8 |``valueBalanceOrchard`` |``int64`` |The net value of Orchard spends minus outputs. | ++-----------------------------+------------------------------+------------------------------------------------+---------------------------------------------------------------------+ +| varies |``bindingSigOrchard`` |``OrchardSignature`` |An OrchardZSA binding signature on the SIGHASH transaction hash. | ++-----------------------------+------------------------------+------------------------------------------------+---------------------------------------------------------------------+ +| **ZSA Issuance Bundle Fields** | ++-----------------------------+------------------------------+------------------------------------------------+---------------------------------------------------------------------+ +| varies |``issuerLength`` |``compactSize`` |The length of the issuer identifier. | ++-----------------------------+------------------------------+------------------------------------------------+---------------------------------------------------------------------+ +| varies |``issuer`` |``byte[issuerLength]`` |The issuer identifier as defined in [#zip-0227-issuer-identifier]_. | ++-----------------------------+------------------------------+------------------------------------------------+---------------------------------------------------------------------+ +| varies |``nIssueActions`` |``compactSize`` |The number of issuance actions in the bundle. | ++-----------------------------+------------------------------+------------------------------------------------+---------------------------------------------------------------------+ +| varies |``vIssueActions`` |``IssueAction[nIssueActions]`` |A sequence of issuance action descriptions. | ++-----------------------------+------------------------------+------------------------------------------------+---------------------------------------------------------------------+ +| varies |``issueAuthSig`` |``IssueAuthSignature`` |The signature of the transaction SIGHASH, signed by the issuer, | +| | | |validated as in Issuance Authorization Signature Scheme | +| | | |[#zip-0227-issuance-auth-sig]_. | ++-----------------------------+------------------------------+------------------------------------------------+---------------------------------------------------------------------+ +| **Memo Bundle Fields** | ++-----------------------------+------------------------------+------------------------------------------------+---------------------------------------------------------------------+ +| 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[`` |Bitflags indicating the type of each entry in ``vMemoChunks``. | +| | |:math:`\mathsf{ceiling}(\mathtt{nMemoChunks}/8)`| | +| | |``]`` | | ++-----------------------------+------------------------------+------------------------------------------------+---------------------------------------------------------------------+ +| varies |``vMemoChunks`` |``MemoChunk[nMemoChunks]`` |A sequence of encrypted memo chunks [#zip-0231-memo-encryption]_. | ++-----------------------------+------------------------------+------------------------------------------------+---------------------------------------------------------------------+ * 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\!`. - -* The field ``anchorSapling`` is present if and only if :math:`\mathtt{nSpendsSapling} > 0\!`. + $\mathtt{nSpendsSapling} + \mathtt{nOutputsSapling} > 0$. If ``valueBalanceSapling`` + is not present, then $\mathsf{v^{balanceSapling}}$ is defined to be $0$. -* The fields ``flagsOrchard``, ``valueBalanceOrchard``, ``anchorOrchard``, - ``sizeProofsOrchardZSA``, ``proofsOrchardZSA``, 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 :math:`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 @@ -209,129 +208,486 @@ Transaction Format ``vOutputsSapling`` and MUST be ordered such that the proof at a given index corresponds to the ``OutputDescriptionV6`` at the same index. +* The fields ``valueBalanceOrchard`` and ``bindingSigOrchard`` are present if and + only if $\mathtt{nActionGroupsOrchard} > 0$. If ``valueBalanceOrchard`` is not present, + then $\mathsf{v^{balanceOrchard}}$ is defined to be $0$. + +* The fields ``issueAuthSigLength`` and ``issueAuthSig`` are present if and only if $\mathtt{nIssueActions} > 0$. + The fields ``issuerLength``, ``issuer``, ``nIssueActions``, and ``vIssueActions`` are always present. + If $\mathtt{nIssueActions} = 0$ then ``issuerLength`` MUST be set to $0$ (``issuer`` and ``vIssueActions`` will be empty in this case). + +* For coinbase transactions, the ``enableSpendsOrchard`` and ``enableZSAs`` bits MUST be set to $0$. + +* The fields ``nMemoChunks``, ``pruned``, and ``vMemoChunks`` are present if and only if + ``fAllPruned == 0``. + +* If ``fAllPruned == 0``, then: + + * ``nonceOrHash`` contains the ZIP 231 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 ZIP 246 + ``memo_chunk_digest`` for a pruned chunk. + +* If ``fAllPruned == 1``, then: + + * ``nonceOrHash`` contains the ZIP 246 ``memo_digest`` for the pruned memo bundle. + +The encodings of ``tx_in``, and ``tx_out`` are as in prior transaction versions (i.e. +unchanged since Zcash launch). [#protocol-txnencoding]_ [#zip-0225-transaction-format]_ + +The encodings of ``SpendDescriptionV6``, ``OutputDescriptionV6``, ``ActionGroupDescription``, +``AssetBurn`` and ``IssueAction`` 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. + +Sapling Output Description (``OutputDescriptionV6``) +---------------------------------------------------- + ++-----------------------------+------------------------------+------------------------------------------------+---------------------------------------------------------------------+ +| 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. | ++-----------------------------+------------------------------+------------------------------------------------+---------------------------------------------------------------------+ +| 100 |``encCiphertext`` |``byte[100]`` |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’ [#protocol-outputdesc]_. + +OrchardZSA Action Group Description +----------------------------------- + +The OrchardZSA Action Group Description is encoded in a transaction as an instance of an ``ActionGroupDescription`` type: + ++-----------------------------+------------------------------+------------------------------------------------+---------------------------------------------------------------------+ +| Bytes | Name | Data Type | Description | ++=============================+==============================+================================================+=====================================================================+ +| varies |``nActionsOrchard`` |``compactSize`` |The number of Action descriptions in ``vActionsOrchard``. | +| | | |This MUST have a value strictly greater than ``0``. | ++-----------------------------+------------------------------+------------------------------------------------+---------------------------------------------------------------------+ +| 372 × ``nActionsOrchard`` |``vActionsOrchard`` |``OrchardZSAAction[nActionsOrchard]`` |A sequence of OrchardZSA Action descriptions in the Action Group. | ++-----------------------------+------------------------------+------------------------------------------------+---------------------------------------------------------------------+ +|``1`` |``flagsOrchard`` |``byte`` |An 8-bit value representing a set of flags. Ordered from LSB to MSB: | +| | | | * ``enableSpendsOrchard`` | +| | | | * ``enableOutputsOrchard`` | +| | | | * ``enableZSAs`` | +| | | | * The remaining bits are set to :math:`0\!`. | ++-----------------------------+------------------------------+------------------------------------------------+---------------------------------------------------------------------+ +| 32 |``anchorOrchard`` |``byte[32]`` |As defined in §7.1 ‘Transaction Encoding and Consensus’ | +| | | |[#protocol-txnencoding]_. | ++-----------------------------+------------------------------+------------------------------------------------+---------------------------------------------------------------------+ +| 4 |``nAGExpiryHeight`` |``uint32`` |A block height in the range {1 .. 499999999} after which any | +| | | |transaction including this Action Group cannot be mined, or 0 if | +| | | |this Action Group places no constraint on transaction expiry. | ++-----------------------------+------------------------------+------------------------------------------------+---------------------------------------------------------------------+ +| varies | ``nAssetBurn`` | ``compactSize`` |The number of Assets burnt. | ++-----------------------------+------------------------------+------------------------------------------------+---------------------------------------------------------------------+ +| 40 × ``nAssetBurn`` | ``vAssetBurn`` | ``AssetBurn[nAssetBurn]`` |A sequence of Asset Burn descriptions, encoded per | +| | | |`OrchardZSA Asset Burn Description`_. | ++-----------------------------+------------------------------+------------------------------------------------+---------------------------------------------------------------------+ +| varies |``sizeProofsOrchard`` |``compactSize`` |As defined in §7.1 ‘Transaction Encoding and Consensus’ | +| | | |[#protocol-txnencoding]_. | ++-----------------------------+------------------------------+------------------------------------------------+---------------------------------------------------------------------+ +| ``sizeProofsOrchard`` |``proofsOrchard`` |``byte[sizeProofsOrchard]`` |The aggregated zk-SNARK proof for all Actions in the Action Group. | ++-----------------------------+------------------------------+------------------------------------------------+---------------------------------------------------------------------+ +| varies |``vSpendAuthSigsOrchard`` |``OrchardSignature[nActionsOrchard]`` |Authorizing signatures for each Action of the Action Group in a | +| | | |transaction. | ++-----------------------------+------------------------------+------------------------------------------------+---------------------------------------------------------------------+ + +The encodings of ``OrchardZSAAction`` and ``AssetBurn`` are described below. + * The proofs aggregated in ``proofsOrchardZSA``, 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 ``OrchardZsaAction`` at the same index. - -* For coinbase transactions, the ``enableSpendsOrchard`` and ``enableZSAs`` bits MUST be set to :math:`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`` -, ``OrchardZsaAction``, ``AssetBurn`` and ``IssueAction`` 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. - -Sapling Spend Description (``SpendDescriptionV6``) --------------------------------------------------- - -+-----------------------------+--------------------------+--------------------------------------+------------------------------------------------------------+ -| Bytes | Name | Data Type | Description | -+=============================+==========================+======================================+============================================================+ -|``32`` |``cv`` |``byte[32]`` |A value commitment to the net value of the input note. | -+-----------------------------+--------------------------+--------------------------------------+------------------------------------------------------------+ -|``32`` |``nullifier`` |``byte[32]`` |The nullifier of the input note. | -+-----------------------------+--------------------------+--------------------------------------+------------------------------------------------------------+ -|``32`` |``rk`` |``byte[32]`` |The randomized validating key for the element of | -| | | |spendAuthSigsSapling corresponding to this Spend. | -+-----------------------------+--------------------------+--------------------------------------+------------------------------------------------------------+ - -The encodings of each of these elements are defined in §7.3 ‘Spend Description Encoding -and Consensus’ of the Zcash Protocol Specification [#protocol-spenddesc]_. + index corresponds to the ``OrchardZSAAction`` at the same index. +* If the value of ``nAGExpiryHeight`` is nonzero, it MUST be consistent with + the ``nExpiryHeight`` of the overall transaction. +* In NU7, ``nExpiryHeight`` MUST be set to ``0``; this restriction is expected + to be lifted in a future network upgrade. -Sapling Output Description (``OutputDescriptionV6``) +Rationale for nAGExpiryHeight +````````````````````````````` + +We introduce the ``nAGExpiryHeight`` field in this transaction format in order to be forward compatible with Swaps over ZSAs, as proposed in ZIP 228 [#zip-0228]_. +For the OrchardZSA protocol, which does not make use of an additional expiry height for transactions, we set the value of ``nAGExpiryHeight`` to be ``0`` by consensus. +This serves as a default value to represent the situation where there is no expiry, analogous to the convention adopted for ``nExpiryHeight`` in ZIP 203 [#zip-0203]. + +Rationale for including Burn fields inside OrchardZSA Action Groups +``````````````````````````````````````````````````````````````````` + +Note that the v6 transaction format includes the burn fields of the transaction inside the OrchardZSA Action Group rather than at the transaction level. +This is a design choice that considers the future scenario where Action Groups may be generated by different parties before being bundled together into a transaction. +In such a scenario, the individual parties can burn Assets of their choice in their corresponding Action Groups. +Maintaining the burn fields at the transaction level would provide the ability to burn Assets only to the party performing the bundling of the Action Groups. + + +OrchardZSA Action Description (``OrchardZSAAction``) ---------------------------------------------------- -+-----------------------------+--------------------------+--------------------------------------+------------------------------------------------------------+ -| 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]_. - -Orchard-ZSA Action Description (``OrchardZsaAction``) ------------------------------------------------------ - -+-----------------------------+--------------------------+--------------------------------------+------------------------------------------------------------+ -| 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 | -+-----------------------------+--------------------------+--------------------------------------+------------------------------------------------------------+ -|``612`` |``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]_. - -Orchard-ZSA Asset Burn Description ++-----------------------------+------------------------------+------------------------------------------------+---------------------------------------------------------------------+ +| 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. | ++-----------------------------+------------------------------+------------------------------------------------+---------------------------------------------------------------------+ +| 132 |``encCiphertext`` |``byte[132]`` |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’ [#protocol-actiondesc]_. + +OrchardZSA Asset Burn Description ---------------------------------- -An Orchard-ZSA Asset Burn description is encoded in a transaction as an instance of an ``AssetBurn`` type: - -+-------+---------------+-----------------------------+--------------------------------------------------------------------------------------------------------------------+ -| Bytes | Name | Data Type | Description | -+=======+===============+=============================+====================================================================================================================+ -| 32 | ``AssetBase`` | ``byte[32]`` | For the Orchard-based ZSA protocol, this is the encoding of the Asset Base :math:`\mathsf{AssetBase^{Orchard}}\!`. | -+-------+---------------+-----------------------------+--------------------------------------------------------------------------------------------------------------------+ -| 8 | ``valueBurn`` | :math:`\{1 .. 2^{64} - 1\}` | The amount being burnt. | -+-------+---------------+-----------------------------+--------------------------------------------------------------------------------------------------------------------+ +An OrchardZSA Asset Burn description is encoded in a transaction as an instance of an ``AssetBurn`` type: + ++-----------------------------+------------------------------+------------------------------------------------+---------------------------------------------------------------------+ +| Bytes | Name | Data Type | Description | ++=============================+==============================+================================================+=====================================================================+ +| 32 |``AssetBase`` |``byte[32]`` |For the OrchardZSA protocol, this is the encoding of the Asset Base | +| | | |:math:`\mathsf{AssetBase^{Orchard}}\!`. | ++-----------------------------+------------------------------+------------------------------------------------+---------------------------------------------------------------------+ +| 8 |``valueBurn`` |``uint64`` |The amount being burnt. The value is checked by consensus to be | +| | | |non-zero, and less than :math:`\mathsf{MAX\_BURN\_VALUE}` | +| | | |[#zip-0226-burn-mechanism]_. | ++-----------------------------+------------------------------+------------------------------------------------+---------------------------------------------------------------------+ + +The encodings of each of these elements are defined in ZIP 226 [#zip-0226-burn-mechanism]_. + +Transparent Sighash Information (``TransparentSighashInfo``) +------------------------------------------------------------ + ++-----------------------------+------------------------------+------------------------------------------------+---------------------------------------------------------------------+ +| Bytes | Name | Data Type | Description | ++=============================+==============================+================================================+=====================================================================+ +| varies |``sizeSighashInfo`` |``compactSize`` |The size in bytes of `sighashInfo`. | ++-----------------------------+------------------------------+------------------------------------------------+---------------------------------------------------------------------+ +| ``sizeSighashInfo`` |``sighashInfo`` |``byte[sizeSighashInfo]`` |The sighash version and associated information | +| | | |[#zip-0246-sighash-info]_. | ++-----------------------------+------------------------------+------------------------------------------------+---------------------------------------------------------------------+ + +Sapling Signature (``SaplingSignature``) +---------------------------------------- + ++-----------------------------+------------------------------+------------------------------------------------+---------------------------------------------------------------------+ +| Bytes | Name | Data Type | Description | ++=============================+==============================+================================================+=====================================================================+ +| varies |``sizeSighashInfo`` |``compactSize`` |The size in bytes of `sighashInfo`. | ++-----------------------------+------------------------------+------------------------------------------------+---------------------------------------------------------------------+ +| ``sizeSighashInfo`` |``sighashInfo`` |``byte[sizeSighashInfo]`` |The sighash version and associated information | +| | | |[#zip-0246-sighash-info]_. | ++-----------------------------+------------------------------+------------------------------------------------+---------------------------------------------------------------------+ +| 64 |``signature`` |``byte[64]`` |An encoding of a RedJubjub signature, which may be either a | +| | | |``spendAuthSig`` or ``bindingSig`` depending on context. | ++-----------------------------+------------------------------+------------------------------------------------+---------------------------------------------------------------------+ + +Orchard Signature (``OrchardSignature``) +---------------------------------------- + ++-----------------------------+------------------------------+------------------------------------------------+---------------------------------------------------------------------+ +| Bytes | Name | Data Type | Description | ++=============================+==============================+================================================+=====================================================================+ +| varies |``sizeSighashInfo`` |``compactSize`` |The size in bytes of `sighashInfo`. | ++-----------------------------+------------------------------+------------------------------------------------+---------------------------------------------------------------------+ +| ``sizeSighashInfo`` |``sighashInfo`` |``byte[sizeSighashInfo]`` |The sighash version and associated information | +| | | |[#zip-0246-sighash-info]_. | ++-----------------------------+------------------------------+------------------------------------------------+---------------------------------------------------------------------+ +| 64 |``signature`` |``byte[64]`` |An encoding of a RedPallas signature, which may be either a | +| | | |``spendAuthSig`` or ``bindingSig`` depending on context. | ++-----------------------------+------------------------------+------------------------------------------------+---------------------------------------------------------------------+ + +Issuance Authorization Signature (``IssueAuthSignature``) +--------------------------------------------------------- + ++-----------------------------+------------------------------+------------------------------------------------+---------------------------------------------------------------------+ +| Bytes | Name | Data Type | Description | ++=============================+==============================+================================================+=====================================================================+ +| varies |``sizeSighashInfo`` |``compactSize`` |The size in bytes of `sighashInfo`. | ++-----------------------------+------------------------------+------------------------------------------------+---------------------------------------------------------------------+ +| ``sizeSighashInfo`` |``sighashInfo`` |``byte[sizeSighashInfo]`` |The sighash version and associated information | +| | | |[#zip-0246-sighash-info]_. | ++-----------------------------+------------------------------+------------------------------------------------+---------------------------------------------------------------------+ +| varies |``sizeSignature`` |``compactSize`` |The size in bytes of `signature`. | ++-----------------------------+------------------------------+------------------------------------------------+---------------------------------------------------------------------+ +| varies |``signature`` |``byte[sizeSignature]`` |The signature of the transaction SIGHASH, signed by the issuer, | +| | | |preceded by a ``0x00`` byte indicating a BIP 340 signature. It is | +| | | |validated as specified in [#zip-0227-issuance-auth-sig]_. | ++-----------------------------+------------------------------+------------------------------------------------+---------------------------------------------------------------------+ -The encodings of each of these elements are defined in ZIP 226 [#zip-0226]_. Issuance Action Description (``IssueAction``) --------------------------------------------- An issuance action, ``IssueAction``, is the instance of issuing a specific Custom Asset, and contains the following fields: -+-----------------------------+--------------------------+-------------------------------------------+---------------------------------------------------------------------+ -| Bytes | Name | Data Type | Description | -+=============================+==========================+===========================================+=====================================================================+ -|``2`` |``assetDescSize`` |``byte`` |The length of the asset description string in bytes. | -+-----------------------------+--------------------------+-------------------------------------------+---------------------------------------------------------------------+ -|``assetDescSize`` |``asset_desc`` |``byte[assetDescSize]`` |A byte sequence of length ``assetDescSize`` bytes which SHOULD be a | -| | | |well-formed UTF-8 code unit sequence according to Unicode 15.0.0 | -| | | |or later. | -+-----------------------------+--------------------------+-------------------------------------------+---------------------------------------------------------------------+ -|``varies`` |``nNotes`` |``compactSize`` |The number of notes in the issuance action. | -+-----------------------------+--------------------------+-------------------------------------------+---------------------------------------------------------------------+ -|``noteSize * nNotes`` |``vNotes`` |``Note[nNotes]`` |A sequence of note descriptions within the issuance action, | -| | | |where ``noteSize`` is the size, in bytes, of a Note. | -+-----------------------------+--------------------------+-------------------------------------------+---------------------------------------------------------------------+ -|``1`` |``flagsIssuance`` |``byte`` |An 8-bit value representing a set of flags. Ordered from LSB to MSB: | -| | | | * :math:`\mathsf{finalize}` | -| | | | * The remaining bits are set to :math:`0\!`. | -+-----------------------------+--------------------------+-------------------------------------------+---------------------------------------------------------------------+ - -The encodings of each of these elements are defined in ZIP 227 [#zip-0227]_. ++-----------------------------+------------------------------+------------------------------------------------+---------------------------------------------------------------------+ +| Bytes | Name | Data Type | Description | ++=============================+==============================+================================================+=====================================================================+ +| 32 |``assetDescHash`` |``byte[32]`` |A hash of the description of the Custom Asset. | ++-----------------------------+------------------------------+------------------------------------------------+---------------------------------------------------------------------+ +| varies |``nNotes`` |``compactSize`` |The number of notes in the Issuance Action. | ++-----------------------------+------------------------------+------------------------------------------------+---------------------------------------------------------------------+ +| 115 × ``nNotes`` |``vNotes`` |``IssueNoteDescription[nNotes]`` |A sequence of issue note descriptions within the Issuance Action. | ++-----------------------------+------------------------------+------------------------------------------------+---------------------------------------------------------------------+ +| 1 |``flagsIssuance`` |``byte`` |An 8-bit value representing a set of flags. Ordered from LSB to MSB: | +| | | | | +| | | |* :math:`\mathsf{finalize}` | +| | | |* The remaining bits are set to :math:`0\!`. | ++-----------------------------+------------------------------+------------------------------------------------+---------------------------------------------------------------------+ + +The encoding of ``IssueNoteDescription`` is described below. +Note that we allow the number of notes (represented by ``nNotes``) to be zero. +This allows for issuers to create Issuance Actions to only finalize an issued Asset, without needing them to simultaneously issue more of that Asset. + +Issue Note Description (``IssueNoteDescription``) +------------------------------------------------- + +An issuance note description, ``IssueNoteDescription`` contains the following fields: + ++-----------------------------+------------------------------+------------------------------------------------+---------------------------------------------------------------------+ +| Bytes | Name | Data Type | Description | ++=============================+==============================+================================================+=====================================================================+ +| 43 |``recipient`` |``byte[43]`` |The encoding of a recipient's diversified payment address, as | +| | | |:math:`\mathsf{LEBS2OSP}_{88}(\mathsf{d})\| | +| | | |\mathsf{LEBS2OSP}_{256}(\mathsf{repr}_{\mathbb{P}} | +| | | |(\mathsf{pk}_\mathsf{d}))\!`, where :math:`\mathsf{d}` is the | +| | | |diversifier and :math:`\mathsf{pk_d}` is the diversified | +| | | |transmission key. **Non Normative Note**: This is the same as the | +| | | |encoding of an Orchard Raw Payment Address, as defined in | +| | | |§5.6.4.2 ‘Orchard Raw Payment Addresses’. | ++-----------------------------+------------------------------+------------------------------------------------+---------------------------------------------------------------------+ +| 8 |``value`` |``uint64`` |The amount being issued in this note. | ++-----------------------------+------------------------------+------------------------------------------------+---------------------------------------------------------------------+ +| 32 |``rho`` |``byte[32]`` |This is defined and encoded in the same manner as for Orchard notes | +| | | |in §3.2.1 ‘Note Plaintexts and Memo Fields’. | ++-----------------------------+------------------------------+------------------------------------------------+---------------------------------------------------------------------+ +| 32 |``rseed`` |``byte[32]`` |The ``rseed`` field of the note, encoded as for Orchard notes in | +| | | |§3.2.1 ‘Note Plaintexts and Memo Fields’. | ++-----------------------------+------------------------------+------------------------------------------------+---------------------------------------------------------------------+ + +Note Plaintexts +--------------- + +New note plaintext formats using lead byte {{LEADBYTE}} are introduced for +Sapling and Orchard, in order to support memo bundles and (for Orchard) ZSAs and +quantum recoverability. + +The $\mathsf{leadByte}$ MUST be {{LEADBYTE}} for all note plaintexts in v6 +transactions. + +Sapling Note Plaintext +`````````````````````` + +In order to accommodate the change needed for memo bundles +[#zip-0231-memo-encryption]_, a v6-onward Sapling note plaintext must include a +32-byte memo key $\mathsf{K^{memo}} : \mathbb{B}^{\mathbb{Y}[32]$, rather than a +512-byte plaintext memo. + +The corresponding changes to the Zcash Protocol Specification are specified in +[#zip-0231-sapling-note-plaintext]_. + +The encoding of a v6-onward Sapling note plaintext in +§ 5.5 ‘Encodings of Note Plaintexts and Memo Fields’ [#protocol-noteptencoding]_ +is similarly updated and is now defined as: + +.. math:: [\mathsf{leadByte}] \,||\, \mathsf{LEBS2OSP}_{88}(\mathsf{d}) \,||\, \mathsf{I2LEOSP}_{64}(\mathsf{v}) \,||\, \mathsf{rseed} \,||\, \mathsf{K^{memo}} + +Orchard Note Plaintext +`````````````````````` + +As well as the same change to accommodate memo bundles as above, OrchardZSA +notes have an additional $\mathsf{AssetBase}$ field, which needs to be included +(as its byte sequence encoding $\mathsf{asset\_base}$) in a v6-onward Orchard +note plaintext. + +Let $\mathcal{V}^{\mathsf{Orchard}}$ be as defined in +§ 5.4.8.3 ‘Homomorphic Pedersen commitments (Sapling and Orchard)’ +[#protocol-concretehomomorphiccommit]_. + +An Orchard note is essentially equivalent to an OrchardZSA note with +$\mathsf{AssetBase} = \mathcal{V}^{\mathsf{Orchard}}$; in particular, they have +the same note commitment (as defined in [#zip-0226-note-structure-and-commitment]_), +and need not be distinguished in note plaintexts. + +Each v6-onward Orchard note plaintext consists of + +.. math:: (\mathsf{leadByte} : \mathbb{B}^{\mathbb{Y}}, \mathsf{d} : \mathbb{B}^{[\ell_{\mathsf{d}}]}, \mathsf{v} : \{0 .. 2^{\ell_{\mathsf{value}}} - 1\}, \mathsf{rseed} : \mathbb{B}^{\mathbb{Y}[32]}, \mathsf{asset\_base} : \mathbb{B}^{\mathbb{Y}[\ell_{\mathbb{P}}/8]}, \mathsf{K^{memo}} : \mathbb{B}^{\mathbb{Y}[32]}) + +where (consistent with [#zip-0226-note-structure-and-commitment]_) $\mathsf{asset\_base}$ +is $\mathsf{LEBS2OSP}_{\ell_{\mathbb{P}}}(\mathsf{repr}_{\mathbb{P}}(\mathsf{AssetBase}))$. + +The encoding of a v6-onward Orchard note plaintext in +§ 5.5 ‘Encodings of Note Plaintexts and Memo Fields’ [#protocol-noteptencoding]_ +is similarly updated and is now defined as: + +.. math:: [\mathsf{leadByte}] \,||\, \mathsf{LEBS2OSP}_{88}(\mathsf{d}) \,||\, \mathsf{I2LEOSP}_{64}(\mathsf{v}) \,||\, \mathsf{rseed} \,||\, \mathsf{asset\_base} \,||\, \mathsf{K^{memo}} + +The encodings of $\mathsf{d}$, $\mathsf{v}$, and $\mathsf{rseed}$ remain unchanged from the previous specification in §5.5 ‘Encodings of Note Plaintexts and Memo Fields’ of the Zcash Protocol Specification [#protocol-noteptencoding]_. + +Non-normative note: The *use* of the $\mathsf{rseed}$ in Orchard note decryption +changes, but its type and encoding do not. + +Rationale for requiring the lead byte to be {{LEADBYTE}} in v6 +`````````````````````````````````````````````````````````````` + +It was decided to synchronize the changes to note encryption required for +quantum recoverability, ZSA support, and memo bundles with a change to the +transaction format, for two reasons: + +* This was necessary because the note ciphertexts must be a different size to + those in v5 transactions — to accommodate the ZSA $\mathsf{AssetBase}$ field + for Orchard, and due to changing the 512-byte $\mathsf{memo}$ field to a + 32-byte $\mathsf{K^{memo}}$ field for both Sapling and Orchard. In fact the + latter change makes it impossible to retain the lead-byte $\mathtt{0x02}$ + format unchanged, because the note ciphertext is not large enough (in either + Sapling or Orchard outputs) for a 512-byte memo. + +* The quantum recoverability change did not necessarily have to be done at the + same time as the ZSA and memo bundle changes. However, it would have + significantly increased overall protocol complexity for there to be a separate + note plaintext format for quantum-recoverable notes. Also, doing it at the + same time minimizes the risk that non-conformant wallets would create outputs + after this change that could not be successfully decrypted by conformant + wallets. That could potentially result in inaccessible funds, as was observed + with the previous note plaintext change at the Canopy upgrade [#zip-0212]_. + (As noted above, it is still possible for funds to be temporarily stuck if a + *receiving* wallet does not fully support v6 transactions, but this is less + problematic because upgrading the wallet will unstick them.) + +Although the ZSA and quantum recoverability-related note plaintext changes do +not apply to Sapling, the change from $\mathsf{memo}$ to $\mathsf{K^{memo}}$ +justifies changing the lead byte for both Sapling and Orchard. + +Implications for Mining +----------------------- + +ZIP 235 [#zip-0235]_ requires that from activation of that ZIP, which is +scheduled for NU7, all coinbase transactions created by miners and mining pools +are v6 transactions. + +The specification of the Stratum protocol in [#zip-0301]_ does not need any +updates for v6 transactions, but implementations might need to be updated. + +Implications for Wallets +------------------------ + +Sending v6 transactions +``````````````````````` + +*All* Zcash wallets SHOULD, without undue delay, switch to sending only v6 +transactions once they are allowed on the network. This applies to all +transactions regardless of whether they transact in native or non-native assets, +or whether they use other v6 features. + +Rationale for sending v6 transactions +````````````````````````````````````` + +.. raw:: html + +
    + Click to show/hide + +This obtains the maximum possible privacy for the wallet's users, maximizes the +overall rate of increase of the anonymity set of OrchardZSA commitments, and +ensures that users' funds are quantum-recoverable. + +Because v5 transactions cannot spend or create non-native assets, a wallet using +Orchard with v5 transactions is revealing more information than a wallet using +it with v6 transactions — i.e. that all of the Orchard notes spent and output by +those transactions are ZEC. + +Only OrchardZSA outputs of v6 transactions are quantum-recoverable, as described +and motivated in [#zip-2005]_. + +Finally, if wallets continue to send v5 transactions then users will not benefit +from other v6 transaction features, such as the larger memo sizes enabled by +memo bundles [#zip-0231-motivation]_, or the benefits of making the fee field +explicit [#zip-2002-motivation]_. + +.. raw:: html + +
    + +Support for receiving funds in v6 transactions +`````````````````````````````````````````````` + +Zcash wallets MUST support parsing and processing v6 transactions by the time +they are allowed on the network (scheduled for NU7 activation). This includes +detecting and decrypting lead-byte {{LEADBYTE}} note plaintexts and memo +bundles. + +The necessary changes to note decryption are specified in ZIP 231 [#zip-0231]_, +ZIP 226 [#zip-0226-orchardzsa-transaction-structure]_, and ZIP 2005 [#zip-2005]_ +(which defines the necessary changes to the Zcash protocol specification). +Note that the changes arising from [#zip-0231]_ apply also to Sapling outputs. + +In the event that a wallet implementation, contrary to the above requirement, +does not support decrypting outputs of v6 transactions (or some subset of them) +immediately once they are allowed on the network, it MUST rescan those outputs +once that support is added. + +Rationale for being ready to receive v6 transactions at their activation +```````````````````````````````````````````````````````````````````````` + +Note plaintexts with lead byte {{LEADBYTE}}, which are required for Orchard +notes in v6 transactions, can be sent to any Orchard address. + +These notes use a different computation of $\mathsf{rcm}$ and $\text{ψ}$ from +$\mathsf{rseed}$, which is necessary in order to achieve quantum recoverability +as explained in [#zip-2005-security-analysis]_. They also have a new +$\mathsf{AssetBase}$ field used to support ZSAs. Therefore, they cannot be +validated or spent without making *all* of the specified changes. A wallet +attempting to non-conformantly use the note decryption algorithm for lead byte +$\mathtt{0x02}$ would compute a different note commitment $\mathsf{cm}_x$ and +would reject the note. + +If wallets do not support v6 transactions and lead-byte {{LEADBYTE}} note +decryption immediately, then funds may be sent to them that they cannot receive. +This affects both the existing Orchard functionality, and receiving non-native +ZSA assets. + +This situation is different from previous upgrades that introduced a new +shielded pool, such as the Sapling and NU5 upgrades, because in those cases the +new pool used an entirely new address type, and existing wallets would not have +given out addresses of those types. + +Furthermore, as described in [Sending v6 transactions]_, other wallets can be +expected to immediately start sending v6 transactions as soon as they are +allowed, and so *all* wallets need to be ready to receive them at that point. + +Deployment +========== + +Version 6 transactions are proposed to be allowed on the network starting from +Network Upgrade 7. [#draft-arya-deploy-nu7]_ Reference implementation ======================== @@ -343,10 +699,35 @@ 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 2023.4.0 or later [NU5 proposal] `_ -.. [#protocol-spenddesc] `Zcash Protocol Specification, Version 2023.4.0 [NU5 proposal]. Section 4.4: Spend Descriptions `_ -.. [#protocol-outputdesc] `Zcash Protocol Specification, Version 2023.4.0 [NU5 proposal]. Section 4.5: Output Descriptions `_ -.. [#protocol-actiondesc] `Zcash Protocol Specification, Version 2023.4.0 [NU5 proposal]. Section 4.6: Action Descriptions `_ -.. [#zip-0226] `ZIP 226: Transfer and Burn of Zcash Shielded Assets `_ -.. [#zip-0227] `ZIP 227: Issuance of Zcash Shielded Assets `_ +.. [#protocol] `Zcash Protocol Specification, Version 2025.6.2 or later [NU6.1] `_ +.. [#protocol-spenddesc] `Zcash Protocol Specification, Version 2025.6.2 [NU6.1]. Section 4.4: Spend Descriptions `_ +.. [#protocol-outputdesc] `Zcash Protocol Specification, Version 2025.6.2 [NU6.1]. Section 4.5: Output Descriptions `_ +.. [#protocol-actiondesc] `Zcash Protocol Specification, Version 2025.6.2 [NU6.1]. Section 4.6: Action Descriptions `_ +.. [#protocol-concretehomomorphiccommit] `Zcash Protocol Specification, Version 2025.6.2 [NU6.1]. Section 5.4.8.3: Homomorphic Pedersen commitments (Sapling and Orchard) `_ +.. [#protocol-noteptencoding] `Zcash Protocol Specification, Version 2025.6.2 [NU6.1]. Section 5.5: Encodings of Note Plaintexts and Memo Fields `_ +.. [#protocol-txnencoding] `Zcash Protocol Specification, Version 2025.6.2 [NU6.1]. Section 7.1: Transaction Encoding and Consensus `_ +.. [#zip-0203] `ZIP 203: Transaction Expiry `_ +.. [#zip-0212] `ZIP 212: Allow Recipient to Derive Ephemeral Secret from Note Plaintext `_ +.. [#zip-0225] `ZIP 225: Version 5 Transaction Format `_ +.. [#zip-0225-transaction-format] `ZIP 225: Version 5 Transaction Format. Specification: Transaction Format `_ +.. [#zip-0226] `ZIP 226: Transfer and Burn of Zcash Shielded Assets `_ +.. [#zip-0226-burn-mechanism] `ZIP 226: Transfer and Burn of Zcash Shielded Assets - Burn Mechanism `_ +.. [#zip-0226-orchardzsa-transaction-structure] `ZIP 226: Transfer and Burn of Zcash Shielded Assets — OrchardZSA Transaction Structure `_ +.. [#zip-0226-note-structure-and-commitment] `ZIP 226: Transfer and Burn of Zcash Shielded Assets — Note Structure and Commitment `_ +.. [#zip-0227] `ZIP 227: Issuance of Zcash Shielded Assets `_ +.. [#zip-0227-issuance-auth-sig] `ZIP 227: Issuance of Zcash Shielded Assets — Issuance Authorization Signature Scheme `_ +.. [#zip-0227-issuer-identifier] `ZIP 227: Issuance of Zcash Shielded Assets — Issuer Identifier `_ +.. [#zip-0228] `ZIP 228: Asset Swaps for Zcash Shielded Assets `_ +.. [#zip-0231] `ZIP 231: Memo Bundles `_ +.. [#zip-0231-motivation] `ZIP 231: Memo Bundles — Motivation `_ +.. [#zip-0231-memo-encryption] `ZIP 231: Memo Bundles — Memo Encryption `_ +.. [#zip-0231-sapling-note-plaintext] `ZIP 231: Memo Bundles — Changes to the Zcash Protocol Specification `_ +.. [#zip-0233] `ZIP 233: Network Sustainability Mechanism: Removing Funds From Circulation `_ +.. [#zip-0235] `ZIP 235: Remove 60% of Transaction Fees From Circulation `_ .. [#zip-0244] `ZIP 244: Transaction Identifier Non-Malleability `_ +.. [#zip-0246-sighash-info] `ZIP 246: Digests for the Version 6 Transaction Format `_ +.. [#zip-0301] `ZIP 301: Zcash Stratum Protocol `_ +.. [#zip-2002-motivation] `ZIP 231: Explicit Fees — Motivation `_ +.. [#zip-2005] `ZIP 2005: Quantum Recoverability `_ +.. [#zip-2005-security-analysis] `ZIP 2005: Quantum Recoverability — Security Analysis `_ +.. [#draft-arya-deploy-nu7] `draft-arya-deploy-nu7: Deployment of the NU7 Network Upgrade `_ diff --git a/zips/zip-0231.md b/zips/zip-0231.md new file mode 100644 index 000000000..f5b05b61f --- /dev/null +++ b/zips/zip-0231.md @@ -0,0 +1,814 @@ + ZIP: 231 + Title: Memo Bundles + Owners: Jack Grigg + Kris Nuttycombe + Daira-Emma Hopwood + Arya Solhi + Credits: Sean Bowe + Nate Wilcox + Status: Draft + Category: Consensus / Wallet + Created: 2024-04-26 + License: MIT + Discussions-To: + + +# Terminology + +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 + +Currently, the memo associated with a shielded output is fixed to 512 bytes of data. + +This ZIP proposes to decouple memo data from outputs by introducing a per-transaction +memo bundle. Each shielded output carries a 32-byte memo key rather than an inline +512-byte memo field. The memo key is used to derive a symmetric encryption key that +decrypts the output's memo from the bundle, which consists of individually encrypted +256-byte chunks. This will: + +* reduce the memo data of a transaction with two shielded outputs from a minimum + of 1024 bytes to approximately 576 bytes; +* allow larger memos, with a proportionate increase in fees; +* enable memo data to be shared between multiple recipients of a transaction; +* enable memo data to be pruned from a stored transaction without impairing the + ability of a consensus node to validate the 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 +corresponding 512-byte memo field, with a 16-byte authentication tag +[^protocol-noteptconcept]. 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. + +An ordinary transaction is one that is padded to 2 inputs and 2 outputs (or 2 +Orchard actions), so as to make transfers that spend a note without change +indistinguishable from an ordinary transaction with change. Such a transaction +will consume 1024 bytes of block space for memo data. An Orchard transfer that +spends a larger number of notes will incur a memo data cost of $512 \times n$ +bytes on-chain, where $n$ is the number of notes being spent as inputs. +Ordinarily, most of this data space is wasted, as most wallets support only a +single 512-byte memo to be sent to the recipient of the transfer. Virtually all +transactions with shielded components consume at least 1024 bytes of block +space for memo data, and between half and 3/4 of that data payload is +ordinarily waste. Adopting this ZIP will eliminate a significant source of +chain bloat. + +Beyond reducing chain bloat, decoupling memos from shielded outputs allows for +some important use cases to be served. The shielded transaction protocol always +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 address(es), 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 the existing 512-byte +memo field. This ZIP makes the maximum size of memo data large enough to +support the inclusion of such proofs. + +Another motivation is that it is 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 +[^zip-0307], this is done by truncating the note ciphertext to just the part +that encrypts the note plaintext, removing the 512-byte encrypted memo and the +16-byte AEAD authentication tag. Because the authentication tag is not +transmitted to the light client, the decryption performed by the client does +not meet the standard IND-CCA2 ∧ INT-CTXT security notion for an authenticated +encryption scheme [^BN2000]. + +By decoupling memo data from note ciphertexts, this proposal reduces the +v6-onward note ciphertext to 100 bytes (excluding any other changes to the note +plaintext proposed by other ZIPs). This makes it practical for the light client +protocol to transmit complete note ciphertexts, including the AEAD tag, in +exchange for a relatively minor bandwidth increase compared to the current +truncated ciphertexts. This allows light clients to perform fully authenticated +decryption, ensuring security against chosen ciphertext attacks and 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. + +In addition to reducing chain bloat by eliminating wasted memo space, this ZIP +defines a mechanism by which validating nodes may reduce their long-term +storage requirements by pruning memo data, without impairing their ability to +validate the entire chain. + +Finally, 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. + + +# Privacy Implications + +Prior to the activation of this ZIP, every shielded output has an associated +memo field. A chain observer can therefore infer a likely 1:1 correlation +between transaction recipients and memo payloads. The maximum number of +distinct memos is precisely known, and the bounds on possible memo sizes are +very small (between 0 and 512 bytes). It is possible to send additional data to +a single recipient by adding (potentially zero-valued) outputs; on-chain this is +indistinguishable from sending more memos to more recipients or (in the case of +Orchard) spending more input notes. + +After the activation of this ZIP, recipient count and memo count are decoupled. +It becomes possible to construct transactions for which there are many more +recipients than distinct memos, or vice versa. Without mitigation, this could +result in more observably distinct patterns relating the number of recipients +to the number of possible memos. In particular, a v6-onward transaction with no memo +would be distinguishable from one with a memo. + +To mitigate this, a v6-onward transaction with any shielded outputs is required to +include at least 2 memo chunks in its memo bundle and pad the memo to a +multiple of 2 chunks (see [Memo bundle padding]). This ensures that the common +use case of sending a transaction without including explicit memo data is +indistinguishable from sending a transaction with a short memo, as is currently +supported by all wallets in common use. + +If a wallet includes an authenticated reply-to address, however, this may be +distinguishable from other ordinary wallet behaviour because the memo data +(including the reply-to address) necessarily exceeds 512 bytes. While it would +be possible to require transactions be padded to at least 16 chunks to +ameliorate this potential distinguisher, this introduces an unreasonable amount +of waste in the case of ordinary transactions. + +On the flip side, a chain observer now only knows upper bounds on the amount +of memo data being conveyed, and the number of possible distinct memos. +They have no information about how memo data is split among the recipients. +This can provide a privacy improvement in some situations. For example, it is +not possible to distinguish between many recipients receiving many small +memos, and the same set of recipients receiving one large shared memo. + +In summary, when sending large amounts of memo data, the change introduced by +this ZIP eliminates a potential distinguisher along one axis in exchange for a +potential distinguisher along another. + + +# Requirements + +- Standard Zcash shielded transactions continue to include a single 512-byte + memo. +- The mechanism should be able to reproduce the existing functionality where + each output may include a corresponding 512 bytes of memo data that is + decryptable only by the recipient of that output. +- 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. +- The memo bundle of a transaction can be pruned from block storage without + preventing the transaction from being verified when that pruned block data + is received by 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 + +- Recipients do not need to be able to receive multiple memos per note. This + capability could 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 in v6-onward transactions. + +## Memo bundle + +A memo bundle consists of a sequence of 272-byte memo chunks, each encrypting +a 256-byte chunk of memo plaintext. These memo chunks represent zero or more +encrypted memos. + +Each v6-onward transaction may contain a single memo bundle, and a memo bundle may contain +at most $\mathsf{memo\_chunk\_limit}$ = 64 memo chunks. This limits the total amount +of memo data that can be conveyed within a single transaction to +$\mathsf{memo\_chunk\_limit}$ × 256 = 16384 bytes, or 16 KiB. + +Memo bundles are encoded in transactions in a prunable manner: the entire +memo bundle can be replaced by a single digest. + +## Memo encryption + +During transaction construction, each output with memo data is assigned a +32-byte memo key $\mathsf{K^{memo}}$, as follows: + +- If an output is intended to be publicly decryptable, it is assigned the memo + key consisting of 32 \$mathtt{0x00}$ bytes. +- If an output has no memo data, it is assigned the memo key consisting of 32 + $\mathtt{0xFF}$ bytes. +- Otherwise, a 32-byte key SHOULD be generated randomly in a way that excludes + the above-mentioned reserved values from the valid range of the generation + function. + +A single memo key MUST NOT be used to encrypt more than one memo within a +single transaction. To share a memo among multiple recipients, the same +$\mathsf{K^{memo}}$ value is placed in each recipient's note plaintext; this +does not violate the above constraint because all recipients decrypt the same +memo. + +In note plaintexts of v6-onward transactions, the 512-byte memo field +is replaced by the 32-byte $\mathsf{K^{memo}}$. + +The explicit encodings of the note plaintexts for Sapling and Orchard outputs +are specified in ZIP 230 [^zip-0230-orchard-note-plaintext]. + +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’ [^protocol-abstractprfs]. + +If the generated key $\mathsf{encryption\_key}$ is 32 $\mathtt{0xFF}$ bytes, +the transaction constructor SHOULD 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 could omit this check. + +Each memo MUST have a length that is a multiple of 256 bytes. (For UTF-8 text +memos, padding is performed at the application level as specified in ZIP 302 +[^zip-0302].) The memo is split into 256-byte plaintext chunks. Each plaintext +chunk is encrypted with ChaCha20Poly1305 [^rfc-8439] 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{is\_final\_chunk}]$. + +The resulting 272-byte ciphertext is referred to as a memo chunk: + +- $\mathsf{MemoChunk} := \mathbb{B}^{{\kern-0.05em\tiny\mathbb{Y}}[272]}$ + +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{is\_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. + +Given a set of memos, each broken into a sequence of chunks, the shuffle +algorithm SHOULD select each successive chunk by choosing among the sequences +with probability weighted by each sequence's remaining length. That is, +given $N$ lists with remaining lengths $l_1, l_2, \ldots, l_N$, the next chunk +is drawn from list $i$ with probability $l_i / \sum_j l_j$. This can be +implemented by generating a uniform random index $r$ in $[0, \sum_j l_j)$ and +selecting the list $i$ such that $\sum_{j + +Rationale for deferred memo decryption + + +In pre-v6 transactions performed by full-node wallets, trial decryption of each +shielded output performs constant work regardless of whether the output belongs +to the wallet: the AEAD decryption of the full 580-byte note ciphertext costs +the same whether it succeeds or fails. + +With memo bundles, successful trial decryption of a 100-byte v6 note ciphertext +yields a memo key $\mathsf{K^{memo}}$, and if the key is not the no-memo +sentinel, the wallet must scan up to $\mathsf{memo\_chunk\_limit}$ memo chunks +to recover the memo. This additional work — potentially up to 64 AEAD +operations — creates a timing differential between successful and unsuccessful +trial decryptions that could be exploited by an adversary to determine whether +a node's wallet recognized a particular output. + +Deferring memo bundle decryption decorrelates the observable timing of block +processing from whether any notes were successfully decrypted, making it more +difficult for an adversary to attribute memo decryption work to a specific +transaction. + +
    + +## Encoding in transactions + +| Bytes | Name | Data Type | Description | +|----------|------------------------|---------------------------------------------------|------------------------------------------------------------------------| +| 1 | $\mathtt{fAllPruned}$ | $\mathtt{uint8}$ | 1 if the memo bundle has been pruned, otherwise 0. | +| 32 | $\mathtt{saltOrHash}$ | $\mathtt{byte}[32]$ | The salt for deriving memo encryption keys, or the memo bundle digest. | +| † varies | $\mathtt{nMemoChunks}$ | $\mathtt{compactSize}$ | The number of memo chunks. | +| † varies | $\mathtt{vMemoChunks}$ | $\mathtt{MemoChunk}[\mathtt{nMemoChunks}]$ | A sequence of encrypted memo chunks. | + +† These fields are present if and only if $\mathtt{fAllPruned} = 0$. + +If $\mathtt{fAllPruned} = 0$, then: + +- $\mathtt{saltOrHash}$ contains the $\mathsf{salt}$ used to derive memo encryption keys + (see [Memo encryption]). + +If $\mathtt{fAllPruned} = 1$, then: + +- $\mathtt{saltOrHash}$ contains the $\mathsf{memo\_bundle\_digest}$ as defined in + [Transaction sighash]. +- The $\mathtt{nMemoChunks}$ and $\mathtt{vMemoChunks}$ fields will be absent. + +## Transaction sighash + +$\mathsf{memo\_chunk\_digest}[i] = H(\mathtt{vMemoChunks}[i]) \\$ +$\mathsf{memo\_bundle\_digest} = H(\mathsf{concat}(\mathsf{memo\_chunk\_digests}))$ + +The memo bundle digest is used in place of the full memo bundle when +the bundle has been pruned. + +TODO: finish this as a modification to ZIP 248 [^zip-0248], which defines +the v6 transaction digest structure. Note that $\mathtt{fAllPruned}$ MUST NOT +contribute to the transaction digest, as it is not part of the committed +transaction data. + +## Changes to ZIP 317 [^zip-0317] + +The conventional fee in ZEC is altered such that a memo bundle may contain two +free chunks if there are any shielded outputs in the transaction. Any memo chunk +beyond this requires `marginal_fee`. See the Fee calculation section of ZIP 317 +[^zip-0317-fee-calculation] for details. + +## Network protocol + +Nodes MUST reject `tx` messages having an $\mathtt{fAllPruned}$ value that is +nonzero. A node that has pruned the memo bundle from a transaction MUST NOT serve +that transaction in response to a `getdata` message for `MSG_TX` or `MSG_WTX`; it SHOULD respond as though +the transaction is not available. + +Decoupling memo data from note data and making it independently prunable helps +to mitigate the long-term storage costs that memo data imposes on node +operators, while preserving the ability of every node to validate the full +transaction chain using the memo bundle digest. + +## Light client protocol + +Light client servers SHOULD include memo bundle pruning status in the compact +transaction format, so that clients can avoid attempting to retrieve memo data +from a server that has pruned it. + +## Changes to the Zcash Protocol Specification + +The changes to support memo bundles that affect the definitions of note +plaintexts and note ciphertexts, interact with the addition of an +$\mathsf{asset\_base}$ field to v6-onward Orchard note plaintexts in order to +support ZSAs, which must be merged with the changes in this section. + +Changes to the algorithms for encryption and decryption are specified below. +Note that [^zip-2005] also updates these algorithms, but the merge is trivial. + +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} \;{\small ⦂}\; \mathbb{B}^{{\kern-0.05em\tiny\mathbb{Y}}}, \mathsf{d} \;{\small ⦂}\; \mathbb{B}^{[\ell_{\mathsf{d}}]}, \mathsf{rseed} \;{\small ⦂}\; \mathbb{B}^{{\kern-0.05em\tiny\mathbb{Y}}[32]}, \mathsf{memo} \;{\small ⦂}\; \mathbb{B}^{{\kern-0.05em\tiny\mathbb{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} \;{\small ⦂}\; \mathbb{B}^{{\kern-0.05em\tiny\mathbb{Y}}}, \mathsf{d} \;{\small ⦂}\; \mathbb{B}^{[\ell_{\mathsf{d}}]}, \mathsf{rseed} \;{\small ⦂}\; \mathbb{B}^{{\kern-0.05em\tiny\mathbb{Y}}[32]}, \mathsf{memo} \;{\small ⦂}\; \mathbb{B}^{{\kern-0.05em\tiny\mathbb{Y}}[512]})$ + > + > Each v6-onward Sapling or Orchard note plaintext (denoted $\mathbf{np}$) consists of + > + > $\hspace{2em}(\mathsf{leadByte} \;{\small ⦂}\; \mathbb{B}^{{\kern-0.05em\tiny\mathbb{Y}}}, \mathsf{d} \;{\small ⦂}\; \mathbb{B}^{[\ell_{\mathsf{d}}]}, \mathsf{rseed} \;⦂\; \mathbb{B}^{{\kern-0.05em\tiny\mathbb{Y}}[32]}, \mathsf{K^{memo}} \;{\small ⦂}\; \mathbb{B}^{{\kern-0.05em\tiny\mathbb{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: + > + > $\begin{array}{|c|c|c|c|c|} \hline \raisebox{0.6ex}{\mathstrut} \text{8-bit } \mathsf{leadByte} & \text{88-bit } \mathsf{d} & \text{64-bit } \mathsf{v} & \text{256-bit } \mathsf{rseed} & \text{32-byte } \mathsf{K^{memo}} \\\hline \end{array}$ + > + > * A byte {{MBLEADBYTE}}, 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]: + +* For v6-onward note ciphertexts, the KDF used to derive the note encryption key + uses a different BLAKE2b-256 personalization string than for pre-v6 note + ciphertexts, to provide domain separation. The personalization string is formed + by concatenating a protocol prefix with the 4-byte little-endian encoding of + the transaction version group id ($\mathsf{nVersionGroupId}$): + + > For v6-onward Sapling note ciphertexts: + > + > $\hspace{2em}\mathsf{KDF^{Sapling}}(\mathsf{sharedSecret}, \mathsf{ephemeralKey}) := \mathsf{BLAKE2b\text{-}256}(\text{"Zc_SaplingKD"} \,||\, \mathsf{I2LEOSP}_{32}(\mathsf{nVersionGroupId}), \mathsf{sharedSecret} \,||\, \mathsf{ephemeralKey})$ + > + > For v6-onward Orchard note ciphertexts: + > + > $\hspace{2em}\mathsf{KDF^{Orchard}}(\mathsf{sharedSecret}, \mathsf{ephemeralKey}) := \mathsf{BLAKE2b\text{-}256}(\text{"Zc_OrchardKD"} \,||\, \mathsf{I2LEOSP}_{32}(\mathsf{nVersionGroupId}), \mathsf{sharedSecret} \,||\, \mathsf{ephemeralKey})$ + + This prevents a malicious lightwalletd server from presenting a v6 note ciphertext + to a wallet as though it were a partial v5 ciphertext, which could otherwise cause + the wallet to decrypt and act on unauthenticated plaintext. + +* 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 an Outgoing Viewing Key (Sapling and Orchard)’ [^protocol-decryptovk]: + +* Replace $\mathsf{memo} \;{\small ⦂}\; \mathbb{B}^{{\kern-0.05em\tiny\mathbb{Y}}[512]}$ with + $\mathsf{memoOrKey}$. +* Specify that the type of $\mathsf{memoOrKey}$ is $\mathbb{B}^{{\kern-0.05em\tiny\mathbb{Y}}[512]}$ + when decrypting a pre-v6 note ciphertext, or $\mathbb{B}^{{\kern-0.05em\tiny\mathbb{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 + +## Memo data retention + +Because memo data can be pruned from stored blocks, nodes that have pruned memo +data are not required to serve complete block data for affected transactions. +However, to support reliable memo delivery, it would be beneficial for the +Zcash community to establish expectations for how long after block confirmation +a node is expected to retain complete (unpruned) memo data. Such a retention +policy would allow wallet implementations to make reasonable assumptions about +memo availability when recovering from backup or performing initial +synchronization. + +## Interaction with ZIP 302 [^zip-0302] + +TBD + +## Note plaintext lead byte assignment + +The lead byte to be used for this proposal, denoted as {{MBLEADBYTE}} above, has +not yet been assigned. + + +# 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. + +## Independent fee policy for memo data + +By decoupling memos from shielded outputs, this ZIP creates an opportunity to +impose economic disincentives on adding memo data to the chain without affecting +the shielded value transfer protocols. Because the fee for memo data is +independent of the fee for value transfer, it can be adjusted independently — +for example, to impose a superlinear cost curve for large amounts of memo data, +or to increase memo fees in response to chain growth, without any impact on the +cost of ordinary shielded transfers. More generally, this decoupling makes it +straightforward to impose restrictions on memo creation that cannot currently be +imposed without also affecting value transfer. + +## Memo chunk size + +To understand the effect of memo chunk size, we construct a table showing the +total amount of data stored on-chain when encoding 16 KiB of memo data to as +many recipients as possible. + +Each table entry has the format "$N$ @ $M$ ($O$)" where $N$ is the maximum +number of distinct recipients you can have within the memo data limits, $M$ +is the cost in bytes of that memo data plus memo keys and authentication tags +when using a 32-byte memo key, and $O$ is the relative overhead compared to +pre-ZIP-231 memos. + +
    + +Calculation details + + +Let: +- $D$ be the limit on total memo data (16384 bytes); +- $C$ be the plaintext chunk size (256 or 512 bytes); +- $S$ be the maximum length of an individual memo (256 or 512 bytes); +- $K$ be the key size (32 bytes); +- $A$ be the authentication tag size (16 bytes); +- $L$ be the limit on the number of chunks (32 or $\infty$). + +Then +- $N = \mathsf{min}(L, \mathsf{ceiling}(D / \mathsf{max}(C, S))$; +- $M = N × (S+K+A)$; and +- $O = (M / D - 1) × 100\%$. +
    +
    + +| Chunk size | Memo size ≤ 256 bytes| Memo size = 512 bytes| +|------------|----------------------|----------------------| +| Pre-231 | 32 @ 16384 (  0.00%) | 32 @ 16384 (  0.00%) | +| 512 | 32 @ 17920 (+ 9.38%) | 32 @ 17920 (+ 9.38%) | +| 256 | 64 @ 19456 (+18.75%) | 32 @ 18432 (+12.50%) | +| 256 32-out | 32 @  9728 (-40.63%) | | + +In the "256 32-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 maximum number of memos. But that's inherently +baked into the decision to use a smaller plaintext 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 + +16-byte (128-bit) keys don't meet Zcash's target security level of 125 bits, +as argued in [^protocol-inbandrationale]. + +However, for the sake of argument, if we used a 16-byte memo key instead of +32 bytes, the transaction size overhead would become: + +| Chunk size | Memo size ≤ 256 bytes| Memo size = 512 bytes| +|------------|----------------------|----------------------| +| Pre-231 | 32 @ 16384 (  0.00%) | 32 @ 16384 (  0.00%) | +| 512 | 32 @ 17408 (+ 6.25%) | 32 @ 17408 (+ 6.25%) | +| 256 | 64 @ 18432 (+12.50%) | 32 @ 17920 (+ 9.38%) | +| 256 32-out | 32 @  9216 (-43.75%) | | + +The decrease in overhead is relatively modest in most cases, but more noticeable +for small memos with a 256-byte plaintext chunk. + +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. + +## 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}}$ 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 [^pczt]. +- 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}}$. + +## Domain separation of note ciphertexts + +V6-onward note ciphertexts use KDF personalization strings that incorporate the +transaction version group id ($\text{"Zc_SaplingKD"} \,||\, \mathsf{nVersionGroupId}$ +and $\text{"Zc_OrchardKD"} \,||\, \mathsf{nVersionGroupId}$), providing domain +separation from pre-v6 note ciphertexts. This prevents a downgrade attack in +which a malicious lightwalletd server presents a v6 note ciphertext as a partial +v5 note ciphertext. Without domain separation, a wallet that supports the v5 +partial-ciphertext optimization (downloading note ciphertexts without the MAC to +save bandwidth) could decrypt a v6 ciphertext without verifying its +authentication tag, potentially acting on unauthenticated data. Using the +version group id rather than a fixed suffix ensures that domain separation +extends automatically to future transaction versions. + +## 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 a node operator can prune the entire memo bundle from +a stored transaction, replacing it with a single digest, while still enabling +the transaction to be validated as part of its corresponding block. + + +# Deployment + +This ZIP is proposed to activate with Network Upgrade 7. [^draft-arya-deploy-nu7] + + +# Reference implementation + +TBD + + +# Alternatives + +- An alternative chunk size could be selected. The 256-byte chunk size was + chosen because the 16-byte AEAD tag for each chunk introduces a 6.25% + per-chunk overhead; smaller chunk sizes would require a higher percentage + of the memo bundle data to be devoted to encryption overhead, while + larger chunk sizes would tend to bloat the chain. +- The 64-chunk limit could be modified to be either smaller or larger. However, + as the smallest Orchard authenticated reply-to address proofs are + approximately 4 kilobytes in size, the limit needs to be sufficient to + permit this use case. +- The fee algorithm could be modified to be a superlinear function of the + number of memo chunks, in order to economically discourage the use of + large amounts of memo data. +- An alternative approach to memo pruning that permitted pruning at the + per-chunk level was proposed, but was judged to provide insufficient benefit + relative to its complexity cost. Per-chunk pruning would have allowed + selective removal of individual memos, but this added complexity to the + encoding and also introduced the risk that a maliciously pruned memo could + have a different interpretation when decrypted relative to the original + unpruned encoding of the memo. Jack Grigg discovered this attack. + +# 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"](https://www.rfc-editor.org/info/bcp14) + +[^protocol]: [Zcash Protocol Specification, Version 2025.6.2 [NU6.1] or later](protocol/protocol.pdf) + +[^protocol-noteptconcept]: [Zcash Protocol Specification, Version 2025.6.2 [NU6.1]. Section 3.2.1: Note Plaintexts and Memo Fields](protocol/protocol.pdf#noteptconcept) + +[^protocol-networks]: [Zcash Protocol Specification, Version 2025.6.2 [NU6.1]. Section 3.12: Mainnet and Testnet](protocol/protocol.pdf#networks) + +[^protocol-abstractprfs]: [Zcash Protocol Specification, Version 2025.6.2 [NU6.1]. Section 4.1.2: Pseudo Random Functions](protocol/protocol.pdf#abstractprfs) + +[^protocol-saplingsend]: [Zcash Protocol Specification, Version 2025.6.2 [NU6.1]. Section 4.7.2: Sending Notes (Sapling)](protocol/protocol.pdf#saplingsend) + +[^protocol-orchardsend]: [Zcash Protocol Specification, Version 2025.6.2 [NU6.1]. Section 4.7.3: Sending Notes (Orchard)](protocol/protocol.pdf#orchardsend) + +[^protocol-saplingandorchardinband]: [Zcash Protocol Specification, Version 2025.6.2 [NU6.1]. Section 4.20.1: Encryption (Sapling and Orchard)](protocol/protocol.pdf#saplingandorchardinband) + +[^protocol-decryptivk]: [Zcash Protocol Specification, Version 2025.6.2 [NU6.1]. Section 4.20.2: Decryption using an Incoming Viewing Key (Sapling and Orchard)](protocol/protocol.pdf#decryptivk) + +[^protocol-decryptovk]: [Zcash Protocol Specification, Version 2025.6.2 [NU6.1]. Section 4.20.3: Decryption using an Outgoing Viewing Key (Sapling and Orchard)](protocol/protocol.pdf#decryptovk) + +[^protocol-noteptencoding]: [Zcash Protocol Specification, Version 2025.6.2 [NU6.1]. Section 5.5: Encodings of Note Plaintexts and Memo Fields](protocol/protocol.pdf#noteptencoding) + +[^protocol-inbandrationale]: [Zcash Protocol Specification, Version 2025.6.2 [NU6.1]. Section 8.7: In-band secret distribution](protocol/protocol.pdf#inbandrationale) + +[^zip-0200]: [ZIP 200: Network Upgrade Mechanism](zip-0200.rst) + +[^draft-arya-deploy-nu7]: [draft-arya-deploy-nu7: Deployment of the NU7 Network Upgrade](draft-arya-deploy-nu7.md) + +[^zip-0230-orchard-note-plaintext]: [ZIP 230: Version 6 Transaction Format — Orchard Note Plaintext](zip-0230.rst#orchard-note-plaintext) + +[^zip-0248]: [ZIP 248: Extensible Transaction Format (PR: zcash/zips#1156)](https://github.com/zcash/zips/pull/1156) + +[^zip-0302]: [ZIP 302: Standardized Memo Field Format](zip-0302.rst) + +[^zip-0307]: [ZIP 307: Light Client Protocol for Payment Detection](zip-0307.rst) + +[^zip-0317]: [ZIP 317: Proportional Transfer Fee Mechanism](zip-0317.rst) + +[^zip-0317-fee-calculation]: [ZIP 317: Proportional Transfer Fee Mechanism - Fee calculation](zip-0317.rst#fee-calculation) + +[^zip-2005]: [ZIP 2005: Quantum Recoverability](zip-2005.md) + +[^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) + +[^BN2000]: [Authenticated Encryption: Relations among notions and analysis of the generic composition paradigm](https://eprint.iacr.org/2000/025) diff --git a/zips/zip-0231.rst b/zips/zip-0231.rst deleted file mode 100644 index 1bbed3699..000000000 --- a/zips/zip-0231.rst +++ /dev/null @@ -1,12 +0,0 @@ -:: - - ZIP: 231 - Title: Decouple Memos from Transaction Outputs - Owners: Jack Grigg - Kris Nuttycombe - Daira-Emma Hopwood - Credits: Sean Bowe - Nate Wilcox - Status: Reserved - Category: Consensus / Wallet - Discussions-To: diff --git a/zips/zip-0233.md b/zips/zip-0233.md index c68bb8cb4..54ed1bc6a 100644 --- a/zips/zip-0233.md +++ b/zips/zip-0233.md @@ -1,242 +1,211 @@ ``` ZIP: 233 -Title: Establish the Zcash Sustainability Fund on the Protocol Level -Owners: Jason McGee - Mark Henderson +Title: Network Sustainability Mechanism: Removing Funds From Circulation +Owners: Jason McGee + Zooko Wilcox + Mark Henderson Tomek Piotrowski Mariusz Pilarek + Paul Dann Original-Authors: Nathan Wilcox Credits: Status: Draft Category: Consensus / Ecosystem Created: 2023-08-16 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. [2] +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] -"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. +"ZEC/TAZ" refers to the native currency of Zcash on a given network, i.e. +ZEC on Mainnet and TAZ on Testnet. -"Issuance" - The method by which unmined or unissued ZEC is converted to ZEC -available to users of the network +"Block Subsidy" - The algorithmic issuance of ZEC/TAZ on block creation, as +defined by consensus. This is split between the miner and Funding Streams. -"We" - the ZIP authors, owners listed in the above front matter +"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.] -"`MAX_MONEY`" is the ZEC supply cap. For simplicity, this ZIP defines it to be -`21,000,000 ZEC`, although this is slightly larger than the actual supply cap -of the original ZEC issuance mechanism. +$\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. -# Abstract -This ZIP describes the motivation, the necessary changes for, and the -implementation specifications for the Zcash Sustainability Fund (ZSF). The ZSF -is a proposed alteration to the block rewards system and accounting of unmined -ZEC that allows for other sources of funding besides unissued ZEC. This new -mechanism for deposits -- that new applications or protocol designs can use to -strengthen the long-term sustainability of the network -- will likely be an -important step for future economic upgrades, such as a transition to Proof of -Stake or Zcash Shielded Assets, and other potential protocol fees and user -applications. +# Abstract -The changes in this ZIP are ultimately minimal, only requiring for the node to -track state in the form of a `ZSF_BALANCE`, and for a new transaction field to -be added, called `ZSF_DEPOSIT`. While wallet developer would be encouraged to -add the `ZSF_DEPOSIT` field to their UIs, no changes or new behavior are -absolutely required for developers or ZEC holders. +This ZIP proposes the introduction of a mechanism to voluntarily remove funds +entirely from circulation on the network. The explicit intent of this removal +is that the funds will be returned to circulation through future block subsidies, +rather than being permanently destroyed or held in reserve for discretionary use. +This mechanism, in combination with ZIP 234 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”. -This ZIP does not change the current ZEC block subsidy issuance schedule. Any -additional amounts paid into the sustainability fund are reserved for use in -future ZIPs. # Motivation -The Zcash network's operation and development relies fundamentally on the block -reward system inherited from Bitcoin. This system currently looks like this: - -- At Every New Block: - - Miner and funding streams are rewarded a constant amount via unissued ZEC - (this constant amount halves at specified heights) - - Miner is rewarded via Transaction fees `(inputs - outputs)` - -The Zcash Sustainability Fund is a proposed replacement to that payout -mechanism, with the relevant parts in *bold* below: - -- **Unmined ZEC is now accounted for as `ZSF_BALANCE`** -- **Transaction includes optional contributions to ZSF via a `ZSF_DEPOSIT` field** -- Thus, at Every New Block: - - Miner and funding streams rewarded the same constant amount, **but from - `ZSF_BALANCE`** (this constant amount still halves at specified heights) - - Miner is rewarded via Transaction fees `(inputs - outputs)`, **where - `outputs` includes the `ZSF_DEPOSIT` amount** - -For example, an end-user wallet application could have an option to contribute -a portion of a transaction to the ZSF, which would be included in a -`ZSF_DEPOSIT` field in the transaction, to be taken into account by the Zcash -nodes. - -This quite simple alteration has -- in our opinion -- a multitude of benefits: - -1. **Long Term Consensus Sustainability:** This mechanism supports long-term - consensus sustainability by addressing concerns about the sustainability of - the network design shared by Bitcoin-like systems through the establishment - of deposits into the Sustainability Fund to augment block rewards, ensuring - long-term sustainability as the issuance rate of Zcash drops and newly - issued ZEC decreases over time. -2. **Benefits to ZEC Holders:** Deposits to the ZSF slow down the payout of - ZEC, temporarily reducing its available supply, benefiting current holders - of unencumbered active ZEC in proportion to their holdings without requiring - them to opt into any scheme, introducing extra risk, active oversight, or - accounting complexity. -3. **Recovery of "Soft-Burned" Funds:** In some instances, such as miners not - claiming all available rewards, some ZEC goes unaccounted for, though not - formally burned. This proposal would recover it through the `ZSF_BALANCE` - mechanism described below. +This mechanism seeks to address concerns about the sustainability of the network +design shared by Bitcoin-like systems: -# Specification +1. **Long Term Consensus Sustainability:** By enabling the removal of funds from + circulation, 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. The intent is that removed funds will be automatically and + algorithmically reissued through future block subsidies, sustaining the + network's long-term security budget, whether or not all three ZIPs + comprising the Network Sustainability Mechanism are deployed in the same + network upgrade. +2. **Benefits to ZEC Holders:** Removing funds from circulation reduces the + circulating supply of ZEC. To the extent that this potentially contributes to + an increase in the value of remaining ZEC, it can be argued to benefit network + users in proportion to their holdings — without requiring them to opt into any + scheme, introducing extra risk, active oversight, or accounting complexity. -In practice, The Zcash Sustainability Fund is a single global balance -maintained by the node state and contributed to via a single transaction field. -This provides the economic and security support described in the motivation -section, while also importantly keeping the fund payouts extremely simple to -describe and implement. +# Privacy Implications -The two modifications are: -1. The re-accounting of unmined ZEC as a node state field called `ZSF_BALANCE` -2. The addition of a transaction field called `ZSF_DEPOSIT` +ZIP 233 adds a new type of transparent transaction event that is fully visible to chain +observers, and linked to other events performed in the transaction. The removal of +funds from circulation does not affect shielded outputs, and therefore does not alter +the privacy properties of shielded funds. -## `ZSF_BALANCE` +# Requirements -The ZEC issuance mechanism is re-defined to remove funds from `ZSF_BALANCE`, -which is initially set to `MAX_MONEY` at the genesis block. +- The mechanism enables users to remove funds from the circulating supply, and each removal event is explicitly specified in the corresponding transaction. +- The process is publicly auditable, allowing network participants to verify the amount and occurrence of funds removed from circulation. -Consensus nodes are then required to track new per-block state: +# Specification -- `ZSF_BALANCE[height] : u64 [zatoshi]` +## Transaction Field -The state is a single 64 bit integer (representing units of `zatoshi`) at any -given block height, $\mathsf{height}$, representing the Sustainability Fund -balance at that height. The `ZSF_BALANCE` can be calculated using the following -formula: +Each transaction gains a $\mathsf{zip233\_amount}$ property, specifying the +value in zatoshis that is removed from circulation when the transaction is +mined. The value removed from circulation subtracts from the remaining value in +the "transparent transaction value pool" as described in § 3.4 ‘Transactions and +Treestates’ [^protocol-transactions]. -$\mathsf{ZsfBalanceAfter}(\mathsf{height}) = \mathsf{MAX\_MONEY} + \sum_{h = 0}^{\mathsf{height}} (\mathsf{ZsfDeposit}(h) + \mathsf{Unclaimed}(h) - \mathsf{BlockSubsidy}(h))$ +$\mathsf{zip233\_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{zip233\_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 mechanism by which the funds removed from +circulation may be reissued through future block subsidies. -where $\mathsf{Unclaimed}(\mathsf{height})$ is the portion of the block subsidy -and miner fees that are unclaimed for the block at the given height. +## Changes to ZIP 230 [^zip-0230] -The block at height $\mathsf{height}$ commits to -$\mathsf{ZsfBalanceAfter}(\mathsf{height})$ as part of a new block commitment -in the block header, at the end of the `hashBlockCommitments` chain in -[ZIP-244](https://zips.z.cash/zip-0244#block-header-changes). +The following field is appended to the Common Transaction Fields of the v6 +transaction format after `nExpiryHeight` [^zip-0230-transaction-format]: -TODO ZIP editors: consider introducing a chain state commitment hash tree. -(When we get closer to the network upgrade, we will have a better idea what -commitments that network upgrade needs.) +| Bytes | Name | Data Type | Description | +|-------|----------------|-----------|----------------------------------------------------------------------------| +| 8 | `zip233Amount` | `uint64` | The value to be removed from circulation in this transaction, in zatoshis. | -## Deposits into the Sustainability Fund +The $\mathsf{zip233\_amount}$ of a transaction is defined to be the value of the +`zip233Amount` field if present, and otherwise 0. -Sustainability fund deposits can be made via the new `zsfDeposit` field. This -can be done by: -- ZEC fund holders, in non-coinbase transactions; -- Zcash miners, in coinbase transactions. +Notes: -In transaction versions without this new field: -- unclaimed miner fees and rewards in **coinbase transactions** are re-defined - as deposits into the sustainability fund, and -- there are no sustainability fund deposits from non-coinbase transactions. +* If both this ZIP and ZIP 2002 are selected for inclusion in the same Network + Upgrade, then the ordering of fields in the transaction format will be ``fee`` + and then ``zip233Amount``. +* Older transaction versions can continue to be supported after a network + upgrade, but removing funds from circulation is not possible for these + transactions. For example, NU5 supports both v4 and v5 transaction formats, + for both coinbase and non-coinbase transactions. -Note: older transaction versions can continue to be supported after a network -upgrade. For example, NU5 supports both v4 and v5 transaction formats, for both -coinbase and non-coinbase transactions. +## Changes to the Zcash Protocol Specification -### `zsfDeposit` fields in transactions +Make a change to § 3.4 ‘Transactions and Treestates’ [^protocol-transactions] +implementing the specification in [ZIP-233 Amount]. -Each transaction can dedicate some of its excess funds to the ZSF, and the -remainder becomes the miner fee, with any excess miner fee/reward going to the -ZSF +In § 7.1 ‘Transaction Encoding and Consensus’ [^protocol-txnconsensus], add: -This is achieved by adding a new field to the common transaction fields -[#zip-0225-transaction-format]: +> [NU7 onward] $\mathsf{zip233\_amount}$ MUST be in the range $\{ 0 .. \mathsf{MAX\_MONEY} \}$. -- `zsfDeposit : u64 [zatoshi]` +In § 7.1.2 ‘Transaction Consensus Rules’ [^protocol-txnconsensus], add a note: -The `ZSF_BALANCE[H]` for a block at height `H` can be calculated given a value -of `ZSF_BALANCE[H-1]` and the set of transactions contained in that block. -First, the `ZSF_DEPOSIT[H]` is calculated based solely on `ZSF_BALANCE[H-1]`. -This is subtracted from the previous block's balance to be distributed as part -of the block reward. Second, the sum of all the `ZSF_DEPOSIT` fields of all -transactions in the block is added to the balance. +> [NU7 onward] $\mathsf{zip233\_amount}$ does not result in an output being produced in any +chain value pool. +## Modifications relative to ZIP 244 [^zip-0244] -### Non-Coinbase Transactions +Relative to the sighash algorithm defined in ZIP 244, the sighash algorithm +that applies to v6 transactions differs by appending the encoding of +$\mathsf{zip233\_amount}$ to the Common Transaction Fields that are the input +to the digest in T.1: `header_digest` [^zip-0244-t-1-header-digest]: -If the `ZSF_DEPOSIT` field is not present in an older transaction version, it -is defined to be zero for non-coinbase transactions. +> T.1f: zip233_amount (8-byte little-endian amount to remove from circulation) -#### Consensus Rule Changes +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. -- Transparent inputs to a transaction insert value into a transparent - transaction value pool associated with the transaction. Transparent outputs - **and sustainability fund deposits** remove value from this pool. +## Applicability -### Coinbase Transactions +All of these changes apply identically to Mainnet and Testnet. -Any excess miner fee/reward is sent to the ZSF. -In new blocks, this deposit is tracked via the `ZSF_DEPOSIT` field in coinbase -transactions. +# Rationale -If the `ZSF_DEPOSIT` field is not present in a coinbase transaction with an -older transaction version, it is defined as the value of any unspent miner fee -and miner reward. This re-defines these previously unspendable funds as ZSF -deposits. +All technical decisions in this ZIP are balanced between the necessary +robustness of the NSM mechanics, and simplicity of implementation. -#### Consensus Rule Changes +## New transaction field for amount to remove from circulation -- The remaining value in the transparent transaction value pool of a coinbase - transaction is **deposited in the sustainability fund**. +An explicit value distinguishes the funds to remove from circulation from +the transaction fee. Explicitness also ensures any arithmetic flaws in any +implementations are more likely to be observed and caught immediately. -### `ZSF_DEPOSIT` Requirements -- ZIP 230 [3] must be updated to include `ZSF_DEPOSIT`. -- ZIP 244 [4] must be updated as well to include `ZSF_DEPOSIT`. +# Deployment -# Rationale +This ZIP is proposed to activate with Network Upgrade 7. [^draft-arya-deploy-nu7] -All technical decisions in this ZIP are balanced between the necessary -robustness of the ZSF mechanics, and simplicity of implementation. -## `ZSF_BALANCE` as node state +# References -Tracking the `ZSF_BALANCE` value as a node state using the above formula is -very simple in terms of implementation, and should work correctly given that -the node implementations calculate the value according to the specifications. +[^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) -## `ZSF_DEPOSIT` as explicit transaction field +[^protocol]: [Zcash Protocol Specification, Version 2025.6.2 [NU6.1] or later](protocol/protocol.pdf) -An explicit value distinguishes the ZEC destined to Sustainability Fund -deposits from the implicit transaction fee. Explicitness also ensures any -arithmetic flaws in any implementations are more likely to be observed and -caught immediately. +[^protocol-transactions]: [Zcash Protocol Specification, Version 2025.6.2 [NU6.1]. Section 3.4: Transactions And Treestates](protocol/protocol.pdf#transactions) -# Deployment +[^protocol-networks]: [Zcash Protocol Specification, Version 2025.6.2 [NU6.1]. Section 3.12: Mainnet and Testnet](protocol/protocol.pdf#networks) -This ZIP is proposed to activate with Network Upgrade (TODO ZIP editors). +[^protocol-constants]: [Zcash Protocol Specification, Version 2025.6.2 [NU6.1]. Section 5.3: Constants](protocol/protocol.pdf#constants) -# References +[^protocol-txnconsensus]: [Zcash Protocol Specification, Version 2025.6.2 [NU6.1]. 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.rst#transaction-format) + +[^zip-0234]: [ZIP 234: Network Sustainability Mechanism: Issuance Smoothing](zip-0234.rst) -**[1]: [Key words for use in RFCs to Indicate Requirement Levels](https://www.rfc-editor.org/rfc/rfc2119.html)** +[^zip-0235]: [ZIP 235: Remove 60% of Transaction Fees From Circulation](zip-0235.rst) -**[2]: [ZIP 200: Network Upgrade Mechanism](https://zips.z.cash/zip-0200)** +[^zip-0244]: [ZIP 244: Transaction Identifier Non-Malleability](zip-0244.rst) -**[3]: [ZIP 230: v6 transactions, including ZSAs](https://github.com/zcash/zips/pull/687)** +[^zip-0244-t-1-header-digest]: [ZIP 244: Transaction Identifier Non-Malleability. Section T.1: header_digest](zip-0244.rst#t-1-header-digest) -**[4]: [ZIP 244: Transaction Identifier Non-Malleability](https://zips.z.cash/zip-0244)** +[^draft-arya-deploy-nu7]: [draft-arya-deploy-nu7: Deployment of the NU7 Network Upgrade](draft-arya-deploy-nu7.md) diff --git a/zips/zip-0234-balance.png b/zips/zip-0234-balance.png deleted file mode 100644 index 9f0e8e5a7..000000000 Binary files a/zips/zip-0234-balance.png and /dev/null differ diff --git a/zips/zip-0234-block_subsidy.png b/zips/zip-0234-block_subsidy.png deleted file mode 100644 index 435d8fcd4..000000000 Binary files a/zips/zip-0234-block_subsidy.png and /dev/null differ diff --git a/zips/zip-0234.md b/zips/zip-0234.md index 332baac6d..9c34e9115 100644 --- a/zips/zip-0234.md +++ b/zips/zip-0234.md @@ -1,37 +1,61 @@ ``` ZIP: 234 -Title: Smooth Out The Block Subsidy Issuance -Owners: Jason McGee - Mark Henderson +Title: Network Sustainability Mechanism: Issuance Smoothing +Owners: Jason McGee + Zooko Wilcox + Mark Henderson Tomek Piotrowski Mariusz Pilarek + Paul Dann Original-Authors: Nathan Wilcox Credits: 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] -"Network upgrade" - to be interpreted as described in ZIP 200. [2] +"ZEC/TAZ" refers to the native currency of Zcash on a given network, i.e. +ZEC on Mainnet and TAZ on Testnet. -“Block Subsidy” - to be interpreted as described in the Zcash Protocol -Specification (TODO ZIP Editors: link from comment). +The terms "Block Subsidy" and "Issuance" are to be interpreted as described in +ZIP 233. [^zip-0233] -“Issuance” - the sum of Block Subsidies over time. (TODO ZIP Editors: work out -if this definition is correct or can be removed). +Let $\mathsf{PostBlossomHalvingInterval}$ be as defined in [^protocol-diffadjustment]. -“`ZsfBalanceAfter(h)`” is the total ZEC available in the Zcash Sustainability -Fund (ZSF) after the transactions in block `h`, described in ZIP draft-zsf.md. -In this ZIP, the Sustainability Fund is used to pay out Block Subsidies from -unmined ZEC, and other fund deposits. +$\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. -Let `PostBlossomHalvingInterval` be as defined in [#protocol-diffadjustment]_. +"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] + +"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 @@ -39,118 +63,161 @@ Let `PostBlossomHalvingInterval` be as defined in [#protocol-diffadjustment]_. 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 slow exponential “smoothing” of the curve. +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. +intervals, assuming no ZEC/TAZ is removed from circulation during that time, and +retains the overall supply cap of `MAX_MONEY`. -This ZIP depends on the ZIP introducing the Zcash Sustainability Fund -(ZIP-XXX). # Motivation +The current block reward halving schedule is fixed and does not provide a way +to “recycle” funds removed from circulation via ZIP-233 into future issuance. +Once scheduled issuance ends, the network becomes reliant on transaction fees +for the security budget. + +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. We want to enable ZEC that has been removed from circulation to be reissued + in the future to benefit network sustainability. +3. We want to retain the existing ZEC supply cap of 21 million. +4. We want the issuance rate to remain similar to the historical rate for Zcash + (and before that, Bitcoin). +5. We want issuance to be easy for all network users to understand and predict. +6. 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 which 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. - -To address this, we propose issuing a fixed portion of the pending -funds-to-be-issued in each block. This has the effect of smoothing out the -issuance curve of ZEC, ensuring a more consistent and predictable rate of coin -issuance, while still preserving the overall supply cap of 21,000,000 coins. -This mechanism by itself (without other anticipated changes) seeks to preserve -the core aspects of Zcash's issuance policy and aims to enhance predictability -and avoid sudden changes. By making this shift, the average block subsidy over -time will remain predictable with very gradual changes. - -However, we anticipate schemes proposed in [#draft-zsf]_ where the amount of -funds-to-be-issued may increase. In that scenario, this issuance mechanism -would distribute that increase starting in the immediately following block and -subsequent blocks. Because this distribution mechanism has an exponential -decay, such increases will be spread out in miniscule amounts to future blocks -over a long time period. This issuance mechanism thus provides a way for -potential increases or decreases of issuance while constraining those changes -to be small on a short time scale to avoid unexpected disruptions. - -Additionally, the current Bitcoin-style issuance does not take into account the -current balance of `ZsfBalanceAfter(h)`. If [#draft-zsf]_ were to activate -without a change to the issuance mechanism, then some funds would never be -disbursed after they are deposited back into the ZSF. +mechanism that dictates the issuance of new coins via the mining block reward. +Halvings have since become culturally foundational, but abrupt reductions in +miner revenue can lead to short-term drops in mining participation, as evidenced +by hashrate/difficulty. + +In Zcash, difficulty declined materially after recent halving events: following the +2020-11-18 halving, weekly difficulty fell about 20.6% within roughly a week and was +still about 9.1% lower around 30 days later. Following the 2024-11-23 halving, +weekly difficulty fell about 17% within roughly a week and about 23% around 30 days +later. [^zechub-difficulty] As difficulty adjusts in response to hashrate, these short-term +drops are consistent with discrete subsidy cuts producing measurable reductions in mining +participation. + +While Bitcoin halvings are often accompanied by bullish narratives and have +sometimes been followed by strong price performance, Zcash has not consistently +followed the same pattern. Thus, by smoothing out the issuance curve, we +mitigate the risks associated with abrupt changes in issuance rates. + +This new NSM-based issuance scheme addresses 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. Critically, +it establishes the intended path for ZEC that has been voluntarily removed from +circulation, as well as transaction fees that are deliberately redirected into +the reserve: these funds are automatically and algorithmically reissued over +future block subsidies, ensuring they benefit the network's long-term security. # Requirements Smoothing the issuance curve is possible using an exponential decay formula that satisfies the following requirements: -## Issuance Requirements - -1. The issuance can be summarised into a reasonably simple explanation -2. Block subsidies approximate a continuous function -3. If there are funds in the ZSF, 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 ZSF at the beginning of that 4 year period, if there are no - deposits into the ZSF during those 4 years - -TODO daira: add a requirement that makes the initial total issuance match the previous total issuance +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 removed from circulation 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 subsidy amount. +6. The immediate change in issuance when this mechanism activates should be + minimal. # Specification -## Goals +## Parameters -We want to decrease the short-term impact of the deployment of this ZIP on -block reward recipients, and minimise the potential reputational risk to Zcash -of changing the block reward amount. +$\mathsf{BLOCK\_SUBSIDY\_FRACTION} = 4126 / 10\_000\_000\_000 = 0.0000004126$ -## Constants +$\mathsf{DEPLOYMENT\_BLOCK\_HEIGHT} = \mathsf{TBD}$ -Define constants: +$\mathsf{MoneyReserveAfter}(\mathsf{height}) =$ The value of the Money Reserve +after the specified block height. -“`BLOCK_SUBSIDY_FRACTION`” = 4126 / 10,000,000,000 or `0.0000004126` +The block height will be chosen by the following criteria: -"`DEPLOYMENT_BLOCK_HEIGHT`" = 2726400 +- It is after NU7 activation height. +- 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 ZEC removed from circulation (i.e. assuming the amount of ZEC removed from + circulation is exactly 0). ## Issuance Calculation -At the `DEPLOYMENT_BLOCK_HEIGHT`, nodes should switch from the current issuance +At the $\mathsf{DEPLOYMENT\_BLOCK\_HEIGHT}$, nodes MUST switch from the current issuance calculation, to the following: -Given the block height `h` define a function **BlockSubsidy(h)**, such that: +$\mathsf{BlockSubsidy}(\mathsf{height}) = \mathsf{ceiling}(\mathsf{BLOCK\_SUBSIDY\_FRACTION} \cdot \mathsf{MoneyReserveAfter}(\mathsf{height} - 1))$ -**BlockSubsidy(h)** = Block subsidy for a given `h`, that satisfies above -requirements. +## Applicability -Using an exponential decay function for **BlockSubsidy** satisfies requirements -**R1** and **R2** above: +All of these changes apply identically to Mainnet and Testnet. -`BlockSubsidy(h) = BLOCK_SUBSIDY_FRACTION * ZsfBalanceAfter(h - 1)` -Finally, to satisfy **R3** above we always round up to the next zatoshi. +# Rationale -`BlockSubsidy(h) = ceiling(BLOCK_SUBSIDY_FRACTION * ZsfBalanceAfter(h - 1))` +* Using an exponential decay function satisfies **Requirements 1** and **2** above. +* We round up to the next zatoshi to satisfy **Requirement 3** above. +* The issuance formula depends only on `MoneyReserveAfter(height - 1)` and a + single constant fraction, making it simple to implement, explain, and verify. -# Rationale +## Parameters + +The 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. -## `BLOCK_SUBSIDY_FRACTION` +The difference in up-front calculation versus dynamic calculation is +in whether or not funds removed from circulation are accounted for +(since funds removed from circulation in the future 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 removed from circulation prior to that height times +$\mathsf{BLOCK\_SUBSIDY\_FRACTION}$. For example, if a total of 100,000 ZEC +were removed from circulation 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 amount removed from circulation (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. -Let `IntendedZSFFractionRemainingAfterFourYears` = 0.5. +## BLOCK_SUBSIDY_FRACTION -The value `4126 / 10_000_000_000` satisfies the approximation within +0.002%: +Let $\mathsf{IntendedMoneyReserveFractionRemainingAfterFourYears} = 0.5$. -`(1 - BLOCK_SUBSIDY_FRACTION)^PostBlossomHalvingInterval ≈ IntendedZSFFractionRemainingAfterFourYears` +The value $4126 / 10\_000\_000\_000$ satisfies the approximation within $\pm 0.002\%$: -Meaning after a period of 4 years around half of `ZSF_BALANCE` will be paid out -as block subsidies, thus satisfying **R4**. +$(1 - \mathsf{BLOCK\_SUBSIDY\_FRACTION})^\mathsf{PostBlossomHalvingInterval} \approx \mathsf{IntendedMoneyReserveFractionRemainingAfterFourYears}$ -The largest possible amount in the ZSF is MAX_MONEY, in the theoretically -possible case that all issued funds are deposited back into the ZSF. If this -happened, the largest interim sum in the block subsidy calculation would be -MAX_MONEY * 4126 + 10000000000. +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**. -This uses 62.91 bits, which is just under the 63 bit limit for 64-bit signed -two's-complement integer amount types. +The largest possible value in the Money Reserve is $\mathsf{MAX\_MONEY}$, in the +theoretically possible case that all issued funds are removed from circulation. +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 @@ -158,64 +225,79 @@ chose a power-of-10 denominator for simplicity. TODO for ZIP owners: How many ZEC per day? -## `DEPLOYMENT_BLOCK_HEIGHT` - -The deployment should happen at the next halving, which is block `2726400`. - -Since there is a planned halving at this point, there will already be a -significant "shock" caused by the drop in issuance caused by the halving. This -reduces surprise and thus increases security. Also, due to the nature of the -smoothed curve having a portion of the curve above the respective step function -line at times, this will maximally _reduce_ the issuance shock at the -`DEPLOYMENT_BLOCK_HEIGHT`. - ## Visualization of the Smoothed Curve -The following graph illustrates compares issuance for the current halving-based -step function vs 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](../rendered/assets/images/zip-0234-block_subsidy.png) -The graph below shows the balance of the ZSF 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 ZSF assuming smooth issuance is implemented](../rendered/assets/images/zip-0234-balance.png) +![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 -Zcash Sustainability Fund is established (ZIP-XXX). # Appendix: Simulation -The [ZSF simulator](https://github.com/eigerco/zsf-simulator) allows us to -simulate the effects of this ZIP on the ZSF balance and the block subsidy, as +The [NSM Simulator](https://github.com/eigerco/zsf-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 no ZEC is ever deposited to the ZSF, its balance will -be depleted after 113.88 years, and the block subsidy will be 0 ZEC after that -point. +indicates that, assuming that no ZEC is ever removed from circulation, 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 +This fragment of the output: ``` Halving 1 at block 1680000: - ZSF subsidies: 262523884819889 (~ 2625238.848 ZEC, 1.563 ZEC per block) + 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), ZSF/legacy: 1.0001 + 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 (aroound 4 years). +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. [^draft-arya-deploy-nu7] +It MUST be deployed at the same time or after ZIP 233 ("NSM: Removing Funds From +Circulation" [^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 2025.6.2 [NU6.1] or later](protocol/protocol.pdf) + +[^protocol-notation]: [Zcash Protocol Specification, Version 2025.6.2 [NU6.1]. Section 2: Notation](protocol/protocol.pdf#notation) + +[^protocol-networks]: [Zcash Protocol Specification, Version 2025.6.2 [NU6.1]. Section 3.12: Mainnet and Testnet](protocol/protocol.pdf#networks) + +[^protocol-chainvaluepoolbalances]: [Zcash Protocol Specification, Version 2025.6.2 [NU6.1]. Section 4.17 Chain Value Pool Balances](protocol/protocol.pdf#chainvaluepoolbalances) + +[^protocol-constants]: [Zcash Protocol Specification, Version 2025.6.2 [NU6.1]. Section 5.3: Constants](protocol/protocol.pdf#constants) + +[^protocol-diffadjustment]: [Zcash Protocol Specification, Version 2025.6.2 [NU6.1]. Section 7.7.3 Difficulty Adjustment](protocol/protocol.pdf#diffadjustment) + +[^zip-0200]: [ZIP 200: Network Upgrade Mechanism](zip-0200.rst) + +[^zip-0233]: [ZIP 233: Network Sustainability Mechanism: Removing Funds From Circulation](zip-0233.md) -[2] ZIP-200: https://zips.z.cash/zip-0200 +[^draft-arya-deploy-nu7]: [draft-arya-deploy-nu7: Deployment of the NU7 Network Upgrade](draft-arya-deploy-nu7.md) -[3] ZIP-XXX: Placeholder for the ZSF ZIP +[^zechub-difficulty]: [ZecHub weekly difficulty dataset](https://raw.githubusercontent.com/ZecHub/zechub-wiki/refs/heads/main/public/data/zcash/difficulty.json) diff --git a/zips/zip-0235.md b/zips/zip-0235.md new file mode 100644 index 000000000..df8b840ea --- /dev/null +++ b/zips/zip-0235.md @@ -0,0 +1,195 @@ +``` +ZIP: 235 +Title: Remove 60% of Transaction Fees From Circulation +Owners: Jason McGee + Zooko Wilcox + Mark Henderson + Tomek Piotrowski + Mariusz Pilarek + Paul Dann +Original-Authors: Nathan Wilcox +Credits: +Status: Draft +Category: Ecosystem +Created: 2023-09-21 +License: BSD-2-Clause +Discussions-To: +``` + + +# 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 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" and "Issuance" are to be interpreted as described in +ZIP 233. [^zip-0233] + + +# Abstract + +This ZIP proposes to remove 60% of transaction fees from circulation, while +the remaining 40% is directed as before. The intent of this removal is that the +funds will be automatically and algorithmically reissued through future block +subsidies, rather than being permanently destroyed or held as a discretionary +reserve. + + +# Motivation + +ZIP 233 ("Network Sustainability Mechanism: Removing Funds From Circulation" +[^zip-0233]) describes a method by which ZEC can be removed from circulation to +support network sustainability. + +By introducing a requirement that a certain proportion of transaction fees be +removed from circulation, we aim 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 [^eip-1559], + but with long-term sustainability benefits. Unlike a permanent burn, the + removed funds are intended to be reissued through future block subsidies. +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 + efficient processing of transactions and supports a robust and responsive + network. +3. **Aligning Interests:** Removing transaction fees from circulation 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. +4. **Future-Proofing the Network**: Removing a portion of transaction fees from + circulation is a forward-looking approach that prepares the Zcash network for + long-term sustainability. By returning these funds to circulation through + future block subsidies, the network maintains a viable security budget + beyond the original issuance schedule. + + +# Requirements + +* For each block, at least 60% (rounded down) of the total fees are to be + removed from circulation. +* 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 $\mathsf{zip233\_amount}$, +as defined in [^zip-0233], 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 [^zip-0230]. + +## 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 remove +the required funds from circulation. Since $\mathsf{zip233\_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{zip233\_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 [^zip-0317]). + +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 are removed from circulation, that would be 210.864 ZEC per +year. [^zsf-fee-estimator] + +## 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 remove ZEC from circulation in various ways to +support network sustainability, including but not limited to: + +- ZSA fees +- Fees and donations specific to decentralized applications +- “Storage fees” for any future data availability +- 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: Removing Funds From Circulation" [^zip-0233]). + + +# 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"](https://www.rfc-editor.org/info/bcp14) + +[^protocol]: [Zcash Protocol Specification, Version 2025.6.2 [NU6.1] or later](protocol/protocol.pdf) + +[^protocol-notation]: [Zcash Protocol Specification, Version 2025.6.2 [NU6.1]. Section 2: Notation](protocol/protocol.pdf#notation) + +[^protocol-networks]: [Zcash Protocol Specification, Version 2025.6.2 [NU6.1]. 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: Removing Funds From Circulation](zip-0233.rst) + +[^zip-0234]: [ZIP 234: Network Sustainability Mechanism: Issuance Smoothing](zip-0234.rst) + +[^zip-0317]: [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) + +[^eip-1559]: [EIP-1559: Fee market change for ETH 1.0 chain](https://eips.ethereum.org/EIPS/eip-1559) diff --git a/zips/zip-0236.rst b/zips/zip-0236.rst index b4fdfc8d8..17c10d41c 100644 --- a/zips/zip-0236.rst +++ b/zips/zip-0236.rst @@ -2,10 +2,10 @@ ZIP: 236 Title: Blocks should balance exactly - Owners: Daira-Emma Hopwood + Owners: Daira-Emma Hopwood Credits: Jack Grigg Kris Nuttycombe - Status: Draft + Status: Final Category: Consensus Created: 2024-07-02 License: MIT @@ -93,61 +93,47 @@ Specification ============= From the activation block of this ZIP onward, coinbase transactions MUST claim all -of the available miner subsidy plus fees in their block. More specifically, the -following paragraph and consensus rule in § 3.4 "Transactions and Treestates" of -the Zcash Protocol Specification [#protocol-transactions]_: +of the available miner subsidy plus fees in their block. - Transparent inputs to a transaction insert value into a transparent transaction - value pool associated with the transaction, and transparent outputs remove value - from this pool. As in Bitcoin, the remaining value in the transparent transaction - value pool of a non-coinbase transaction is available to miners as a fee. The - remaining value in the transparent transaction value pool of a coinbase transaction - is destroyed. +Changes to the Zcash Protocol Specification +------------------------------------------- - **Consensus rule:** The remaining value in the transparent transaction value pool - MUST be nonnegative. +The following sentence in § 3.4 ‘Transactions and Treestates’ [#protocol-transactions]_: -is modified to become: + The remaining value in the transparent transaction value pool of a coinbase + transaction is destroyed. - Transparent inputs to a transaction insert value into a transparent transaction - value pool associated with the transaction, and transparent outputs remove value - from this pool. The effect of Sapling Spends and Outputs, and of Orchard Actions - on the transaction value pool are specified in § 4.13 and § 4.14 respectively. - - As in Bitcoin, the remaining value in the transparent transaction value pool of - a non-coinbase transaction is available to miners as a fee. That is, the sum of - those values for non-coinbase transactions in each block is treated as an implicit - input to the transaction value balance of the block's coinbase transaction (in - addition to the implicit input created by issuance). +is clarified as follows: The remaining value in the transparent transaction value pool of coinbase transactions in blocks prior to NU6 is destroyed. From activation of NU6, this remaining value is required to be zero; that is, all of the available balance MUST be consumed by outputs of the coinbase transaction. - **Consensus rules:** +In § 7.1.2 ‘Transaction Consensus Rules’ [#protocol-txnconsensus]_ as modified by +[#zip-2001]_, replace: + + The total output value of a coinbase transaction MUST NOT be greater than its + total input value. - * The remaining value in the transparent transaction value pool of a non-coinbase - transaction MUST be nonnegative. - * [Pre-NU6] The remaining value in the transparent transaction value pool of a - coinbase transaction MUST be nonnegative. - * [NU6 onward] The remaining value in the transparent transaction value pool of - a coinbase transaction MUST be zero. +with -where "NU6" is to be replaced by the designation of the network upgrade in which -this ZIP will be activated. + [Pre-NU6] The total output value of a coinbase transaction MUST NOT be greater + than its total input value. -Note that the differences in the first two paragraphs of the above replacement text -are clarifications of the protocol, rather than consensus changes. Those could be -made independently of this ZIP. + [NU6 onward] The total output value of a coinbase transaction MUST be equal to + its total input value. -This change applies identically to Mainnet and Testnet. +These changes apply identically to Mainnet and Testnet. Deployment ========== -This ZIP is proposed to be deployed with NU6. [#zip-0253]_ +This ZIP was deployed with NU6. [#zip-0253]_ + +The wording change to § 7.1.2 depends on [#zip-2001]_ which was also deployed +with NU6. [#zip-0253]_ Reference implementation @@ -171,5 +157,7 @@ References .. [#protocol] `Zcash Protocol Specification, Version 2024.5.1 or later `_ .. [#protocol-transactions] `Zcash Protocol Specification, Version 2024.5.1 [NU6]. Section 3.4: Transactions and Treestates `_ .. [#protocol-networks] `Zcash Protocol Specification, Version 2024.5.1 [NU6]. Section 3.12: Mainnet and Testnet `_ +.. [#protocol-txnconsensus] `Zcash Protocol Specification, Version 2024.5.1 [NU6]. Section 7.1.2: Transaction Consensus Rules `_ .. [#zip-0200] `ZIP 200: Network Upgrade Mechanism `_ .. [#zip-0253] `ZIP 253: Deployment of the NU6 Network Upgrade `_ +.. [#zip-2001] `ZIP 2001: Lockbox Funding Streams `_ diff --git a/zips/zip-0239.rst b/zips/zip-0239.rst index 23f18ffa4..e9dd6ca79 100644 --- a/zips/zip-0239.rst +++ b/zips/zip-0239.rst @@ -2,8 +2,8 @@ ZIP: 239 Title: Relay of Version 5 Transactions - Owners: Daira-Emma Hopwood - Jack Grigg + Owners: Daira-Emma Hopwood + Jack Grigg Status: Final Category: Network Created: 2021-05-29 diff --git a/zips/zip-0240.md b/zips/zip-0240.md new file mode 100644 index 000000000..71bd1a333 --- /dev/null +++ b/zips/zip-0240.md @@ -0,0 +1,5 @@ + ZIP: 240 + Title: Standard Transaction Rules + Status: Reserved + Category: Consensus + Discussions-To: diff --git a/zips/zip-0243.rst b/zips/zip-0243.rst index 47c574b07..5074c58b8 100644 --- a/zips/zip-0243.rst +++ b/zips/zip-0243.rst @@ -2,8 +2,8 @@ ZIP: 243 Title: Transaction Signature Validation for Sapling - Owners: Jack Grigg - Daira-Emma Hopwood + Owners: Jack Grigg + Daira-Emma Hopwood Credits: Simon Liu Status: Final Category: Consensus diff --git a/zips/zip-0244.rst b/zips/zip-0244.rst index 7dce6b2e5..a553f7045 100644 --- a/zips/zip-0244.rst +++ b/zips/zip-0244.rst @@ -2,9 +2,9 @@ ZIP: 244 Title: Transaction Identifier Non-Malleability - Owners: Kris Nuttycombe - Daira-Emma Hopwood - Jack Grigg + Owners: Kris Nuttycombe + Daira-Emma Hopwood + Jack Grigg Status: Final Category: Consensus Created: 2021-01-06 @@ -453,9 +453,9 @@ Signature Digest A new per-input transaction digest algorithm is defined that constructs a hash that may be signed by a transaction creator to commit to the effects of the transaction. A signature digest is produced for each transparent input, each Sapling input, and each Orchard -action. For transparent inputs, this follows closely the algorithms from ZIP 143 [#zip-0143]_ -and ZIP 243 [#zip-0243]_. For shielded inputs, this algorithm has the exact same output -as the transaction digest algorithm, thus the txid may be signed directly. +action. This follows closely the algorithms from ZIP 143 [#zip-0143]_ and ZIP 243 [#zip-0243]_. +For transactions without transparent inputs, 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; each name referenced here will be described in detail below:: @@ -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-0245.rst b/zips/zip-0245.rst index fd55a7c90..b8f5aa390 100644 --- a/zips/zip-0245.rst +++ b/zips/zip-0245.rst @@ -2,8 +2,8 @@ ZIP: 245 Title: Transaction Identifier Digests & Signature Validation for Transparent Zcash Extensions - Owners: Kris Nuttycombe - Daira-Emma Hopwood + Owners: Kris Nuttycombe + Daira-Emma Hopwood Status: Draft Category: Consensus Created: 2021-01-13 diff --git a/zips/zip-0246.rst b/zips/zip-0246.rst new file mode 100644 index 000000000..b53fc797d --- /dev/null +++ b/zips/zip-0246.rst @@ -0,0 +1,657 @@ +:: + + ZIP: 246 + Title: Digests for the Version 6 Transaction Format + Owners: Arya + Conrado Gouvea + Daira-Emma Hopwood + Jack Grigg + Kris Nuttycombe + Status: Draft + Category: Consensus + Created: 2025-02-12 + License: MIT + + +=========== +Terminology +=========== + +The key words "MUST" and "MUST NOT" in this document are to be interpreted as described +in BCP 14 [#BCP14]_ when, and only when, they appear in all capitals. + +The terms "consensus branch", "epoch", and "network upgrade" in this document are to be +interpreted as described in ZIP 200. [#zip-0200]_ + +The term "field encoding" refers to the binary serialized form of a Zcash transaction +field, as specified in section 7.1 of the Zcash protocol specification +[#protocol-txnencoding]_. + + +======== +Abstract +======== + +This ZIP defines the sighash algorithms associated with the v6 transaction +format. + +This proposal also defines the new concept of "sighash algorithm versioning": +where previously each transaction version had a single associated sighash +algorithm, going forward it will be possible for signers to use any sighash +algorithm within the closed set specified for a given transaction version (and +made available in consensus via network upgrades). + +========== +Motivation +========== + +The motivation for sighash algorithm versioning is that we want to be able to +specify the V6 transaction format and signatures without knowing what the +signatures for atomic swaps in action bundles will need to commit to. This +allows for future signature hash algorithms to be specified for V6 transactions +that support signing parts of a transaction while leaving the remainder of the +transaction malleable, or that commit to additional state that nodes may start +tracking in a future upgrade and that is not part of an individual transaction +being signed. + +Being able to remove support for sighash algorithm versions makes it possible +to respond effectively in the case that a bug is found in a previously deployed +sighash algorithm. + +============ +Requirements +============ + +- Continue to support existing functionality of the protocol (e.g. multisig and + signing modes for transparent inputs). + +- It should be possible to update this ZIP with additional sighash algorithm + versions that might have divergent behavior with respect to previous + versions, after previous versions have been deployed in network upgrades. + +- It should be possible to disable support for sighash algorithm versions in + network upgrades. + +- At the time that one is making a signature, the set of valid sighash + algorithm versions is known to consensus. + +- Sighash version information is present alongside the signature. + +================ +Non-requirements +================ + +- Sighash algorithm versioning as defined in this ZIP does not need to + constrain how signature hashes are constructed for future transaction + versions. + +============= +Specification +============= + +------------------ +Sighash versioning +------------------ + +Rough summary: + +- Sighash versions are numbered starting from 0 for each tx version. +- v0 is by convention the "commit to all effecting data" sighash algorithm. Other + versions can commit to whatever makes sense for desired functionality within + that tx version. +- Consensus rules choose the digest algorithm for each signer based on + ``sighashVersion``. + +The sighash version is encoded as a single byte alongside any associated data +that the sighash algorithm version requires (for deterministically computing the +digest): + +``sighashInfo = [sighashVersion] || associatedData`` + +where ``associatedData`` is specific to the bundle it appears in. + +The following sighash algorithm versions are defined for v6 transactions: + ++--------------------+-------------------------------------------------------+ +| |:math:`\hspace{4.5em}` ``associatedData`` | ++--------------------+-------------+-------------+-------------+-------------+ +| ``sighashVersion`` | Transparent | Sapling | Orchard | Issuance | ++--------------------+-------------+-------------+-------------+-------------+ +| 0 |``[]`` |``[]`` |``[]`` |``[]`` | ++--------------------+-------------+-------------+-------------+-------------+ + +---------- +v0 Digests +---------- + +The v0 digests are based on the v5 transaction digest algorithm defined in +ZIP 244 [#zip-0244]_. + +TODO: Update the Authorizing Data Commitment below for the ``sighashInfo`` +changes to the tx format. + +TxId Digest +=========== + +The overall structure of the TxID digest is as follows; each name referenced +here will either be referenced or described in detail below:: + + txid_digest + ├── header_digest * + ├── transparent_digest + │   ├── prevouts_digest + │   ├── sequence_digest + │   └── outputs_digest + ├── sapling_digest + │   ├── sapling_spends_digest + │   │   ├── sapling_spends_compact_digest + │   │   └── sapling_spends_noncompact_digest + │   ├── sapling_outputs_digest * + │   │   ├── sapling_outputs_compact_digest * + │   │   └── sapling_outputs_noncompact_digest * + │   └── valueBalance + ├── orchard_digest * + │   ├── orchard_action_groups_digest * + │   │   ├── orchard_actions_compact_digest * + │   │   ├── orchard_actions_noncompact_digest * + │   │   ├── flagsOrchard + │   │   ├── anchorOrchard + │   │   ├── nAGExpiryHeight * + │   │   └── orchard_burn_digest * + │   └── valueBalanceOrchard + ├── issuance_digest * + │   ├── issuerLength * + │   ├── issuer * + │   └── issue_actions_digest * + │       ├── assetDescHash * + │       ├── issue_notes_digest * + │       └── flagsIssuance * + └── memo_digest * +    ├── nonce * +    └── memo_chunks_digest * +       └── memo_chunk_digest * + +Each node written as ``snake_case`` in this tree is a BLAKE2b-256 hash of its +children, initialized with a personalization string specific to that branch +of the tree. Nodes that are not themselves digests are written in ``camelCase``. +In the specification below, nodes of the tree are presented in depth-first order. + +The nodes with a ``*`` have new definitions given below. All other nodes have the +same definition as in ZIP 244 [#zip-0244]_. + +txid_digest +----------- +A BLAKE2b-256 hash of the following values :: + + T.1: header_digest (32-byte hash output) + T.2: transparent_digest (32-byte hash output) + T.3: sapling_digest (32-byte hash output) + T.4: orchard_digest (32-byte hash output) + T.5: issuance_digest (32-byte hash output) + T.6: memo_digest (32-byte hash output) + +The personalization field of this hash is set to:: + + "ZcashTxHash_" || CONSENSUS_BRANCH_ID + +``ZcashTxHash_`` has 1 underscore character. + +As in ZIP 244 [#zip-0244]_, CONSENSUS_BRANCH_ID is the 4-byte little-endian encoding of +the consensus branch ID for the epoch of the block containing the transaction. + +T.1: header_digest +`````````````````` +A BLAKE2b-256 hash of the following values :: + + T.1a: version (4-byte little-endian version identifier including overwinter 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 amount) + T.1g: burn_amount (8-byte little-endian burn amount) + +The personalization field of this hash is set to:: + + "ZTxIdHeadersHash" + +T.3b: sapling_outputs_digest +'''''''''''''''''''''''''''' +In the case that Sapling outputs are present, this digest is a BLAKE2b-256 hash of the +following values :: + + T.3b.i: sapling_outputs_compact_digest (32-byte hash) + T.3b.ii: sapling_outputs_noncompact_digest (32-byte hash) + +The personalization field of this hash is set to:: + + "ZTxIdSOutputHash" + +In the case that the transaction has Sapling spends but no Sapling outputs, +``sapling_outputs_digest`` is :: + + BLAKE2b-256("ZTxIdSOutputHash", []) + +T.3b.i: sapling_outputs_compact_digest +...................................... +A BLAKE2b-256 hash of the subset of Sapling output information included in the +ZIP-307 [#zip-0307]_ ``CompactBlock`` format for all Sapling shielded outputs +belonging to the transaction. For each output, the following elements are included +in the hash:: + + T.3b.i.1: cmu (field encoding bytes) + T.3b.i.2: ephemeral_key (field encoding bytes) + T.3b.i.3: enc_ciphertext (field encoding bytes) + +The personalization field of this hash is set to:: + + "ZTxId6SOutC_Hash" (1 underscore character) + +The field encodings are specified in ZIP 230 [#zip-0230-sapling-output-field-encodings]_. + +T.3b.ii: sapling_outputs_noncompact_digest +........................................... +A BLAKE2b-256 hash of the remaining subset of Sapling output information **not** included +in the ZIP 307 [#zip-0307]_ ``CompactBlock`` format, excluding zkproof data, for all +Sapling shielded outputs belonging to the transaction. For each output, the following +elements are included in the hash:: + + T.3b.ii.1: cv (field encoding bytes) + T.3b.ii.3: out_ciphertext (field encoding bytes) + +The personalization field of this hash is set to:: + + "ZTxId6SOutN_Hash" (1 underscore character) + +The field encodings are specified in ZIP 230 [#zip-0230-sapling-output-field-encodings]_. + +T.4: orchard_digest +``````````````````` +When OrchardZSA Actions Groups are present in the transaction, this digest is a BLAKE2b-256 hash of the following values:: + + T.4a: orchard_action_groups_digest (32-byte hash output) + T.4b: valueBalanceOrchard (64-bit signed little-endian) + +The personalization field of this hash is set to:: + + "ZTxIdOrchardHash" + +In the case that the transaction has no OrchardZSA Action Groups, ``orchard_digest`` is :: + + BLAKE2b-256("ZTxIdOrchardHash", []) + +T.4a: orchard_action_groups_digest +'''''''''''''''''''''''''''''''''' + +A BLAKE2b-256 hash of the subset of OrchardZSA Action Groups information for all OrchardZSA Action Groups belonging to the transaction. +For each Action Group, the following elements are included in the hash:: + + T.4a.i : orchard_actions_compact_digest (32-byte hash output) + T.4a.ii : orchard_actions_noncompact_digest (32-byte hash output) + T.4a.iii : flagsOrchard (1 byte) + T.4a.iv : anchorOrchard (32 bytes) + T.4a.v : nAGExpiryHeight (4 bytes) + T.4a.vi : orchard_burn_digest (32-byte hash output) + +The personalization field of this hash is set to:: + + "ZTxIdOrcActGHash" + +T.4a.i: orchard_actions_compact_digest +...................................... + +A BLAKE2b-256 hash of the subset of OrchardZSA Action information intended to be included in +an updated version of the ZIP-307 [#zip-0307]_ ``CompactBlock`` format for all OrchardZSA +Actions belonging to the Action Group. For each Action, the following elements are included +in the hash:: + + T.4a.i.1 : nullifier (field encoding bytes) + T.4a.i.2 : cmx (field encoding bytes) + T.4a.i.3 : ephemeralKey (field encoding bytes) + T.4a.i.4 : encCiphertext (field encoding bytes) + +The personalization field of this hash is set to:: + + "ZTxId6OActC_Hash" (1 underscore character) + +The field encodings are specified in ZIP 230 [#zip-0230-orchardzsa-action-description-orchardzsaaction]_. + +T.4a.ii: orchard_actions_noncompact_digest +.......................................... + +A BLAKE2b-256 hash of the remaining subset of OrchardZSA Action information **not** intended +for inclusion in an updated version of the the ZIP 307 [#zip-0307]_ ``CompactBlock`` +format, for all OrchardZSA Actions belonging to the Action Group. For each Action, +the following elements are included in the hash:: + + T.4a.ii.1 : cv (field encoding bytes) + T.4a.ii.2 : rk (field encoding bytes) + T.4a.ii.3 : outCiphertext (field encoding bytes) + +The personalization field of this hash is set to:: + + "ZTxId6OActN_Hash" (1 underscore character) + +The field encodings are specified in ZIP 230 [#zip-0230-orchardzsa-action-description-orchardzsaaction]_. + + +T.4a.vi: orchard_burn_digest +'''''''''''''''''''''''''''' + +A BLAKE2b-256 hash of the data from the burn fields of the transaction. For each tuple in +the $\mathsf{assetBurn}$ set, the following elements are included in the hash:: + + T.4b.i : assetBase (field encoding bytes) + T.4b.ii: valueBurn (64-bit unsigned little-endian) + +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 +$\mathsf{assetBurn}$ set is empty), the ``orchard_burn_digest`` is:: + + BLAKE2b-256("ZTxIdOrcBurnHash", []) + +The field encodings are specified in ZIP 230 [#zip-0230-orchardzsa-asset-burn-description]_. + + +T.5: issuance_digest +```````````````````` +A BLAKE2b-256 hash of the following values :: + + T.5a: issuerLength (field encoding bytes) + T.5b: issuer (field encoding bytes) + T.5c: issue_actions_digest (32-byte hash output) + +The personalization field of this hash is set to:: + + "ZTxIdSAIssueHash" + +In case the transaction has no issuance components, ``issuance_digest`` is:: + + BLAKE2b-256("ZTxIdSAIssueHash", []) + +The field encodings are specified in ZIP 230 [#zip-0230-transaction-format]_. + +T.5a: issue_actions_digest +'''''''''''''''''''''''''' +A BLAKE2b-256 hash of Issue Action information for all Issuance Actions belonging to the transaction. For each Action, the following elements are included in the hash:: + + T.5a.i : assetDescHash (field encoding bytes) + T.5a.ii : issue_notes_digest (32-byte hash output) + T.5a.iii: flagsIssuance (1 byte) + +The personalization field of this hash is set to:: + + "ZTxIdIssuActHash" + +The field encodings are specified in ZIP 230 [#zip-0230-issuance-action-description-issueaction]_. + +T.5a.i: issue_notes_digest +.......................... +A BLAKE2b-256 hash of Note information for all Issue Note Descriptions belonging to the Issuance Action. For each Note, the following elements are included in the hash:: + + T.5a.i.1: recipient (field encoding bytes) + T.5a.i.2: value (field encoding bytes) + T.5a.i.3: rho (field encoding bytes) + T.5a.i.4: rseed (field encoding bytes) + +The personalization field of this hash is set to:: + + "ZTxIdIAcNoteHash" + +In case the transaction has no Issue Notes, ``issue_notes_digest`` is:: + + BLAKE2b-256("ZTxIdIAcNoteHash", []) + +The field encodings are specified in ZIP 230 [#zip-0230-issue-note-description-issuenotedescription]_. + +T.6: memo_digest +```````````````` +A BLAKE2b-256 hash of the following values :: + + T.6a: nonce (field encoding bytes) + T.6b: memo_chunks_digest (32-byte hash output) + +The personalization field of this hash is set to:: + + "ZTxIdMemo___Hash" (3 underscore characters) + +In case the transaction has no memo chunks, ``memo_digest`` is:: + + BLAKE2b-256("ZTxIdMemo___Hash", []) + +The field encodings are specified in ZIP 230 [#zip-0230-transaction-format]_. + +T.6b: memo_chunks_digest +'''''''''''''''''''''''' +A BLAKE2b-256 hash of the concatenated ``memo_chunk_digest`` values of all memo chunks +within the memo bundle. + +The personalization field of this hash is set to:: + + "ZTxIdMemoCksHash" + +In the case that the transaction has no memo chunks, +``memo_chunks_digest`` is :: + + BLAKE2b-256("ZTxIdMemoCksHash", []) + +T.6b.i: memo_chunk_digest +......................... +A BLAKE2b-256 hash of the field encoding of a single encrypted Memo Chunk. + +The personalization field of this hash is set to:: + + "ZTxIdMemoCk_Hash" (1 underscore character) + +The field encodings are specified in ZIP 230 [#zip-0230-transaction-format]_. + + +Signature Digest +================ + +The per-input transaction digest algorithm to generate the signature digest in ZIP 244 [#zip-0244-sigdigest]_ is modified so that a signature digest is produced for each transparent input, each Sapling input, each OrchardZSA Action, and additionally for each Issuance Action. +The modifications replace the ``orchard_digest`` in ZIP 244 with a new ``orchard_digest``, and add a new branch, ``issuance_digest``, for the Issuance Action information. + +The overall structure of the hash is as follows. We omit the descriptions of the sections that do not change for the OrchardZSA protocol:: + + signature_digest + ├── header_digest + ├── transparent_sig_digest + ├── sapling_digest + ├── orchard_digest + ├── issuance_digest + └── memo_digest + +signature_digest +---------------- +A BLAKE2b-256 hash of the following values :: + + S.1: header_digest (32-byte hash output) + S.2: transparent_sig_digest (32-byte hash output) + S.3: sapling_digest (32-byte hash output) + S.4: orchard_digest (32-byte hash output) + S.5: issuance_digest (32-byte hash output) + S.6: memo_digest (32-byte hash output) + +The personalization field remains the same as in ZIP 244 [#zip-0244]_, namely:: + + "ZcashTxHash_" || CONSENSUS_BRANCH_ID + +``ZcashTxHash_`` has 1 underscore character. + +S.4: orchard_digest +``````````````````` +Identical to that specified for the transaction identifier. + +S.5: issuance_digest +```````````````````` +Identical to the ``issuance_digest`` specified for the transaction identifier. + +S.6: memo_digest +```````````````` +Identical to that specified for the transaction identifier. + + +Authorizing Data Commitment +=========================== + +The transaction digest algorithm defined in ZIP 244 [#zip-0244-authcommitment]_ which commits to the authorizing data of a transaction is modified by the OrchardZSA protocol to have the structure specified in this section. +There is a new branch added for issuance information, and the ``orchard_auth_digest`` in ZIP 244 is altered to account for the presence of Action Groups. + +We omit the descriptions of the sections that do not change for the OrchardZSA protocol:: + + auth_digest + ├── transparent_auth_digest + ├── sapling_auth_digest + ├── orchard_auth_digest + └── issuance_auth_digest + +The pair (Transaction Identifier, Auth Commitment) constitutes a commitment to all the data of a serialized transaction that may be included in a block. + +auth_digest +----------- +A BLAKE2b-256 hash of the following values :: + + A.1: transparent_auth_digest (32-byte hash output) + A.2: sapling_auth_digest (32-byte hash output) + A.3: orchard_auth_digest (32-byte hash output) + A.4: issuance_auth_digest (32-byte hash output) + +The personalization field of this hash remains the same as in ZIP 244. + +Note that while the structure of ``sapling_auth_digest`` remains the same as in ZIP 244, the field encodings of some of its components +(viz. ``spend_auth_sigs`` and ``binding_sig``) differ due to changes to their field encodings in ZIP 230 [#zip-0230-transaction-format]_. + + +A.1: transparent_auth_digest +```````````````````````````` + +In the case that the transaction contains transparent inputs, this is a BLAKE2b-256 hash of the following values for each transparent input:: + + A.1a: TransparentSighashInfo (field encoding bytes) + A.1b: scriptSig (field encoding bytes) + +The personalization field of this hash is:: + + "ZTxAuthTransHash" + +In the case that the transaction has no transparent inputs, ``transparent_auth_digest`` is:: + + BLAKE2b-256("ZTxAuthTransHash", []) + +The field encoding of ``TransparentSighashInfo`` is specified in ZIP 230 [#zip-0230-transparent-sighash-info-field-encodings]_. + +A.3: orchard_auth_digest +```````````````````````` + +In the case that OrchardZSA Action Groups are present, this is a BLAKE2b-256 hash of the following values:: + + A.3a: orchard_action_groups_auth_digest (32-byte hash output) + A.3b: bindingSigOrchard (field encoding bytes) + +The personalization field of this hash is the same as in ZIP 244, that is:: + + "ZTxAuthOrchaHash" + +In case that the transaction has no OrchardZSA Action Groups, ``orchard_auth_digest`` is:: + + BLAKE2b-256("ZTxAuthOrchaHash", []) + +The field encodings are specified in ZIP 230 [#zip-0230-transaction-format]_. +Note that this means the encoding of ``bindingSigOrchard`` differs from that used in ZIP 244. + +A.3a: orchard_action_groups_auth_digest +''''''''''''''''''''''''''''''''''''''' + +A BLAKE2b-256 hash of the subset of OrchardZSA Action Group information for all OrchardZSA Action Groups belonging to the transaction. +For each OrchardZSA Action Group, this is a BLAKE2b-256 hash of the following values:: + + A.3a.i: proofsOrchard (field encoding bytes) + A.3a.ii: orchard_zsa_spend_auth_sigs_auth_digest (32-byte hash output) + +The personalization field of this hash is set to:: + + "ZTxAuthOrcAGHash" + +The field encodings are specified in ZIP 230 [#zip-0230-orchardzsa-action-group-description]_. + +A.3a.ii: orchard_zsa_spend_auth_sigs_auth_digest +................................................ + +This is a BLAKE2b-256 hash of the concatenation of ``OrchardSignature`` encodings for the spend authorization signature of each OrchardZSA Action in the OrchardZSA Action Group (i.e. the contents of the ``vSpendAuthSigsOrchard`` field of the ``ActionGroupDescription``):: + + A.3a.ii.1: spendAuthSigsOrchard (field encoding bytes) + +The personalization field of this hash is set to:: + + "ZTxAuthOrSASHash" + +The encoding of ``OrchardSignature`` is specified in ZIP 230 [#zip-0230-orchard-signature-orchardsignature]_. +Note that this means the encoding of ``spendAuthSigsOrchard`` differs from that used in ZIP 244. + +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) + +The personalization field of this hash is set to:: + + "ZTxAuthZSAOrHash" + +In the case that the transaction has no Orchard Actions, ``issuance_auth_digest`` is :: + + BLAKE2b-256("ZTxAuthZSAOrHash", []) + +The field encodings are specified in ZIP 230 [#zip-0230-transaction-format]_. + + +========= +Rationale +========= + +TBD + +----------------------------------------------------------------- +Rationale for ``auth_digest`` domain separator reuse from ZIP 244 +----------------------------------------------------------------- + +An authorizing data commitment cannot be used without the context of a transaction ID. +That is, it cannot be used independently from the ``version`` and ``versionGroupId`` fields committed to within the transaction ID. +Therefore, reusing the same personalization values within the authorizing data commitment tree as in ZIP 244 is safe, even though the structure may have changed. + +======================== +Reference implementation +======================== + +TBD + + +========== +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 2025.6.2 or later [NU6.1] `_ +.. [#protocol-spenddesc] `Zcash Protocol Specification, Version 2025.6.2 [NU6.1]. Section 4.4: Spend Descriptions `_ +.. [#protocol-outputdesc] `Zcash Protocol Specification, Version 2025.6.2 [NU6.1]. Section 4.5: Output Descriptions `_ +.. [#protocol-actiondesc] `Zcash Protocol Specification, Version 2025.6.2 [NU6.1]. Section 4.6: Action Descriptions `_ +.. [#protocol-txnencoding] `Zcash Protocol Specification, Version 2022.3.8. Section 7.1: Transaction Encoding and Consensus `_ +.. [#zip-0200] `ZIP 200: Network Upgrade Mechanism `_ +.. [#zip-0230-transaction-format] `ZIP 230: Version 6 Transaction Format — Specification: Transaction Format `_ +.. [#zip-0230-orchardzsa-action-group-description] `ZIP 230: Version 6 Transaction Format — Specification: OrchardZSA Action Group Description `_ +.. [#zip-0230-orchardzsa-action-description-orchardzsaaction] `ZIP 230: Version 6 Transaction Format — Specification: OrchardZSA Action Description `_ +.. [#zip-0230-orchardzsa-asset-burn-description] `ZIP 230: Version 6 Transaction Format — Specification: OrchardZSA Asset Burn Description `_ +.. [#zip-0230-sapling-output-field-encodings] `ZIP 230: Version 6 Transaction Format — Specification: Sapling Output Description (OutputDescriptionV6) `_ +.. [#zip-0230-transparent-sighash-info-field-encodings] `ZIP 230: Version 6 Transaction Format — Specification: Transparent Sighash Information `_ +.. [#zip-0230-orchard-signature-orchardsignature] `ZIP 230: Version 6 Transaction Format — Specification: Orchard Signature `_ +.. [#zip-0230-issuance-action-description-issueaction] `ZIP 230: Version 6 Transaction Format — Specification: Issuance Action Description `_ +.. [#zip-0230-issue-note-description-issuenotedescription] `ZIP 230: Version 6 Transaction Format — Specification: Issue Note Description `_ +.. [#zip-0244] `ZIP 244: Transaction Identifier Non-Malleability `_ +.. [#zip-0244-sigdigest] `ZIP 244: Transaction Identifier Non-Malleability: Signature Digest `_ +.. [#zip-0244-authcommitment] `ZIP 244: Transaction Identifier Non-Malleability: Authorizing Data Commitment `_ +.. [#zip-0307] `ZIP 307: Light Client Protocol for Payment Detection `_ diff --git a/zips/zip-0250.rst b/zips/zip-0250.rst index 0c0757a8b..54d2785d3 100644 --- a/zips/zip-0250.rst +++ b/zips/zip-0250.rst @@ -2,7 +2,7 @@ ZIP: 250 Title: Deployment of the Heartwood Network Upgrade - Owners: Daira-Emma Hopwood + Owners: Daira-Emma Hopwood Status: Final Category: Consensus / Network Created: 2020-02-28 diff --git a/zips/zip-0251.rst b/zips/zip-0251.rst index c906e0b69..bd0584fde 100644 --- a/zips/zip-0251.rst +++ b/zips/zip-0251.rst @@ -2,7 +2,7 @@ ZIP: 251 Title: Deployment of the Canopy Network Upgrade - Owners: Daira-Emma Hopwood + Owners: Daira-Emma Hopwood Status: Final Category: Consensus / Network Created: 2020-02-28 diff --git a/zips/zip-0252.rst b/zips/zip-0252.rst index 93804a61b..6a007b2d1 100644 --- a/zips/zip-0252.rst +++ b/zips/zip-0252.rst @@ -2,8 +2,8 @@ ZIP: 252 Title: Deployment of the NU5 Network Upgrade - Owners: teor - Daira-Emma Hopwood + Owners: Daira-Emma Hopwood + Original-Authors: Teor Status: Final Category: Consensus / Network Created: 2021-02-23 diff --git a/zips/zip-0253.md b/zips/zip-0253.md index 35e497475..f2dd1da5b 100644 --- a/zips/zip-0253.md +++ b/zips/zip-0253.md @@ -2,7 +2,7 @@ ZIP: 253 Title: Deployment of the NU6 Network Upgrade Owners: Arya - Status: Proposed + Status: Final Category: Consensus / Network Created: 2024-07-17 License: MIT @@ -69,9 +69,9 @@ NU6 does not define a new transaction version or impose a new minimum transactio [^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 or later](protocol/protocol.pdf) +[^protocol]: [Zcash Protocol Specification, Version 2025.6.2 or later [NU6.1]](protocol/protocol.pdf) -[^protocol-networks]: [Zcash Protocol Specification, Version 2024.5.1 [NU6]. Section 3.12: Mainnet and Testnet](protocol/protocol.pdf#networks) +[^protocol-networks]: [Zcash Protocol Specification, Version 2025.6.2 [NU6.1]. Section 3.12: Mainnet and Testnet](protocol/protocol.pdf#networks) [^zip-0200]: [ZIP 200: Network Upgrade Mechanism](zip-0200.rst) diff --git a/zips/zip-0254.md b/zips/zip-0254.md new file mode 100644 index 000000000..0c2891d34 --- /dev/null +++ b/zips/zip-0254.md @@ -0,0 +1,15 @@ + + ZIP: 254 + Title: Deployment of the NU7 Network Upgrade (Withdrawn) + Owners: Arya + Status: Withdrawn + Category: Consensus / Network + Created: 2024-10-31 + License: MIT + Discussions-To: + +The deployment ZIP draft for NU7 is [^draft-arya-deploy-nu7]. + +# References + +[^draft-arya-deploy-nu7]: [draft-arya-deploy-nu7: Deployment of the NU7 Network Upgrade](draft-arya-deploy-nu7.md) diff --git a/zips/zip-0255.md b/zips/zip-0255.md new file mode 100644 index 000000000..d838c3cd0 --- /dev/null +++ b/zips/zip-0255.md @@ -0,0 +1,91 @@ + + ZIP: 255 + Title: Deployment of the NU6.1 Network Upgrade + Owners: Daira-Emma Hopwood + Credits: Arya + Status: Proposed + Category: Consensus / Network + Created: 2025-05-06 + License: MIT + Discussions-To: + + +# 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 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 + +This proposal defines the deployment of the NU6.1 network upgrade. + + +# Specification + +## NU6.1 deployment + +The primary sources of information about NU6.1 consensus protocol changes are: + +* The Zcash Protocol Specification [^protocol]. +* ZIP 200: Network Upgrade Mechanism [^zip-0200]. +* ZIP 271: Deferred Dev Fund Lockbox Disbursement [^zip-0271]. +* ZIP 1016: Community And Coinholder Funding Model [^zip-1016]. + +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 +NU6.1 upgrade: + +CONSENSUS_BRANCH_ID +: `0x4DEC4DF0` + +ACTIVATION_HEIGHT (NU6.1) +: Testnet: 3536500 +: Mainnet: 3146400 + +MIN_NETWORK_PROTOCOL_VERSION (NU6.1) +: Testnet: `170130` +: Mainnet: `170140` + +For each network (Testnet and Mainnet), nodes compatible with NU6.1 activation +on that network MUST advertise a network protocol version that is greater +than or equal to the MIN_NETWORK_PROTOCOL_VERSION (NU6.1) for that activation. + +## Backward compatibility + +Prior to the network upgrade activating on each network, NU6.1 and pre-NU6.1 +nodes are compatible and can connect to each other. However, NU6.1 nodes will +have a preference for connecting to other NU6.1 nodes, so pre-NU6.1 nodes will +gradually be disconnected in the run up to activation. + +Once the network upgrades, even though pre-NU6.1 nodes can still accept the +numerically larger protocol version used by NU6.1 as being valid, NU6.1 nodes +will always disconnect peers using lower protocol versions. + + +# 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"](https://www.rfc-editor.org/info/bcp14) + +[^protocol]: [Zcash Protocol Specification, Version 2025.6.0 or later](protocol/protocol.pdf) + +[^protocol-networks]: [Zcash Protocol Specification, Version 2025.6.0 [NU6.1 proposal]. Section 3.12: Mainnet and Testnet](protocol/protocol.pdf#networks) + +[^zip-0200]: [ZIP 200: Network Upgrade Mechanism](zip-0200.rst) + +[^zip-0201]: [ZIP 201: Network Peer Management for Overwinter](zip-0201.rst) + +[^zip-0271]: [ZIP 271: Deferred Dev Fund Lockbox Disbursement](zip-0271.md) + +[^zip-1016]: [ZIP 1016: Community and Coinholder Funding Model](zip-1016.md) diff --git a/zips/zip-0260.md b/zips/zip-0260.md new file mode 100644 index 000000000..ed2e16401 --- /dev/null +++ b/zips/zip-0260.md @@ -0,0 +1,6 @@ + ZIP: 260 + Title: Extending Block Messages with Additional Authentication Data + Credits: teor + Status: Reserved + Category: Network + Discussions-To: diff --git a/zips/zip-0270.md b/zips/zip-0270.md new file mode 100644 index 000000000..c632181ce --- /dev/null +++ b/zips/zip-0270.md @@ -0,0 +1,12 @@ + + ZIP: 270 + Title: Key Rotation for Tracked Signing Keys + Owners: Jack Grigg + Kris Nuttycombe + Daira-Emma Hopwood + Arya + Status: Reserved + Category: Consensus + Created: 2025-09-16 + License: MIT + Discussions-To: diff --git a/zips/zip-0271.md b/zips/zip-0271.md new file mode 100644 index 000000000..d8ed8edf6 --- /dev/null +++ b/zips/zip-0271.md @@ -0,0 +1,526 @@ + ZIP: 271 + Title: Dev Fund Extension and One-Time Disbursement + Owners: Daira-Emma Hopwood + Kris Nuttycombe + Jack Grigg + Status: Proposed + Category: Consensus / Process + Created: 2025-02-19 + License: MIT + Pull-Request: + + + + +# Terminology + +The key words "MUST", "MUST NOT", and "RECOMMENDED" in this document are +to be interpreted as described in BCP 14 [^BCP14] when, and only when, they +appear in all capitals. + +# Abstract + +This ZIP proposes an extension of protocol-based development funding, in the +context of multiple alternatives for distributing funds that have accrued to +the Deferred Dev Fund Lockbox. This proposal is intended to be evaluated in the +context of the Community And Coinholder Funding Model [^zip-1016] proposal. + +At a high level, this ZIP proposes: +* A one-time disbursement of the full contents of the lockbox to a transparent + P2SH multisig address, at the time of the activation of this ZIP. The + key-holders of that address are then responsible for distributing the + resulting funds in the form of development grants, according to the rules set + by [^zip-1016]. +* Extension of protocol-based development funding blocks starting from the + scheduled end height of the current ``FS_DEFERRED`` and ``FS_FPF_ZCG`` + funding streams defined in ZIP 1015 [^zip-1015-funding-streams]. +* A variety of different mechanisms that may be used for distributing funds + that accrue in the lockbox during the period of the extension. + +# Requirements + +* Funds are held in a multisig P2SH address that is resistant to compromise + of some of the parties' keys, up to a given threshold. +* No single party's non-cooperation or loss of keys is able to cause any + Protocol-defined Ecosystem Funding to be locked up unrecoverably. +* The funds previously accrued to the Deferred Dev Fund Lockbox as of the + activation height of this ZIP will be usable immediately on activation. + +# Specification + +This ZIP proposes the creation of a new Zcash Development Fund. The balance of +this Fund consists of the contents of the ZIP 1015 Deferred Development Fund +Lockbox as of the activation height of this ZIP, plus any funds that later +accrue to the lockbox. + +## One-time lockbox disbursement + +The coinbase transaction of the activation block of this ZIP MUST include one or more +lockbox disbursement output(s) to a 2-of-3 P2SH multisig with keys held by the +following "Key-Holder Organizations": Zcash Foundation, the Electric Coin Company, +and Shielded Labs. + +Let $\mathsf{ZIP271ActivationHeight}$ be the activation height of NU6.1 on the +relevant network (Mainnet or Testnet) as defined in [^zip-0255]. + +Let $\mathsf{ZIP271DisbursementAmount}$ be the zatoshi amount in the Deferred +Dev Fund Lockbox as of the end of the block preceding the activation height. +($\mathsf{ZIP271DisbursementAmount}$ can be predicted in advance given that height.) + +Let $\mathsf{ZIP271DisbursementChunks} = 10$. + +Let $\mathsf{ZIP271DisbursementAddress}$ be $“\texttt{t3ev37Q2uL1sfTsiJQJiWJoFzQpDhmnUwYo}”$ +on Mainnet and $“\texttt{t2RnBRiqrN1nW4ecZs1Fj3WWjNdnSs4kiX8}”$ on Testnet. + +The additional coinbase outputs MUST pay a sum of $\mathsf{ZIP271DisbursementAmount}$ +zatoshi, split into $\mathsf{ZIP271DisbursementChunks}$ equal outputs, to the address +represented by $\mathsf{ZIP271DisbursementAddress}$, each using a standard P2MS script +as specified in ZIP 48 [^zip-0048]. $\mathsf{ZIP271DisbursementAmount}$ zatoshi +are added to the transparent transaction value pool of the coinbase transaction +to fund the output(s), and deducted from the balance of the Deferred Dev Fund Lockbox. +The latter deduction occurs before any other change to the Deferred Dev Fund +Lockbox balance in the transaction, and MUST NOT cause the Deferred Dev Fund +Lockbox balance to become negative at that point. + +Note: The value $\mathsf{ZIP271DisbursementAmount}$ needs to be precalculated +so that it is known at the point when the relevant consensus check is done in +node implementations. + +$\mathsf{ZIP271DisbursementAmount}$ MUST be $78750\_0000\_0000$ zatoshi on both +Testnet and Mainnet (i.e. 78,750 TAZ on Testnet, 78,750 ZEC on Mainnet). + +Non-normative note: The BIP 388 wallet policy [^bip-0388] for the Mainnet +$\mathsf{ZIP271DisbursementAddress}$ is + + Wallet descriptor template: sh(sortedmulti(2,@0/**,@1/**,@2/**)) + Key information vector: + [2efd03f5/48'/133'/0'/133000']xpub6ERFr6gbA9jHXGj9Qxebua1Fj78ADQJPMyFgP78rUz9kdr4kMMXjkbGQSk6GPD8aYsyPPDXUqftNbuW3jKcHPP1hBa1paPv9FNMLqCqWsNz + [281d1aeb/48'/133'/0'/133000']xpub6FNah9qMu1jMRQdsFXXYWfWXXMhsdP3KRAexTBnnMykskq7VWQGm4439zUwAxNPGVfi7nuL5UWhLwGrHmfnxvLFEx3coS2tjYrezDavvh3T + [e1c4c104/48'/133'/0'/133000']xpub6E2qmBdHpQu9yJ3HvYJ8p8FVYMEWG4a6St2Knd7vfQC9jm7gyWZdvxMo6FafcKvjxiSmd61NW2Mu7udKDbcA5DAVzVdNU6JPrY2uhtPXxE4 + +### Rationale for using P2MS outputs + +
    + +Rationale + + +The keyholders may desire the grant-filling transactions use transparent inputs or +shielded inputs. Regardless of their desire, the one-time disbursement must at some +point go through a shielded pool, because this ZIP does not propose altering the +consensus rules for spendability of transparent coinbase outputs. That would be far +too complex a change for the intended scope. + +This means that by using P2MS (i.e. P2SH multisig) outputs in consensus, the +Key-Holder Organizations will need to spend each chunk of the one-time disbursement +completely into a shielded output. This spend would presumably be to a FROST address +in order to maintain consistent security position over the lockbox funds; perhaps +publishing the viewing key to maintain visibility. + +An alternative proposal could require the one-time disbursement to directly create +a shielded output to the FROST address. This would mean that the Key-Holder +Organizations could immediately start disbursing grants (although the 100-block +coinbase maturity is not particularly onerous). + +This ZIP instead uses P2MS outputs for two reasons: + +* Using a shielded output would place a requirement on the miner (or mining pool) + to be able to create shielded coinbase outputs. Technically that requirement + is already in the consensus rules, but it has never before been exercised, + since no Funding Stream has been defined with a shielded address. +* Using a shielded output in the context of this ZIP would mean that the FROST + address needs to be derived well in advance of NU activation. At the time of + writing (May 2025), ZIP 312 does not specify key generation, and it would be + undesirable to couple the specification process for that to this ZIP. P2SH + multisig addresses by comparison have a relatively stable and well understood + format and generation process. + +The one-time disbursement is split into 10 P2MS outputs in order to give the +Key-Holder Organisations more flexibility to shield only part of the disbursement +at a time. +
    + +### Changes to the Zcash Protocol Specification + +#### § 4.17 ‘Chain Value Pool Balances’ [^protocol-chainvaluepoolbalances] + +Change: + +> Define $\mathsf{totalDeferredOutput}$ as in +> § 7.8 ‘Calculation of Block Subsidy, Funding Streams, and Founders’ Reward’. +> +> Then, consistent with [[ZIP-207]](zip-0207), 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})$. +> +> Non-normative notes: +> * $\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. + +to + +> Define $\mathsf{totalDeferredOutput}$ and $\mathsf{totalDeferredInput}$ as in § 7.8. +> +> Then, consistent with [[ZIP-207]](zip-0207), 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}) - \mathsf{totalDeferredInput}(\mathsf{h})$$ +> +> Consensus rule: If the deferred development fund chain value pool balance would +> become negative in the block chain created as a result of accepting a block, then +> all nodes MUST reject the block as invalid. +> +> Non-normative notes: +> * $\mathsf{totalDeferredOutput}(\mathsf{h})$ is necessarily zero for heights +> $\mathsf{h}$ prior to NU6 activation. +> * $\mathsf{totalDeferredInput}(\mathsf{h})$ is necessarily zero for heights +> $\mathsf{h}$ prior to NU6.1 activation. + +#### § 7.1.2 ‘Transaction Consensus Rules’ [^protocol-txnconsensus] + +Change: + +> * A transaction MUST NOT spend a transparent output of a coinbase transaction +> from a block less than 100 blocks prior to the spend. Note that transparent +> outputs of coinbase transactions include Founders’ Reward outputs and +> transparent funding stream outputs. + +to + +> * A transaction MUST NOT spend a transparent output of a coinbase transaction +> from a block less than 100 blocks prior to the spend. Note that transparent +> outputs of coinbase transactions include Founders’ Reward outputs, +> transparent funding stream outputs [[ZIP-207]](zip-0207), and lockbox +> disbursement outputs [ZIP-271]. + +#### § 7.8 ‘Calculation of Block Subsidy, Funding Streams, and Founders’ Reward’ [^protocol-subsidies] + +Change the section title to include "Lockbox Disbursement". + +Add the following definitions: + +> Let $\mathsf{ZIP217ActivationHeight}$ and $\mathsf{ZIP271DisbursementAmount}$ +> be as defined in [ZIP-271]. + +and + +> $\mathsf{totalDeferredInput}(\mathsf{height}) := \begin{cases} +> \mathsf{ZIP271DisbursementAmount},&\!\!\text{if } \mathsf{height} = \mathsf{ZIP217ActivationHeight} \\ +> 0,&\!\!\text{otherwise}. +> \end{cases}$ + +#### § 7.10 ‘Payment of Funding Streams’ [^protocol-fundingstreams] + +Change the section title to ‘Payment of Funding Streams, Deferred Lockbox, and Lockbox Disbursement’. + +Add a new paragraph at the start of the section: + +> [[ZIP-207]](zip-0207) defines a consensus mechanism to require coinbase transactions +> to include funding stream outputs, intended to provide funds from issuance for Zcash +> development. [[ZIP-2001]](zip-2001) extended this mechanism to support directing funds +> from issuance into a reserve, the deferred development fund lockbox. [[ZIP-271]](zip-271) +> defines a one-time disbursal of funds from this lockbox in order to support the +> Community And Coinholder Funding Model [[ZIP-1016]](zip-1016). + +Add the following definition: + +> Let $\mathsf{ZIP271ActivationHeight}$, $\mathsf{ZIP271DisbursementAmount}$, +> $\mathsf{ZIP271DisbursementChunks}$, and $\mathsf{ZIP271DisbursementAddress}$ be as +> defined for the relevant network (Mainnet or Testnet) in [[ZIP-271]](zip-271). + +Change: + +> Consensus rule: [Canopy onward] 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 $\mathsf{DeferredPool}$ 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. +> +> * The prescribed way to [...] + +to + +> Consensus rule: [Canopy onward] In each block with coinbase transaction $\mathsf{cb}$ +> at block height $\mathsf{height}$, $\mathsf{cb}$ MUST contain at least the given number +> of distinct outputs for each of the following: +> +> * for each funding stream $\mathsf{fs}$ active at that block height with a recipient +> identifier other than $\mathsf{DeferredPool}$ given by $\mathsf{fs.Recipient}(\mathsf{height})$, +> one output that pays $\mathsf{fs.Value}(\mathsf{height})$ zatoshi in the prescribed way +> to the address represented by that recipient identifier. +> * [NU6.1 onward] if the block height is $\mathsf{ZIP271ActivationHeight}$, +> $\mathsf{ZIP271DisbursementChunks}$ equal outputs paying a total of +> $\mathsf{ZIP271DisbursementAmount}$ zatoshi in the prescribed way to the +> Key-Holder Organizations’ P2SH multisig address represented by +> $\mathsf{ZIP271DisbursementAddress}$, as specified by [[ZIP-271]](zip-271). +> +> The term “prescribed way” is defined as follows: +> +> * The prescribed way to [...] + +Change the reference to the definition of standard redeem script hashes for P2SH multisig +addresses from the "Pay To Script Hash (P2SH) — Multisig" section of the Bitcoin Developer +Documentation [^Bitcoin-Multisig], to ZIP 48 [^zip-0048]. (This is a clarification, and +is not intended to change the redeem scripts for existing P2SH addresses defined by +consensus before NU6.1.) + +Change the second bullet point defining the prescribed way to pay a Sapling payment +address so that it also applies to Orchard, i.e.: + +> * The prescribed way to pay a Sapling or Orchard payment address is defined in +> [[ZIP-213]](zip-213), using the post-Heartwood consensus rules specified for +> Sapling and Orchard outputs of coinbase transactions in +> § 7.1.2 ‘Transaction Consensus Rules’ [^protocol-txnconsensus]. + +Clarify the notes as follows: + +> * The funding stream addresses are not treated specially in any other way, and +> there can be other outputs to them, in coinbase transactions or otherwise. +> In particular, it is valid for a coinbase transaction to have other outputs, +> possibly to the same address, that do not meet the criterion in the above +> consensus rule, as long as there is at least the given number of distinct +> outputs that meet it, disjointly for each funding item. +> * For clarification, if there are multiple active funding streams or lockbox +> disbursements with the same recipient identifier and/or value, there MUST be +> at least the given number of distinct outputs for each of them. +> * Up to and including NU6.1 there have been no funding streams or lockbox +> disbursements defined with a shielded payment address as a recipient. +> That might change in future, so implementations are encouraged to support +> Sapling and Orchard outputs as recipients, as permitted by [[ZIP-213]](zip-213) +> and [[ZIP-207]](zip-207). + +#### § 7.10.1 ‘ZIP 214 Funding Streams’ [^protocol-zip214fundingstreams] + +Add the Mainnet and Testnet funding streams from Revision 2 of ZIP 214 +[^zip-0214-funding-streams] to this section. + +## Extension to the lockbox funding stream + +The ``FS_DEFERRED`` lockbox funding stream is set to receive 12% of the block subsidy and +is extended by 1,260,000 blocks on both Mainnet and Testnet. +This ZIP activates before or on the first block after the end of current dev fund as of +this writing and specified in [^zip-1015-funding-streams], and will extend ``FS_DEFERRED`` on +Mainnet until block height 4406400. + +### Rationale for lockbox extension + +
    + +Rationale + + +Performing a one-time disbursement to a P2SH multisig address will provide a +source of grant funding for a limited period, allowing time for a lockbox +disbursement mechanism to be specified and deployed, as originally intended by +ZIP 1015 [^zip-1015]. + +In particular, this provides an opportunity for transaction format changes that +may be required for such a mechanism to be included in the v6 transaction +format [^zip-0230]. It is desirable to limit the frequency of transaction +format changes because such changes are disruptive to the ecosystem. It is not +necessary that protocol rules for disbursement actually be implemented until +after the transaction format changes are live on the network. It is RECOMMENDED +that any such transaction format changes be included in the upcoming v6 +transaction format in order to avoid such disruption. + +By implementing a one-time disbursement along with a continuation of the +``FS_DEFERRED`` stream, we prioritize both the availability of grant funding +and the implementation of a more flexible and secure mechanism for disbursement +from the lockbox — making it possible to address the need to rotate keys and/or +alter the set of key holders in a way that reverting to hard-coded output +addresses for repeated disbursements would not. +
    + +# Privacy and Security Implications + +As development funding is a public good on the Zcash network, there are not +relevant privacy concerns related to this proposal; all disbursement +(but not necessarily subsequent distribution) of development funds is +intentionally transparent and auditable by any participant in the network. + +## Security implications of the One-Time Lockbox Disbursement + +After the activation block of this ZIP has been mined, all development funds +previously accrued to the in-protocol lockbox will be held instead by a 2-of-3 +multisig address. The key-holders for this address will have the capability to +spend these funds. Compromise or loss of 2 of these 3 keys would result in +total loss of funds; as such, in the event of the compromise or loss of a +single key, the Key-Holders MUST establish a new multisig key set and address, +and transfer remaining unspent funds held by the original address before +additional loss or compromise occurs. + +Because this is a one-time disbursement, additional key rotation infrastructure +is not required. + +## Security implications for extension of the lockbox funding stream + +Funds will continue to securely accrue to the Deferred Development Lockbox +until a disbursement mechanism for the lockbox is implemented in a future +network upgrade. Such a disbursement mechanism should be designed to include an +in-protocol option for key rotation, such that it is not necessary to perform a +network upgrade to recover from key loss or compromise, or to change the size +of the signing set or the number of signatures required to reach threshold. + +# Previously considered alternatives + +The following two variables were defined for use in this ZIP: + +* $\mathsf{stream\_value}$: the percentage of the block subsidy to send to + a new funding stream, as described in the options below. +* $\mathsf{stream\_end\_height}$: The ending block height of that stream. + +## Option 1: Extend the lockbox funding stream + +This was the selected option; the section [Extensions to the lockbox funding stream](#extensiontothelockboxfundingstream) +was previously referred to as "Option 1" of this ZIP. ZIP 1016 [^zip-1016] set +the $\mathsf{stream\_value}$ parameter to 12%, and the +$\mathsf{stream\_end\_height}$ parameter to Mainnet block height 4406400, equal +to that of the Zcash Community Grants stream so that both streams end at +Zcash's 3rd halving. + +## Option 2: Revert to hard-coded output address + +A new funding stream consisting of $\mathsf{stream\_value}\%$ of the block +subsidy is defined to begin when the existing ZIP 1015 funding streams +[^zip-1015-funding-streams] end. The new streams will distribute funds to a +3-of-5 P2SH multisig with keys held by the same Key-Holder Organizations as +above. The resulting Fund is considered to include both this stream of funds, +and funds from the one-time lockbox disbursement described above. + +Option 2 can be realized by either of the following mechanisms: + +### Mechanism 2a: Classic funding stream + +A new funding stream is defined that pays directly to the above-mentioned 3-of-5 +multisig address on a block-by-block basis. It is defined to start at the end +height of the existing ``FS_DEFERRED`` funding stream and end at +$\mathsf{stream\_end\_height}$ and consists of $\mathsf{stream\_value}\%$ of the +block subsidy. + +### Mechanism 2b: Periodic lockbox disbursement + +Constant parameter $N = 35000$ blocks $= +\mathsf{PostBlossomHalvingInterval}/48$ (i.e. approximately one month of +blocks). + +The ``FS_DEFERRED`` lockbox funding stream is extended to end at height +$\mathsf{stream\_end\_height}$ and has its per-block output value set to +$\mathsf{stream\_value}\%$. A consensus rule is added to disburse from the +Deferred Dev Fund Lockbox to a 2-of-3 P2SH multisig with keys held by the same +Key-Holder Organizations as above, starting at block height +$\mathsf{activation\_height} + N$ and continuing at periodic intervals of $N$ +blocks until $\mathsf{stream\_end\_height}$. Each disbursement empties the +lockbox. + +This is equivalent to specifying +$\frac{\mathstrut\mathsf{stream\_end\_height} \,-\, \mathsf{activation\_height}}{N}$ [One-time lockbox disbursement]s, +that all output to the same address. + +#### Rationale for periodic disbursement + +
    + +Rationale + + +Classic funding streams [^zip-0207] produce many small output values, due to +only being able to direct funds from a single block's subsidy at a time. This +creates operational burdens to utilizing the funds — in particular due to block +and transaction sizes limiting how many outputs can be combined at once, which +increases the number of required transactions and correspondingly the overall +fee. + +The periodic lockbox disbursement mechanism can produce the same effective +funding stream, but with aggregation performed for free: the output to the +funding stream recipient is aggregated into larger outputs every $N$ blocks. In +the specific case of Mechanism 2b, the recipient multisig address would receive +around 40 outputs, instead of around 1,300,000. +
    + +## Security implications for Mechanism 2a + +As of the activation height of this ZIP, development funds will begin accruing +as additional outputs spendable by a 2-of-3 multisig address on a +block-by-block basis. Key-Holders will need to perform regular multiparty +signing ceremonies in order to shield the resulting coinbase outputs. Each such +signing ceremony involves shared spending authority being used to sign +thousands of inputs to large shielding transactions; for practical reasons, +this is often handled using a scripted process that has spending authority over +these funds. This process is an attractive target for compromise; for this +reason it is RECOMMENDED that address rotation (in this case, by means of +hard-coding a sequence of addresses, each of which receives a time-bounded +subset of the block reward fractional outputs) be implemented, as was done +for the ECC funding stream described in ZIP 1014 [^zip-1014]. + +In the case of key compromise or loss, it may be necessary to perform an +emergency Network Upgrade to perform a manual key rotation to ensure that +future development funds are not lost. + +## Security implications for Mechanism 2b + +Due to the aggregation of funds recommended by Option 2b, it is no longer +necessary to use scripts with spending privileges to perform shielding and/or +distribution operations; instead, these operations can be performed by human +operators using an interactive protocol that does not require sharing spending +key material. + +As with Option 2a, key compromise or loss would require an emergency Network +Upgrade to perform manual key rotation to mitigate the potential for loss of +funds. + + +# Deployment + +This proposal will be deployed with the NU6.1 network upgrade. [^zip-0255] + + +# Reference implementation + +* [zcashd PR 7032: Network Upgrade 6.1](https://github.com/zcash/zcash/pull/7032) +* [zcashd PR 7059: Release zcashd v6.10.0](https://github.com/zcash/zcash/pull/7059) +* [librustzcash PR 1979: Crate releases for NU6.1 mainnet upgrade](https://github.com/zcash/librustzcash/pull/1979) +* [zebrad PR 9603: add(consensus): Implement one-time lockbox disbursement mechanism for NU6.1](https://github.com/ZcashFoundation/zebra/pull/9603) + + +# 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"](https://www.rfc-editor.org/info/bcp14) + +[^protocol-chainvaluepoolbalances]: [Zcash Protocol Specification, Version 2025.6.0 [NU6.1 proposal]. Section 4.17: Chain Value Pool Balances](protocol/protocol.pdf#chainvaluepoolbalances) + +[^protocol-txnconsensus]: [Zcash Protocol Specification, Version 2025.6.0 [NU6.1 proposal]. Section 7.1.2: Transaction Consensus Rules](protocol/protocol.pdf#txnconsensus) + +[^protocol-subsidies]: [Zcash Protocol Specification, Version 2025.6.0 [NU6.1 proposal]. Section 7.8: Calculating Block Subsidy, Funding Streams, Lockbox Disbursement, and Founders’ Reward (section title as modified)](protocol/protocol.pdf#subsidies) + +[^protocol-fundingstreams]: [Zcash Protocol Specification, Version 2025.6.0 [NU6.1 proposal]. Section 7.10: Payment of Funding Streams, Deferred Lockbox, and Lockbox Disbursements (section title as modified)](protocol/protocol.pdf#fundingstreams) + +[^protocol-zip214fundingstreams]: [Zcash Protocol Specification, Version 2025.6.0 [NU6.1 proposal]. Section 7.10.1: ZIP 214 Funding Streams](protocol/protocol.pdf#zip214fundingstreams) + +[^zip-0048]: [ZIP 48: Transparent Multisig Wallets](zip-0048.md) + +[^zip-0207]: [ZIP 207: Funding Streams](zip-0207.rst) + +[^zip-0207-consensus-rules]: [ZIP 207: Funding Streams — Consensus Rules](zip-0207#consensus-rules) + +[^zip-0214]: [ZIP 214: Consensus rules for a Zcash Development Fund](zip-0214.rst) + +[^zip-0214-funding-streams]: [ZIP 214: Consensus rules for a Zcash Development Fund — Funding Streams](zip-0214#funding-streams) + +[^zip-0230]: [ZIP 230: Version 6 Transaction Format](zip-0230.rst) + +[^zip-0255]: [ZIP 255: Deployment of the NU6.1 Network Upgrade](zip-0255.md) + +[^zip-1014]: [ZIP 1014: Establishing a Dev Fund for ECC, ZF, and Major Grants](zip-1014.rst) + +[^zip-1015]: [ZIP 1015: Block Subsidy Allocation for Non-Direct Development Funding](zip-1015.rst) + +[^zip-1015-funding-streams]: [ZIP 1015: Block Subsidy Allocation for Non-Direct Development Funding — Funding Streams](zip-1015#funding-streams) + +[^zip-1016]: [ZIP 1016: Community and Coinholder Funding Model](zip-1016.md) + +[^bip-0388]: [BIP 388: Wallet Policies for Descriptor Wallets](https://github.com/bitcoin/bips/blob/master/bip-0388.mediawiki) + +[^Bitcoin-Multisig]: [Bitcoin Developer Documentation — Pay To Script Hash (P2SH) — Multisig](https://developer.bitcoin.org/devguide/transactions.html#multisig) diff --git a/zips/zip-0300.rst b/zips/zip-0300.rst index 17eb9b030..6c618f7e1 100644 --- a/zips/zip-0300.rst +++ b/zips/zip-0300.rst @@ -2,7 +2,7 @@ ZIP: 300 Title: Cross-chain Atomic Transactions - Owners: Daira-Emma Hopwood + Owners: Daira-Emma Hopwood Original-Authors: Jay Graber Status: Proposed Category: Informational diff --git a/zips/zip-0301.rst b/zips/zip-0301.rst index c76161db3..b976a501a 100644 --- a/zips/zip-0301.rst +++ b/zips/zip-0301.rst @@ -2,13 +2,13 @@ ZIP: 301 Title: Zcash Stratum Protocol - Owners: Jack Grigg + Owners: Jack Grigg Credits: 5a1t Daira-Emma Hopwood Marek Palatinus (slush) and colleagues Jelle Bourdeaud'hui (razakal) ocminer - Status: Final + Status: Active Category: Standards / Ecosystem Created: 2016-09-23 License: MIT diff --git a/zips/zip-0302.rst b/zips/zip-0302.rst index a87ffac51..327f64bdd 100644 --- a/zips/zip-0302.rst +++ b/zips/zip-0302.rst @@ -2,7 +2,7 @@ ZIP: 302 Title: Standardized Memo Field Format - Owners: Jack Grigg + Owners: Jack Grigg Original-Authors: Jay Graber Status: Draft Category: Standards / RPC / Wallet diff --git a/zips/zip-0303.rst b/zips/zip-0303.rst index 54e439e80..85f17c416 100644 --- a/zips/zip-0303.rst +++ b/zips/zip-0303.rst @@ -4,6 +4,6 @@ Title: Sprout Payment Disclosure Owners: Deirdre Connolly Original-Authors: Simon Liu - Status: Reserved + Status: Withdrawn Category: Standards / RPC / Wallet Pull-Request: diff --git a/zips/zip-0304.rst b/zips/zip-0304.rst index 995eefc7b..107033e98 100644 --- a/zips/zip-0304.rst +++ b/zips/zip-0304.rst @@ -2,9 +2,9 @@ ZIP: 304 Title: Sapling Address Signatures - Owners: Jack Grigg - Credits: Daira-Emma Hopwood - Sean Bowe + Owners: Jack Grigg + Credits: Daira-Emma Hopwood + Sean Bowe Status: Draft Category: Standards / RPC / Wallet Created: 2020-06-01 @@ -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-0305.rst b/zips/zip-0305.rst index a7695fd06..75dabfd36 100644 --- a/zips/zip-0305.rst +++ b/zips/zip-0305.rst @@ -2,7 +2,7 @@ ZIP: 305 Title: Best Practices for Hardware Wallets supporting Sapling - Owners: Daira-Emma Hopwood + Owners: Daira-Emma Hopwood Status: Reserved Category: Wallet Discussions-To: diff --git a/zips/zip-0306.rst b/zips/zip-0306.rst index 76b95ead2..8cfd89f6c 100644 --- a/zips/zip-0306.rst +++ b/zips/zip-0306.rst @@ -2,7 +2,7 @@ ZIP: 306 Title: Security Considerations for Anchor Selection - Owners: Daira-Emma Hopwood + Owners: Daira-Emma Hopwood Status: Reserved Category: Informational Discussions-To: diff --git a/zips/zip-0307.rst b/zips/zip-0307.rst index 720443c80..9575f620f 100644 --- a/zips/zip-0307.rst +++ b/zips/zip-0307.rst @@ -2,8 +2,8 @@ ZIP: 307 Title: Light Client Protocol for Payment Detection - Owners: Jack Grigg - Daira-Emma Hopwood + Owners: Jack Grigg + Daira-Emma Hopwood Original-Authors: George Tankersley Credits: Matthew Green Category: Standards / Ecosystem @@ -34,7 +34,7 @@ Motivation ========== Currently a client that wishes to send or receive shielded payments must be a full node -participanting in the Zcash network. This requires an amount of available bandwidth, +participating in the Zcash network. This requires an amount of available bandwidth, space, and processing power that may be unsuitable for some classes of user. This light client protocol addresses that need, and is appropriate for low-power, bandwidth-conscious, or otherwise limited machines (such as mobile phones). @@ -79,7 +79,7 @@ Compact Stream Format A key observation in this protocol is that the current zcashd encrypted field is several hundred bytes long, due to the inclusion of a transaction “memo”. The need to download -this entire field imposes a substantial bandwidth cost on each light wallets, which may be +this entire field imposes a substantial bandwidth cost on each light wallet, which may be a limited mobile device on a restricted-bandwidth plan. While more efficient techniques can be developed in the future, for the moment we propose ignoring the memo field during payment detection. Futhermore, we can also ignore any information that is not directly @@ -172,7 +172,7 @@ and spendable. Spend Compression ----------------- -Recall that a full Sapling Spend description is 384 bytes long [#protocol-spendencoding]_: +Recall that a full Sapling Spend description is 384 bytes long [#protocol-spendencodingandconsensus]_: +-------+--------------+-----------+ | Bytes | Name | Type | @@ -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 ```````````````````````````````````` @@ -609,12 +609,12 @@ 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-merkletree] `Zcash Protocol Specification, Version 2020.1.15. Section 3.7: Note Commitment Trees `_ -.. [#protocol-merklepath] `Zcash Protocol Specification, Version 2020.1.15. Section 4.8: Merkle Path Validity `_ -.. [#protocol-saplingdecryptivk] `Zcash Protocol Specification, Version 2020.1.15. Section 4.17.2: Decryption using an Incoming Viewing Key (Sapling) `_ -.. [#protocol-notept] `Zcash Protocol Specification, Version 2020.1.15. Section 5.5: Encodings of Note Plaintexts and Memo Fields `_ -.. [#protocol-spendencoding] `Zcash Protocol Specification, Version 2020.1.15. Section 7.3: Encoding of Spend Descriptions `_ -.. [#protocol-outputencoding] `Zcash Protocol Specification, Version 2020.1.15. Section 7.4: Encoding of Output Descriptions `_ +.. [#protocol-merkletree] `Zcash Protocol Specification, Version 2025.6.1 [NU6.1]. Section 3.8: Note Commitment Trees `_ +.. [#protocol-merklepath] `Zcash Protocol Specification, Version 2025.6.1 [NU6.1]. Section 4.9: Merkle Path Validity `_ +.. [#protocol-saplingdecryptivk] `Zcash Protocol Specification, Version 2025.6.1 [NU6.1]. Section 4.20.2: Decryption using an Incoming Viewing Key (Sapling) `_ +.. [#protocol-notept] `Zcash Protocol Specification, Version 2025.6.1 [NU6.1]. Section 5.5: Encodings of Note Plaintexts and Memo Fields `_ +.. [#protocol-spendencodingandconsensus] `Zcash Protocol Specification, Version 2025.6.1 [NU6.1]. Section 7.3: Spend Description Encoding and Consensus `_ +.. [#protocol-outputencodingandconsensus] `Zcash Protocol Specification, Version 2025.6.1 [NU6.1]. Section 7.4: Output Description Encoding and Consensus `_ .. [#zip-0212] `ZIP 212: Allow Recipient to Derive Sapling Ephemeral Secret from Note Plaintext `_ .. [#protocolbuffers] `Protocol Buffers documentation `_ .. [#incremental-witness] `zcash_primitives Rust crate — merkle_tree.rs `_ diff --git a/zips/zip-0308.rst b/zips/zip-0308.rst index ed039af23..853d412c1 100644 --- a/zips/zip-0308.rst +++ b/zips/zip-0308.rst @@ -2,10 +2,9 @@ ZIP: 308 Title: Sprout to Sapling Migration - Owners: Daira-Emma Hopwood - Original-Authors: Daira-Emma Hopwood - Eirik Ogilvie-Wigley - Status: Final + Owners: Daira-Emma Hopwood + Original-Authors: Eirik Ogilvie-Wigley + Status: Active Category: Standards / RPC / Wallet Created: 2018-11-27 License: MIT diff --git a/zips/zip-0309.rst b/zips/zip-0309.rst index cd85c9c34..ef986c58f 100644 --- a/zips/zip-0309.rst +++ b/zips/zip-0309.rst @@ -9,5 +9,5 @@ Status: Reserved Category: Standards / Ecosystem Created: 2019-07-15 - Discussions-To: + Discussions-To: Pull-Request: diff --git a/zips/zip-0310.rst b/zips/zip-0310.rst index 843f6e3c9..c3d9271eb 100644 --- a/zips/zip-0310.rst +++ b/zips/zip-0310.rst @@ -2,8 +2,8 @@ ZIP: 310 Title: Security Properties of Sapling Viewing Keys - Owners: Daira-Emma Hopwood - Jack Grigg + Owners: Daira-Emma Hopwood + Jack Grigg Status: Draft Category: Informational Created: 2020-03-09 diff --git a/zips/zip-0311.rst b/zips/zip-0311.rst index b55b94bac..d31b3b7b3 100644 --- a/zips/zip-0311.rst +++ b/zips/zip-0311.rst @@ -2,7 +2,7 @@ ZIP: 311 Title: Zcash Payment Disclosures - Owners: Jack Grigg + Owners: Jack Grigg Status: Draft Category: Standards / RPC / Wallet Discussions-To: @@ -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 @@ -435,12 +435,12 @@ References .. [#RFC2119] `RFC 2119: Key words for use in RFCs to Indicate Requirement Levels `_ .. [#RFC4648] `RFC 4648: The Base16, Base32, and Base64 Data Encodings `_ -.. [#protocol] `Zcash Protocol Specification, Version 2020.1.15 or later `_ -.. [#protocol-spendstatement] `Zcash Protocol Specification, Version 2020.1.15. Section 4.15.2: Spend Statement (Sapling) `_ -.. [#protocol-saplingencrypt] `Zcash Protocol Specification, Version 2020.1.15. 4.17.1: Encryption (Sapling) `_ -.. [#protocol-saplingdecryptovk] `Zcash Protocol Specification, Version 2020.1.15. 4.17.3: Decryption using a Full Viewing Key (Sapling) `_ -.. [#protocol-concretediversifyhash] `Zcash Protocol Specification, Version 2020.1.15. Section 5.4.1.6: DiversifyHash Hash Function `_ -.. [#protocol-concretespendauthsig] `Zcash Protocol Specification, Version 2020.1.15. Section 5.4.6.1: Spend Authorization Signature `_ +.. [#protocol] `Zcash Protocol Specification, Version 2025.6.1 [NU6.1] or later `_ +.. [#protocol-spendstatement] `Zcash Protocol Specification, Version 2025.6.1 [NU6.1]. Section 4.15.2: Spend Statement (Sapling) `_ +.. [#protocol-saplingencrypt] `Zcash Protocol Specification, Version 2025.6.1 [NU6.1]. 4.19.1: Encryption (Sapling) `_ +.. [#protocol-saplingdecryptovk] `Zcash Protocol Specification, Version 2025.6.1 [NU6.1]. Section 4.20.3: Decryption using an Outgoing Viewing Key (Sapling) `_ +.. [#protocol-concretediversifyhash] `Zcash Protocol Specification, Version 2025.6.1 [NU6.1]. Section 5.4.1.6: DiversifyHash Hash Function `_ +.. [#protocol-concretespendauthsig] `Zcash Protocol Specification, Version 2025.6.1 [NU6.1]. Section 5.4.6.1: Spend Authorization Signature `_ .. [#bip-0322] `BIP 322: Generic Signed Message Format `_ .. [#slip-0044] `SLIP-0044 : Registered coin types for BIP-0044 `_ .. [#zip-0304] `ZIP 304: Sapling Address Signatures `_ 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-0314.rst b/zips/zip-0314.rst index 1ebb8a68a..340c2a777 100644 --- a/zips/zip-0314.rst +++ b/zips/zip-0314.rst @@ -2,7 +2,7 @@ ZIP: 314 Title: Privacy upgrades to the Zcash light client protocol - Owners: Taylor Hornby + Owners: Taylor Hornby Status: Reserved Category: Standards / Wallet Discussions-To: diff --git a/zips/zip-0315.rst b/zips/zip-0315.rst index 519d5d2bc..5229a7d51 100644 --- a/zips/zip-0315.rst +++ b/zips/zip-0315.rst @@ -2,9 +2,9 @@ ZIP: 315 Title: Best Practices for Wallet Implementations - Owners: Daira-Emma Hopwood - Jack Grigg - Kris Nuttycombe + Owners: Daira-Emma Hopwood + Jack Grigg + Kris Nuttycombe Credits: Francisco Gindre Status: Draft Category: Wallet @@ -62,12 +62,16 @@ that they have enough information to assess the consequences of their economic a This ZIP covers best practices for: * what information to display to the user about transactions and balances; -* how to handle interactions between the ZIP 32 [#zip-0032]_ key tree and Unified Addresses [#zip-0316]_; +* how to handle interactions between the ZIP 32 [#zip-0032]_ key tree and + Unified Addresses [#zip-0316]_; * when to use external or internal keys/addresses; * sharing addresses and viewing keys; * sending and receiving funds (including fee selection); * migrating funds between pools. +Note: The policies implemented by the legacy `zcashd` internal wallet are known +to be in violation of this ZIP. + Requirements ============ @@ -122,6 +126,29 @@ other. Specification ============= +Wallet seeds +------------ + +To meet the ZIP 32 requirement on the entropy of wallet seeds +[#zip-0032-wallet-seeds]_, when generating a seed byte sequence: + +* if using a BIP 39 mnemonic [#bip-0039]_, a 24-word mnemonic will be needed; +* if using SLIP 39 secret sharing [#slip-0039]_, a share length of 33 words will + be needed. + +In the case where a wallet implementation restores a wallet from an existing +mnemonic, it will normally not be in a position to enforce a minimum entropy +requirement on that mnemonic. + +A wallet implementation MAY accept BIP 39 mnemonics of fewer than 24 words or +SLIP 39 shares of fewer than 33 words when restoring a wallet (but as specified +above, MUST NOT generate them). If it accepts them —or in other cases where it +can reliably detect that the seed to be restored will have less than 256 bits of +entropy— it SHOULD warn the user that the security of the restored wallet will +be weaker than expected, and SHOULD recommend transferring all of the wallet's +funds, once it has fully synced, to another wallet controlled by the user. + + Long-term storage of funds -------------------------- @@ -133,8 +160,8 @@ auto-shield such funds by default. A shielding transaction is always linked to the transparent addresses it spends from. This can cause undesirable information leaks: -a) if there are multiple transparent addresses, they will be linked to each - other; +a) if the inputs to the transaction are associated with multiple transparent + addresses, those addresses will be linked to each other; b) a link between the input transparent address(es) and the payment will be visible to the recipient(s), or to any other holder of an Incoming Viewing Key for the destination address(es). @@ -156,9 +183,54 @@ transactions to other transactions. The remainder of this specification assumes a wallet that follows all of these recommendations, except where explicitly noted. -A wallet MAY allow users to disable auto-shielding, auto-migration, -and/or opportunistic migration. If it does so, this need not be via -three independent settings. +Address management +------------------ + +Zcash wallets SHOULD only use addresses generated deterministically from a +seed as specified in ZIP 32 [#zip-0032]_. The discussion of address management +below assumes this is the case. + +The general framework specified in ZIP 32 is that addresses are derived in +a hierarchy [#zip-0032-wallet-usage]_, following a similar structure to that +defined by BIP 44. Each `account` in the derivation path represents a distinct +spending authority. Funds within an account are differentiated according to the +protocol under which the TXOs that contributed to the account balance were +created, but TXOs are not managed individually except when it is required +to select funds from a specific shielded pool in order to reduce information +leakage. + +ZIP 316 specifies that when generating a Unified Address, the same diversifier +index MUST be used for each Receiver. [#zip-0316-deriving-a-unified-address]_ +This has the consequence that, for wallets that implement address rotation, +care must be taken to avoid accidentally leaking information that allows an +observer to link the ownership of addresses that are intended by the wallet +user to be unrelated to one another. + + +Allowed transfers +----------------- + +Wallets SHOULD NOT spend funds from a transparent address in a transaction with +an external recipient, unless the user gives explicit consent for this on a +per-transaction basis. Wallets MAY further restrict the set of transfers they +perform. + + +Auto-shielding +-------------- + +Auto-shielding requires that the wallet have ambient access to the spending +authority, and that this authority may be exercised without user intervention. +This is not the case for e.g. wallets where key material is stored in a secure +enclave with access that is mediated by direct user interaction, or wallets +used in conjunction with hardware devices. + +For wallets that have the required ambient spending authority, auto-shielding +is the process by which transparent UTXOs detected as belonging to the wallet +are shielded by the wallet without user intervention. + +Wallet users MUST be able to disable auto-shielding functionality offered by a +wallet. Automatic shielding and automatic/opportunistic migration SHOULD NOT be applied to inputs where the cost of shielding or migrating them will @@ -176,7 +248,9 @@ Trusted and untrusted TXOs A wallet SHOULD treat received TXOs that are outputs of transactions created by the same wallet, as trusted TXOs. Wallets MAY enable users to mark specific external transactions as trusted, allowing their received TXOs also to be -classified as trusted TXOs. +classified as trusted TXOs. Wallets MAY also permit users to define alternate +policies for the number of confirmations required before untrusted TXOs may be +spent based on a user-configured value threshold. A wallet SHOULD have a policy that is clearly communicated to the user for the number of confirmations needed to spend untrusted and trusted TXOs @@ -185,6 +259,13 @@ respectively. The following confirmation policy is RECOMMENDED: * 10 confirmations, for untrusted TXOs; * 3 confirmations, for trusted TXOs. +Wallets SHOULD NOT permit the spending of TXOs with fewer than 3 confirmations, +with the exception of: + +* transparent UTXOs that are spent in shielding transactions +* ephemeral transparent UTXOs created in the process of sending funds from + the shielded pools to a TEX recipient address [#zip-0320]_. + Rationale for the given numbers of confirmations '''''''''''''''''''''''''''''''''''''''''''''''' @@ -201,8 +282,8 @@ that funds are re-sent. Categories of TXOs according to spendability -------------------------------------------- -A TXO is *known-spendable*, relative to a given block chain and wallet state, -if and only if all of the following are true in that state: +A TXO is *known-spendable*, relative to a given block chain and wallet +state, if and only if all of the following are true in that state: * the TXO is unspent at the wallet's view of the chain tip, and that view is reasonably up-to-date; @@ -210,20 +291,34 @@ if and only if all of the following are true in that state: TODO: consider undoing the up-to-date part, as when combined with the definition of balance below, it causes wallet balance to drop to zero in the short window between opening and updating the wallet's chain tip view. -* the TXO is not committed to be spent in another transaction created +* the TXO is not committed to be spent in another unexpired transaction created by this wallet; and -* the wallet has the TXO's spending key (for whatever protocol the TXO uses). +* the wallet can effect the spend, either by having access to the TXO's + spending key (for whatever protocol the TXO uses) or by mediating interaction + with a hardware device or other offline signing protocol. + +Shielded TXOs +''''''''''''' -A TXO is *confirmed-spendable*, relative to a given block chain and +A shielded TXO is *confirmed-spendable*, relative to a given block chain and wallet state, if and only if all of the following are true in that state: -* the wallet is synchronized; and * the TXO is known-spendable; and -* either auto-shielding is not active or the TXO is shielded; and -* auto-migration *from* whatever protocol the TXO uses is not active; and -* the TXO is trusted and has at least the required confirmations for - trusted TXOs, or it is untrusted and has at least the required - confirmations for untrusted TXOs. +* the wallet has sufficient contextual information to be able to effect the + spend (i.e. it is able to construct required witnesses, etc.); and +* one of the following is true: + + * the TXO is not an output of a wallet-internal shielding transaction, and either: + + * it is trusted and has at least the required confirmations for trusted TXOs + * it is untrusted and has at least the required confirmations for untrusted TXOs. + + * the TXO is the output of a wallet-internal shielding transaction, and both: + + * the transparent UTXOs spent in the shielding transaction have at least + `(untrusted_confirmations - trusted_confirmations)` confirmations + * the wallet-internal shielding transaction has at least `trusted_confirmations` + confirmations A TXO is *unconfirmed-spendable*, relative to a given block chain and wallet state, if and only if the TXO is known-spendable but is not @@ -235,12 +330,24 @@ A TXO is *watch-only* if and only if the wallet has its full viewing key A wallet MUST NOT attempt to spend a TXO in a user-initiated transaction that is not confirmed-spendable. -Open question: what should be specified about which TXOs can be spent -in non-user-initiated transactions? +Transparent UTXOs +''''''''''''''''' -Note: the definition of a TXO includes outputs in mempool transactions -that are unconflicted from the perspective of the wallet. +A transparent UTXO is *confirmed-shieldable* relative to a given block chain and +wallet state, if and only if all of the following are true in that state: +* the TXO is known-spendable; and +* the wallet has sufficient contextual information to be able to effect the + spend (i.e. it is able to construct a correct redeem script, etc.) + +Wallets MAY attempt to spend received transparent UTXOs in wallet-internal +shielding transactions with zero confirmations. In this case, the resulting +shielded funds will not be made available for spending until the transaction +that produced the original transparent UTXOs has at least +`untrusted_confirmations`, and the shielding transaction has at least +`trusted_confirmations`. Wallet implementers should take care not to mistake +the TXOs resulting from shielding transactions as trusted outputs just because +they are sent to a wallet-internal address. Reporting of balances --------------------- @@ -250,13 +357,29 @@ Wallets SHOULD report: * Confirmed-spendable balance. * Pending balance, *or* total balance. +Wallets MAY report: + +* Un-economic balance. + These are calculated as follows: -* The confirmed-spendable balance is the sum of values of - confirmed-spendable TXOs. -* The pending balance is the sum of values of unconfirmed-spendable TXOs. +* The confirmed-spendable balance is the sum of values of confirmed-spendable + TXOs. This balance MAY ignore notes with value less than the ZIP 317 + marginal fee [#zip-0317]_. +* The pending balance is the sum of values of unconfirmed-spendable TXOs. This + balance MAY ignore notes with value less than the ZIP 317 marginal fee + [#zip-0317]_, and MUST exercise this option in a way that is consistent + with how the confirmed-spendable balance is computed. * The total balance is the confirmed-spendable balance plus the pending balance. +* The un-economic balance is the total of TXOs that individually have value + less than the ZIP 317 marginal fee [#zip-0317]_. Such TXOs can only be spent + as "grace inputs" as they do not provide sufficient value to pay the fees + required to spend them; wallets MAY ignore the presence of such notes in note + selection and balance calculation. If wallets ignore the presence of such + notes, they MUST do so consistently; i.e. wallets MUST NOT report them as + part of balance that is exposed to the user as spendable or pending if the + wallet does not provide any mechanism to spend them. Note: the definition of "confirmed-spendable" above ensures that: @@ -319,6 +442,25 @@ have an expiry height), and their balances as described in `Reporting of balances`_. +Display of voluntary fund removal +'''''''''''''''''''''''''''''''''' + +Wallets that support voluntary removal of funds from circulation as specified +in ZIP 233 [#zip-0233]_ SHOULD display clear, user-friendly messaging at +transaction confirmation time explaining the purpose and effect of the removal. + +For example, a wallet might display: + + "These funds will be used for network sustainability purposes. They will + be gradually reissued to support the long-term security of the Zcash + network." + +This guidance applies to user-initiated voluntary removals via ZIP 233. It +does not apply to the automatic removal of transaction fees specified in +ZIP 235 [#zip-0235]_, which occurs without user action and does not require +explicit user confirmation. + + Transaction creation -------------------- @@ -508,49 +650,6 @@ What they are supposed to reveal; see ZIP 310 for Sapling (needs updating for Orchard). https://github.com/zcash/zips/issues/606 - -Allowed transfers ------------------ - -* Sprout -> transparent or Sapling -* Sapling -> transparent or Sapling or Orchard -* Orchard -> transparent or Sapling or Orchard -* if auto-shielding is off: - * transparent -> transparent or Sapling or Orchard -* if auto-shielding is on: - * transparent -> internal Orchard or Sapling - -Note: wallets MAY further restrict the set of transfers they perform. - - -Auto-shielding --------------- - -Wallets SHOULD NOT spend funds from a transparent address to an external address, -unless the user gives explicit consent for this on a per-transaction basis. - -TODO: Reword this to define the source transparent address as any transparent -address (external, internal, or ephemeral), except in the case of ephemeral as -allowed for implementing ZIP 320. - -In order to support this policy, wallets SHOULD implement a system of auto-shielding -with the following characteristics: - - -If auto-shielding functionality is available in a wallet, then users MUST be able -to explicitly consent to one of the following possibilities: - -* auto-shielding is always on; -* auto-shielding is always off; -* the user specifies a policy... - -Auto-shielding MUST be one of: - -* "must opt in or out" (zcashd will do this -- i.e. refuse to start unless the option - is configured), or -* always on. - - Auto-migration -------------- @@ -694,8 +793,15 @@ 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" `_ +.. [#bip-0039] `BIP 39: Mnemonic code for generating deterministic keys `_ +.. [#slip-0039] `SLIP 39: Shamir's Secret-Sharing for Mnemonic Codes `_ .. [#zip-0032] `ZIP 32: Shielded Hierarchical Deterministic Wallets `_ +.. [#zip-0032-wallet-seeds] `ZIP 32: Shielded Hierarchical Deterministic Wallets — Specification: Wallet seeds `_ +.. [#zip-0032-wallet-usage] `ZIP 32: Shielded Hierarchical Deterministic Wallets — Specification: Wallet usage `_ .. [#zip-0203] `ZIP 203: Transaction Expiry `_ +.. [#zip-0233] `ZIP 233: Network Sustainability Mechanism: Removing Funds From Circulation `_ +.. [#zip-0235] `ZIP 235: Remove 60% of Transaction Fees From Circulation `_ .. [#zip-0316] `ZIP 316: Unified Addresses and Unified Viewing Keys `_ +.. [#zip-0316-deriving-a-unified-address] `ZIP 316: Unified Addresses and Unified Viewing Keys — Deriving a Unified Address from a UIVK `_ .. [#zip-0317] `ZIP 317: Proportional Transfer Fee Mechanism `_ .. [#zip-0320] `ZIP 320: Defining an Address Type to which funds can only be sent from Transparent Addresses `_ diff --git a/zips/zip-0316.rst b/zips/zip-0316.rst index 91b6c4123..7e7058f4c 100644 --- a/zips/zip-0316.rst +++ b/zips/zip-0316.rst @@ -2,16 +2,16 @@ ZIP: 316 Title: Unified Addresses and Unified Viewing Keys - Owners: Daira-Emma Hopwood - Nathan Wilcox - Jack Grigg - Sean Bowe - Kris Nuttycombe + Owners: Daira-Emma Hopwood + Nathan Wilcox + Jack Grigg + Sean Bowe + Kris Nuttycombe Original-Authors: Greg Pfeil Ying Tong Lai Credits: Taylor Hornby Stephen Smith - Status: Revision 0: Final, Revision 1: Proposed + Status: [Revision 0] Active, [Revision 1] Withdrawn, [Revision 2] Draft Category: Standards / RPC / Wallet Created: 2021-04-07 License: MIT @@ -214,6 +214,12 @@ to be a compelling reason to deviate from the standard, since the benefits of UA come precisely from their applicability across all new protocol upgrades. +For `Revision 2`_, users must be able to visually distinguish addresses +that risk information being leaked on-chain as a result of a transfer, +from addresses that present no such risks, with the exception of pool-crossing +amounts. The latter are accepted leage in the UA design, in order to achieve +the desired wallet compatibility properties. + Receivers --------- @@ -255,20 +261,22 @@ Transfers When executing a Transfer the Sender selects a Receiver via a Selection process. -Given a valid UA, Selection must treat any unrecognised Item as though -it were absent. +Given a valid UA, Selection must treat any unrecognised Item as though it were +absent (with the exception that Items with typecodes in the MUST-understand +range may not be ignored; the Sender must reject addresses containing +MUST-understand Items that they do not recognise). - This property is crucial for forward compatibility to ensure users who upgrade to newer protocols / UAs don't lose the ability to smoothly interact with older wallets. -- This property is crucial for allowing Transparent-Only UA-Conformant - wallets to interact with newer shielded wallets, removing a +- This property is crucial for allowing wallets that support only older + shielded protocols to interact with newer shielded wallets, removing a disincentive for adopting newer shielded wallets. -- This property also allows Transparent-Only wallets to upgrade to - shielded support without re-acquiring counterparty UAs. If they are - re-acquired, the user flow and usability will be minimally disrupted. +- This property also allows wallets to upgrade to newer shielded protocol + support without re-acquiring counterparty UAs. If they are re-acquired, + the user flow and usability will be minimally disrupted. Experimental Usage ------------------ @@ -315,39 +323,59 @@ Revisions .. _`Revision 1`: -* Revision 1: This version adds support for `MUST-understand Typecodes`_ - and `Address Expiration Metadata`_. It also drops the restriction that - a UA/UVK must contain at least one shielded Item. - -A Revision 0 UA/UVK is distinguished from a Revision 1 UA/UVK by its +* Revision 1 (Withdrawn): Revision 1 proposed a variant of this specification + similar to that specified for `Revision 2`_ addresses having the ``tu`` + Human-Readable Part. It faced `opposition from the community + `_ + due to it being difficult to discern the privacy implications of sharing an + address as that specified, and has been withdrawn. See + `the previously proposed specification + `_ + for details. + +.. _`Revision 2`: + +* Revision 2: This version adds support for `MUST-understand Typecodes`_ and + `Address Expiration Metadata`_. It introduces two new variants of Unified + Addresses; ``zu`` addresses, which are prohibited from containing transparent + receivers, and ``tu`` addresses, which allow transparent receivers to be + augmented with metadata items. For Unified Viewing Keys, this version adopts + ``uvf`` and ``uvi`` encoding prefixes for Unified Full Viewing Keys and + Unified Incoming Viewing Keys respectively, drops the restriction that a UVK + must contain at least one shielded Item, and adds support for + `P2SH Viewing Key Items`_ using BIP 388 wallet policies [#bip-0388]_. + +A Revision 0 UA/UVK is distinguished from a Revision 2 UA/UVK by its Human-Readable Part, as follows. -Let *prefix* be: +Let *addr_prefix* be: -* “``u``”, if this is a UA/UVK prior to `Revision 1`_; -* “``ur``”, if this is a UA/UVK from `Revision 1`_ onward. +* “``u``”, if this is a UA or UVK prior to `Revision 2`_; +* “``zu``”, if this is a shielded-only UA from `Revision 2`_ onward. +* “``tu``”, if this is a transparent-enabled UA from `Revision 2`_ onward. The Human-Readable Parts (as defined in [#bip-0350]_) of Unified Addresses are defined as: -* *prefix*, for Unified Addresses on Mainnet; -* *prefix* || “``test``”, for Unified Addresses on Testnet. +* *addr_prefix*, for Unified Addresses on Mainnet; +* *addr_prefix* || “``test``”, for Unified Addresses on Testnet. -The Human-Readable Parts of Unified Viewing Keys are defined as: +Let *ivk_prefix* be: -* *prefix* || “``ivk``” for Unified Incoming Viewing Keys on Mainnet; -* *prefix* || “``ivktest``” for Unified Incoming Viewing Keys on Testnet; -* *prefix* || “``view``” for Unified Full Viewing Keys on Mainnet; -* *prefix* || “``viewtest``” for Unified Full Viewing Keys on Testnet. +* “``uivk``” prior to `Revision 2`_; +* “``uvi``” from `Revision 2`_ onward. -While support for Revision 1 UAs/UVKs is still being rolled out across -the Zcash ecosystem, a Producer can maximize interoperability by -generating a Revision 0 UA/UVK in cases where the conditions on its -use are met (i.e. there are no MUST-understand Metadata Items, and at -least one shielded item). At some point when Revision 1 UA/UVKs are -widely supported, this will be unnecessary and it will be sufficient -to always produce Revision 1 UA/UVKs. +Let *fvk_prefix* be: +* “``uview``” prior to `Revision 2`_; +* “``uvf``” from `Revision 2`_ onward. + +The Human-Readable Parts of Unified Viewing Keys are defined as: + +* *ivk_prefix* for Unified Incoming Viewing Keys on Mainnet; +* *ivk_prefix* || “``test``” for Unified Incoming Viewing Keys on Testnet; +* *fvk_prefix* for Unified Full Viewing Keys on Mainnet; +* *fvk_prefix* || “``test``” for Unified Full Viewing Keys on Testnet. Encoding of Unified Addresses ----------------------------- @@ -364,14 +392,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 +420,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 +455,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 +489,80 @@ 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}).$ Note that + a zero $\mathsf{ivk}$ is not valid [#protocol-2025.6.0]_. + +.. _`P2SH Viewing Key Items`: + +* For `Revision 0`_: Typecode $\mathtt{0x01}$ MUST NOT be included + in a UFVK or UIVK by Producers, and MUST be treated as unrecognised + by Consumers. + +* For `Revision 2`_ onward, a P2SH Viewing Key Item with Typecode + $\mathtt{0x01}$ MAY be included in a UFVK or UIVK by Producers. A P2SH + Viewing Key Item encodes a BIP 388 wallet policy [#bip-0388]_ as follows: + + * $\mathtt{template\_len} : \mathtt{compactSize}$ — the length in + bytes of the descriptor template. + + * $\mathtt{template} : \mathtt{byte[template\_len]}$ — a BIP 388 + descriptor template [#bip-0388]_, encoded as US-ASCII. + + * $\mathtt{n\_keys} : \mathtt{compactSize}$ — the number of key + information entries. + + * For each of the $\mathtt{n\_keys}$ entries: + + * $\mathtt{chaincode} : \mathtt{byte[32]}$ — the BIP 32 chain code. -* 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}` - MUST NOT be included in a UFVK or UIVK by Producers, and MUST be - treated as unrecognised by Consumers. + * $\mathtt{pubkey} : \mathtt{byte[33]}$ — the compressed public key + in SEC1 encoding. + + Key placeholders in the descriptor template use the ``@N`` notation defined + by BIP 388. In order to preserve the diversifiability properties of UVKs, in + a UFVK, the template MUST use the ``/**`` multipath notation for each key + placeholder (indicating derivation of both external and internal addresses). + In a UIVK, the template MUST use the ``/*`` notation instead (indicating + derivation of external addresses only). To produce the key information vector + for a UIVK, it is necessary to perform an additional step of non-hardened + derivation from the keys provided in the UFVK's key information vector + using the external child path index (index 0). Producers MUST encode + $\mathsf{n_keys}$ in a deterministic order, which may vary depending upon the + template in use. For ZIP 48 keys, this is lexicographic by chain code and + pubkey. + + The number of ``@N`` key placeholders in the descriptor template MUST equal + $\mathtt{n\_keys}.$ Consumers MUST reject P2SH Viewing Key Items for which + this does not hold, or for which the descriptor template is not a valid BIP + 388 descriptor template, or does not satisfy the above requirements on the + use of ``/**`` or ``/*`` multipath notation. * 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`_. @@ -524,20 +592,36 @@ and this should be taken into account in the design of such Items. 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. - -* The :math:`\mathtt{typecode}` and :math:`\mathtt{length}` fields are - encoded as :math:`\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.) - -* Within a single UA or UVK, all HD-derived Receivers, FVKs, and IVKs - SHOULD represent an Address or Viewing Key for the same account (as - used in the ZIP 32 or BIP 44 Account level). +* A Unified Address or Unified Viewing Key MUST contain at least one + non-metadata Item. + +* A `Revision 0`_ Unified Address MUST contain at least one shielded Item + (currently Typecodes $\mathtt{0x02}$ and $\mathtt{0x03}$). Consumers MUST + reject addresses that violate this restriction. + +* A `Revision 2`_ Unified Address encoded with the ``zu`` prefix MUST NOT + contain any transparent Items (currently Typecodes $\mathtt{0x00}$ and + $\mathtt{0x01}$). Consumers MUST reject addresses that violate this + restriction. + +* A `Revision 0`_ Unified Viewing Key MUST contain at least one shielded Item + (currently Typecodes $\mathtt{0x02}$ and $\mathtt{0x03}$). This requirement + is dropped for `Revision 2`_ UVKs. Consumers MUST reject any UVK that + violates the restriction applying to its Revision. + +* 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.) + +* Within a single UA or UVK, all HD-derived Receivers, FVKs, and IVKs SHOULD + represent an Address or Viewing Key for the same account (as used in + derivation at the ZIP 32 or BIP 44 Account level, or, for ZIP 48 [#zip-0048]_ + and/or FROST [#zip-0312]_ UVKs, a single set of signers with the ability to + generate independent addresses corresponding to that spending authority). In + the case of FROST, key material MUST be derived according to the requirements + of ZIPs 312 and 2005, in particular the "Usage with FROST" section of the + latter [#zip-2005-usagewithfrost]_. * For Transparent Addresses, the Receiver Encoding does not include the first two bytes of a raw encoding. @@ -548,13 +632,15 @@ Requirements for both Unified Addresses and Unified Viewing Keys upgrade [#zip-0211]_) to send funds into the Sprout chain value pool, this would not be generally useful. +* It is RECOMMENDED that Producers upgrade to understand and generate + `Revision 2`_ addresses as soon as possible. + * 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. + 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 @@ -570,27 +656,62 @@ Requirements for both Unified Addresses and Unified Viewing Keys that cannot be interpreted as specified above. * If the encoding of a Unified Address/Viewing Key is shown to a user - in an abridged form due to lack of space, at least the first 20 - characters MUST be included. + in an abridged form due to lack of space, at least the first 20 characters + MUST be included. This helps the user to see enough of the UA/UVK to + defend against partial matching attacks; see + `Rationale for showing at least the first 20 characters`_ for additional + commentary on how the cost of such attacks depends on the number of + characters the user is able to check. -Rationale for dropping the "at least one shielded Item" restriction -''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''' +Rationale for dropping the "at least one shielded Item" restriction for UVKs +'''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''' .. raw:: html
    Click to show/hide -The original rationale for this restriction was that the existing P2SH -and P2PKH transparent-only address formats, and the existing P2PKH -extended public key format, sufficed for representing transparent Items -and were already supported by the existing ecosystem. +The original rationale for this restriction was that the existing P2SH and +P2PKH transparent-only address formats, and the existing P2PKH extended public +key format, sufficed for representing viewing keys with transparent Items, and +were already supported by the existing ecosystem. -However, as of `Revision 1`_ there are uses for transparent-only UAs -and UVKs that are not covered by the existing formats. In particular, -they can use Metadata Items to represent expiration heights/dates as -described in `Address Expiration Metadata`_, or source restrictions as -proposed in ZIP 320 [#zip-0320]_. +However, as of `Revision 2`_ there are uses for transparent-only UVKs that are +not covered by the existing formats. In particular, they allow the +representation of viewing keys for P2SH addresses, which is an important use +case with the advent of ZIP 48 [#zip-0048]_. In addition, transparent-only +viewing keys can use Metadata Items to represent expiration heights/dates as +described in `Address Expiration Metadata`_ that is useful in the generation of +``tu``-prefixed addresses. + +.. raw:: html + +
    + +Rationale for removing Transparent Receivers from ``zu`` Unified Addresses +'''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''' + +.. raw:: html + +
    + Click to show/hide + +A common complaint about `Revision 0`_ Unified Addresses was that there was no +way for a user to visually distinguish a Unified Address that allowed the +receipt of transparent funds from one that did not; Transparent addresses do +not provide any privacy protection, and including them in UAs created a risk +that Senders would fall back to transparent transfers even when the Recipient +supports shielded protocols. Historically, the ``z`` address prefix indicated +to the user that no element of the recipient address would cause information +about the recipient to be leaked on-chain by transfers to that address. +`Revision 2`_ restores this property. + +Transparent Items are still permitted in Unified Viewing Keys because +viewing keys serve a different purpose: they allow observation of +transaction activity across all pools, including transparent. A UFVK or +UIVK that includes a transparent component allows the holder to derive +transparent addresses for scanning purposes and to track transparent +funds associated with the same account. .. raw:: html @@ -621,14 +742,30 @@ Rationale for showing at least the first 20 characters
    Click to show/hide -Showing fewer than 20 characters of the String Encoding of a UA/UVK -would potentially allow practical attacks in which the adversary -constructs another UA/UVK that matches in the characters shown. When a -UA/UVK is abridged it is preferable to show a prefix rather than some -other part, both for a more consistent user experience across wallets, -and because security analysis of the cost of partial UA/UVK string -matching attacks is more complicated if checksum characters are included -in the characters that are compared. +Showing fewer than 20 characters of the String Encoding of a UA/UVK would +potentially allow practical attacks in which the adversary constructs another +UA/UVK that matches in the characters shown. When a UA/UVK is abridged it is +preferable to show a prefix rather than some other part, both for a more +consistent user experience across wallets, and because security analysis of the +cost of partial UA/UVK string matching attacks is more complicated if checksum +characters are included in the characters that are compared. + +To analyze the difficulty of partial matching attacks, we must subtract the +length of the HRP and the "1" separator from the 20 characters. The longest HRP +defined for a Mainnet UA/UVK in this specification for is "uview" for Revision +0 UFVKs — and so in the worst case only 14 characters, corresponding to 70 +bits, of the jumbled Mainnet UA/UVK data will be present. (We are not +particularly concerned about attacks on Testnet UA/UVKs.) This implies an +easier partial matching attack than Zcash's usual target security level against +classical attacks of $2^{125}$. Note also that multi-target attacks are +possible. 20 characters should therefore be considered an absolute minimum, and +wallet implementors may wish to show a larger number of initial characters for +abridged UA/UVKs to enable users to defend against partial matching attacks up +to a higher difficulty for the adversary. + +Note that if different sources show different substrings of a UA/UVK then users are +only able to compare the characters that are common to all of these substrings, and +so it is only *initial* characters that contribute to satisfying this requirement. .. raw:: html @@ -643,8 +780,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,15 +796,15 @@ 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). .. _`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 +As of `Revision 2`_ of this ZIP, the subset of Metadata Typecodes in +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. @@ -693,10 +830,10 @@ Rationale for making Revision 0 UA/UVKs with MUST-understand Typecodes invalid
    Click to show/hide -A Consumer implementing this ZIP prior to `Revision 1`_ will not -recognise the Human-Readable Parts beginning with “``ur``” that mark a -`Revision 1`_ UA/UVK. So if a UA/UVK that includes MUST-understand -Typecodes is required to use these `Revision 1`_ HRPs, this will ensure +A Consumer implementing this ZIP prior to `Revision 2`_ will not +recognise the Human-Readable Parts beginning with “``zu``” that mark a +`Revision 2`_ UA/UVK. So if a UA/UVK that includes MUST-understand +Typecodes is required to use these `Revision 2`_ HRPs, this will ensure that the MUST-understand specification is correctly enforced even for such implementations. @@ -708,31 +845,31 @@ such implementations. Address Expiration Metadata --------------------------- -As of `Revision 1`_, Typecodes :math:`\mathtt{0xE0}` and :math:`\mathtt{0xE1}` +As of `Revision 2`_, 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 +A Sender that supports `Revision 2`_ of this specification MUST set a non-zero ``nExpiryHeight`` field in transactions it creates that are sent to a Unified Address that defines an Address Expiry Height. If the ``nExpiryHeight`` normally constructed by the Sender would be greater than 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 +888,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. @@ -805,6 +942,71 @@ set this bound more tightly; a common expiry delta used by many wallets is 40 blocks from the current chain tip, as suggested in ZIP 203 [#zip-0203-default-expiry]_. +Typecode Registry +----------------- + +The following table specifies the full range of Typecodes and indicates which +address types permit each Typecode. Typecode range entries in the table below +are to be interpreted as end-inclusive. + +Producers MUST NOT include Items with Typecodes not permitted for the address +type being produced, and MUST NOT generate UA/UVKs containing Items with +typecodes that are Unassigned. + +The guiding principle for ``zu`` addresses is that a ``zu`` address MUST NOT +contain any Items whose interpretation in transaction construction could result +in an unprivileged observer of the chain being able to distinguish transactions +sent to addresses containing such Items from transactions sent to addresses +that do not. + +In contrast, a ``tu`` address MAY contain items whose interpretation in +transaction construction could result in additional information being leaked +on-chain. As such a user giving out a ``tu`` address should recognise that +they may be giving up some privacy in transactions received at that address. + +If a new Metadata Item type should not be allowed in ``zu`` addresses, it MUST +be assigned in the MUST-understand Metadata range. + +Experimental Typecodes ($\mathtt{0xFFFA}$ to $\mathtt{0xFFFF}$) are permitted +at the discretion of wallets that have opted into the corresponding experiment +as described in `Experimental Usage`_; for ``zu`` addresses, such wallets are +responsible for ensuring that the experiment does not compromise the privacy +properties of ``zu`` addresses. + +:: + + +-------------------+--------------------------------------+----+--------+--------+ + | Typecode | Description | R0 | R2 zu | R2 tu | + +===================+======================================+====+========+========+ + | 0x00 | Transparent P2PKH | ✅ | ❌ | ✅ | + +-------------------+--------------------------------------+----+--------+--------+ + | 0x01 | Transparent P2SH | ✅ | ❌ | ✅ | + +-------------------+--------------------------------------+----+--------+--------+ + | 0x02 | Sapling | ✅ | ✅ | ✅ | + +-------------------+--------------------------------------+----+--------+--------+ + | 0x03 | Orchard | ✅ | ✅ | ✅ | + +-------------------+--------------------------------------+----+--------+--------+ + | 0x04..=0xBF | Unassigned | ❌ | ❌ | ❌ | + +-------------------+--------------------------------------+----+--------+--------+ + | 0xC0..=0xDF | Non-MUST-understand Metadata | ❌ | ❌ | ❌ | + +-------------------+--------------------------------------+----+--------+--------+ + | 0xE0 | Address Expiry Height | ❌ | ✅ | ✅ | + +-------------------+--------------------------------------+----+--------+--------+ + | 0xE1 | Address Expiry Time | ❌ | ✅ | ✅ | + +-------------------+--------------------------------------+----+--------+--------+ + | 0xE2..=0xFC | Unassigned MUST-understand Metadata | ❌ | ❌ | ❌ | + +-------------------+--------------------------------------+----+--------+--------+ + | 0xFD..=0xFFF9 | Unassigned | ❌ | ❌ | ❌ | + +-------------------+--------------------------------------+----+--------+--------+ + | 0xFFFA..=0xFFFF | Experimental | ✅ | [1] | ✅ | + +-------------------+--------------------------------------+----+--------+--------+ + +[1] See note above regarding experimental typecodes in ``zu`` addresses. + +Additions to this registry are made via 2xxx-series ZIPs. This table will be +updated by the ZIP Editors when such a ZIP transitions to ``Proposed`` status. + + Deriving Internal Keys ---------------------- @@ -816,17 +1018,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 +1036,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-conventions]_. +- 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 @@ -851,18 +1053,38 @@ derive an internal P2PKH FVK from the external P2PKH FVK (i.e. its parent) without having the external spending key, because child derivation at the Change level is non-hardened. +As of `Revision 2`_, to satisfy the above properties for transparent P2SH keys, +we derive the external and internal $\mathsf{ovk}$ components from the P2SH FVK +(described in `P2SH Viewing Key Items`_) as follows: + +- Let $\mathsf{fvk\_ser}$ be the raw encoding of the P2SH Viewing Key + Item (i.e. the concatenation of $\mathsf{template\_len}$, + $\mathsf{template}$, $\mathsf{n\_keys}$, and the key information + entries, as specified in `P2SH Viewing Key Items`_). +- Let $I_\mathsf{ovk} = \textsf{BLAKE2b-512}(\texttt{"ZIP316\_P2SH\_OVK\_"},\, \mathsf{fvk\_ser}).$ +- Let $\mathsf{ovk_{external}}$ be the first $32$ bytes of + $I_\mathsf{ovk}$ and let $\mathsf{ovk_{internal}}$ be the + remaining $32$ bytes of $I_\mathsf{ovk}$. + +Since a P2SH FVK encodes the keys, with their chain codes, at a level +from which both external and internal child keys can be derived (via +the ``/**`` multipath notation in the descriptor template), we can +derive both external and internal P2SH addresses without having any +spending key, because child derivation at the Change and Index levels +is non-hardened. + Deriving a UIVK from a UFVK --------------------------- As a consequence of the specification in `MUST-understand Typecodes`_, -as of `Revision 1`_ a Consumer of a UFVK MUST understand the meaning of +as of `Revision 2`_ a Consumer of a UFVK MUST understand the meaning of all "MUST-understand" Metadata Item Typecodes present in the UFVK in order to derive a UIVK from it. -If the source UFVK is Revision 1 then the derived UIVK SHOULD be -Revision 1; if the source UFVK includes any Metadata Items then -the derived UIVK MUST be Revision 1. +If the source UFVK is Revision 2 then the derived UIVK SHOULD be +Revision 2; if the source UFVK includes any Metadata Items then +the derived UIVK MUST be Revision 2. For Metadata Items recognised by the Consumer, the processing of the Item when deriving a UIVK is specified in the section or ZIP describing @@ -877,9 +1099,19 @@ 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]_. +* For a P2SH FVK (as of `Revision 2`_), the corresponding P2SH IVK + is obtained by: + + 1. Replacing each occurrence of ``/**`` in the descriptor template + with ``/*``. + 2. For each key in the key information vector, deriving the child key + with non-hardened index $0$ (external chain) as described in + [#bip-0032-public-to-public]_, and appending $0$ (non-hardened) + to the key's derivation path. + In each case, the Typecode remains the same as in the FVK. Items (including Metadata Items that are not "MUST-understand") that @@ -891,13 +1123,13 @@ Deriving a Unified Address from a UIVK -------------------------------------- As a consequence of the specification in `MUST-understand Typecodes`_, -as of `Revision 1`_ a Consumer of a UIVK MUST understand the meaning of +as of `Revision 2`_ a Consumer of a UIVK MUST understand the meaning of all "MUST-understand" Metadata Item Typecodes present in the UIVK in order to derive a Unified Address from it. -If the source UIVK is Revision 1 then the derived Unified Address -SHOULD be Revision 1; if the source UIVK includes any Metadata Items -then the derived Unified Address MUST be Revision 1. +If the source UIVK is `Revision 2`_ then the derived Unified Address +SHOULD be Revision 2; if the source UIVK includes any Metadata Items +then the derived Unified Address MUST be Revision 2. For Metadata Items recognised by the Consumer, the processing of the Item when deriving a Unified Address is specified in the section or @@ -911,11 +1143,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,9 +1177,19 @@ 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. +* As of `Revision 2`_, for a Transparent P2SH IVK, the corresponding P2SH + Receiver is obtained by: + + 1. For each key in the key information vector, deriving the child key + at the diversifier index using non-hardened BIP 32 public derivation + [#bip-0032-public-to-public]_. + 2. Instantiating the descriptor template by substituting each ``@N`` + placeholder with the corresponding derived public key, evaluating + the resulting output descriptor [#bip-0380]_ to obtain the output + script, and computing the HASH160 of the serialized script to + produce the P2SH Receiver Encoding. Items (including Metadata Items that are not "MUST-understand") that are unrecognised by a given Consumer, or that are specified in experiments @@ -985,7 +1239,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 +1248,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 +1257,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 +1284,19 @@ 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 -c^{n+m}}{q}.` +work $w$ to produce and verify a UA/UVK, and the size of the character +set is $c,$ then the generic attack costs $\sim \frac{w \cdot c^{n+m}}{q}.$ There is also a generic brute force attack against nonmalleability. The adversary modifies the target UA/UVK slightly and computes the corresponding decoding, then repeats until the decoding is valid and also useful to the adversary (e.g. it would lead to the Sender using a Transparent Address). -With :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 +1305,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 +1348,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 +1357,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 +1374,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,20 +1385,20 @@ 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 +the requirement to have at least one shielded Item in Revision 2 UA/UVKs (`see rationale <#rationale-for-dropping-the-at-least-one-shielded-item-restriction>`_). Note that Revision 0 of this ZIP specified a minimum input length to -: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 restrictions is not observable, other than potentially affecting which -error is reported. A Consumer supporting Revision 1 of this specification +error is reported. A Consumer supporting Revision 2 of this specification MAY therefore apply either the 48-byte or 38-byte minimum to Revision 0 UA/UVKs. @@ -1166,31 +1419,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 +1461,35 @@ attacks, or attacks that confuse addresses with viewing keys. Efficiency '''''''''' -The cost is dominated by 4 BLAKE2b compressions for :math:`\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 -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. +The cost is dominated by 4 BLAKE2b compressions for $\ell_M \leq 128$ +bytes. A Revision 0 UA containing a Transparent Address, a Sapling +Address, and an Orchard Address, would have $\ell_M = 128$ bytes. +A UA containing a Sapling Address and an Orchard +Address would have $\ell_M = 106$ bytes. For longer UAs (when other Receiver Types are added) or UVKs, the cost -increases to 6 BLAKE2b compressions for :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. @@ -1266,12 +1518,18 @@ Reference implementation ======================== Revision 0: + * https://github.com/zcash/librustzcash/pull/352 * https://github.com/zcash/librustzcash/pull/416 -Revision 1: +Revision 1 (Withdrawn): + * https://github.com/zcash/librustzcash/pull/1135 +Revision 2 (Draft): + +* https://github.com/zcash/librustzcash/pull/2199 + Acknowledgements ================ @@ -1281,6 +1539,18 @@ Marshall Gaucher, Joseph Van Geffen, Brad Miller, Deirdre Connolly, Teor, Eran Tromer, Conrado Gouvêa, and Marek Bielik for discussions on the subject of Unified Addresses and Unified Viewing Keys. +Changelog +========= + +`Revision 1`_ of this specification originally defined addresses with +capabilities essentially equivalent to the ``tu`` encoding specified in +`Revision 2`_; however, this specification was rejected by the community on the +grounds that users should be able to gain some sense of the privacy +implications of an address that they are sharing by visual inspection, which +unified addresses inhibit in general. `Revision 2`_ proposes the ``zu`` and +``tu`` prefixes to provide such visual distinguisability while retaining the +benefits related to supporting protocol upgrades and expiry metadata for both +shielded-only and transparent-transfer-permitting address types. References ========== @@ -1298,29 +1568,36 @@ References .. [#protocol-orchardpaymentaddrencoding] `Zcash Protocol Specification, Version 2023.4.0. Section 5.6.4.2: Orchard Raw Payment Addresses `_ .. [#protocol-orchardinviewingkeyencoding] `Zcash Protocol Specification, Version 2023.4.0. Section 5.6.4.3: Orchard Raw Incoming Viewing Keys `_ .. [#protocol-orchardfullviewingkeyencoding] `Zcash Protocol Specification, Version 2023.4.0. Section 5.6.4.4: Orchard Raw Full Viewing Keys `_ +.. [#protocol-2025.6.0] `Zcash Protocol Specification, Version 2025.6.0 [NU6.1 proposal]. Section 10: Change History — 2025.6.0 `_ .. [#zip-0000] `ZIP 0: ZIP Process `_ -.. [#zip-0032-sapling-helper-functions] `ZIP 32: Shielded Hierarchical Deterministic Wallets — Sapling helper functions `_ -.. [#zip-0032-sapling-extfvk] `ZIP 32: Shielded Hierarchical Deterministic Wallets — Sapling extended full viewing keys `_ -.. [#zip-0032-sapling-diversifier-derivation] `ZIP 32: Shielded Hierarchical Deterministic Wallets — Sapling diversifier derivation `_ -.. [#zip-0032-sapling-internal-key-derivation] `ZIP 32: Shielded Hierarchical Deterministic Wallets — Sapling internal key derivation `_ -.. [#zip-0032-orchard-child-key-derivation] `ZIP 32: Shielded Hierarchical Deterministic Wallets — Orchard child key derivation `_ -.. [#zip-0032-orchard-internal-key-derivation] `ZIP 32: Shielded Hierarchical Deterministic Wallets — Orchard internal key derivation `_ -.. [#zip-0032-specification-wallet-usage] `ZIP 32: Shielded Hierarchical Deterministic Wallets — Specification: Wallet usage `_ -.. [#zip-0032-sapling-key-path] `ZIP 32: Shielded Hierarchical Deterministic Wallets — Sapling key path `_ -.. [#zip-0032-orchard-key-path] `ZIP 32: Shielded Hierarchical Deterministic Wallets — Orchard key path `_ -.. [#zip-0203-default-expiry] `ZIP 203: Transaction Expiry — Changes for Blossom `_ +.. [#zip-0032-sapling-helper-functions] `ZIP 32: Shielded Hierarchical Deterministic Wallets — Sapling helper functions `_ +.. [#zip-0032-sapling-extfvk] `ZIP 32: Shielded Hierarchical Deterministic Wallets — Sapling extended full viewing keys `_ +.. [#zip-0032-sapling-diversifier-derivation] `ZIP 32: Shielded Hierarchical Deterministic Wallets — Sapling diversifier derivation `_ +.. [#zip-0032-sapling-internal-key-derivation] `ZIP 32: Shielded Hierarchical Deterministic Wallets — Sapling internal key derivation `_ +.. [#zip-0032-orchard-child-key-derivation] `ZIP 32: Shielded Hierarchical Deterministic Wallets — Orchard child key derivation `_ +.. [#zip-0032-orchard-internal-key-derivation] `ZIP 32: Shielded Hierarchical Deterministic Wallets — Orchard internal key derivation `_ +.. [#zip-0032-specification-wallet-usage] `ZIP 32: Shielded Hierarchical Deterministic Wallets — Specification: Wallet usage `_ +.. [#zip-0032-sapling-key-path] `ZIP 32: Shielded Hierarchical Deterministic Wallets — Sapling key path `_ +.. [#zip-0032-orchard-key-path] `ZIP 32: Shielded Hierarchical Deterministic Wallets — Orchard key path `_ +.. [#zip-0048] `ZIP 48: Transparent Multisig Wallets `_ +.. [#zip-0203-default-expiry] `ZIP 203: Transaction Expiry — Changes for Blossom `_ .. [#zip-0211] `ZIP 211: Disabling Addition of New Value to the Sprout Chain Value Pool `_ .. [#zip-0224] `ZIP 224: Orchard Shielded Protocol `_ +.. [#zip-0312] `ZIP 312: FROST for Spend Authorization Multisignatures `_ .. [#zip-0315] `ZIP 315: Best Practices for Wallet Handling of Multiple Pools `_ -.. [#zip-0320] `ZIP 320: Defining an Address Type to which funds can only be sent from Transparent Addresses `_ .. [#zip-0321] `ZIP 321: Payment Request URIs `_ +.. [#zip-2005-usagewithfrost] `ZIP 2005: Orchard Quantum Recoverability — Usage with FROST `_ .. [#bip-0032] `BIP 32: Hierarchical Deterministic Wallets `_ +.. [#bip-0032-conventions] `BIP 32: Hierarchical Deterministic Wallets — Conventions `_ +.. [#bip-0032-key-identifiers] `BIP 32: Hierarchical Deterministic Wallets — Key identifiers `_ .. [#bip-0032-serialization-format] `BIP 32: Hierarchical Deterministic Wallets — Serialization Format `_ .. [#bip-0032-public-to-public] `BIP 32: Hierarchical Deterministic Wallets — Child key derivation (CKD) functions: Public parent key → public child key `_ .. [#bip-0044] `BIP 44: Multi-Account Hierarchy for Deterministic Wallets `_ .. [#bip-0044-path-change] `BIP 44: Multi-Account Hierarchy for Deterministic Wallets — Path levels: Change `_ .. [#bip-0044-path-index] `BIP 44: Multi-Account Hierarchy for Deterministic Wallets — Path levels: Index `_ .. [#bip-0350] `BIP 350: Bech32m format for v1+ witness addresses `_ +.. [#bip-0380] `BIP 380: Output Script Descriptors General Operation `_ +.. [#bip-0388] `BIP 388: Wallet Policies for Descriptor Wallets `_ .. [#P2PKH] `Transactions: P2PKH Script Validation — Bitcoin Developer Guide `_ .. [#P2SH] `Transactions: P2SH Scripts — Bitcoin Developer Guide `_ .. [#Bitcoin-CompactSize] `Variable length integer. Bitcoin Wiki `_ diff --git a/zips/zip-0317.rst b/zips/zip-0317.rst index 4bb9986d1..5ca8b081f 100644 --- a/zips/zip-0317.rst +++ b/zips/zip-0317.rst @@ -2,11 +2,11 @@ ZIP: 317 Title: Proportional Transfer Fee Mechanism - Owners: Aditya Bharadwaj - Daira-Emma Hopwood + Owners: Daira-Emma Hopwood + Kris Nuttycombe + Jack Grigg + Original-Authors: Aditya Bharadwaj Credits: Madars Virza - Kris Nuttycombe - Jack Grigg Francisco Gindre Status: Active Category: Standards / Wallet @@ -75,6 +75,11 @@ Requirements two inputs and two outputs for each shielded pool used by the transaction). * Users should be able to spend a small number of UTXOs or notes with value below the marginal fee per input. +* 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. Specification @@ -87,10 +92,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 --------------- @@ -98,48 +103,65 @@ Fee calculation This specification defines several parameters that are used to calculate the conventional fee: -===================================== ============= ============================================== -Parameter Value Units -===================================== ============= ============================================== -:math:`marginal\_fee` :math:`5000` zatoshis per logical action (as defined below) -:math:`grace\_actions` :math:`2` logical actions -:math:`p2pkh\_standard\_input\_size` :math:`150` bytes -:math:`p2pkh\_standard\_output\_size` :math:`34` bytes -===================================== ============= ============================================== +============================================== ============= ============================================== +Parameter Value Units +============================================== ============= ============================================== +:math:`\mathit{marginal\_fee}` :math:`5000` zatoshis per logical action (as defined below) +:math:`\mathit{grace\_actions}` :math:`2` logical actions +:math:`\mathit{p2pkh\_standard\_input\_size}` :math:`150` bytes +:math:`\mathit{p2pkh\_standard\_output\_size}` :math:`34` bytes +:math:`\mathit{creation\_cost}` :math:`100` logical actions +============================================== ============= ============================================== Wallets implementing this specification SHOULD use a conventional fee -calculated in zatoshis per the following formula: +calculated in zatoshis per the following formulae: + +|br| .. math:: - \begin{array}{rcl} - contribution_{\,\mathsf{Transparent}} &=& - \mathsf{max}\big(\mathsf{ceiling}\big(\frac{tx\_in\_total\_size}{p2pkh\_standard\_input\_size}\big),\, - \mathsf{ceiling}\big(\frac{tx\_out\_total\_size}{p2pkh\_standard\_output\_size}\big)\big) \\ - contribution_{\,\rlap{\mathsf{Sprout}}\phantom{\mathsf{Transparent}}} &=& 2 \cdot nJoinSplit \\ - contribution_{\,\rlap{\mathsf{Sapling}}\phantom{\mathsf{Transparent}}} &=& \mathsf{max}(nSpendsSapling,\, nOutputsSapling) \\ - contribution_{\,\rlap{\mathsf{Orchard}}\phantom{\mathsf{Transparent}}} &=& nActionsOrchard \\ + \begin{array}{lcl} + \mathit{free\_memo\_chunks} &=& \begin{cases} + 2, &\!\!\text{if } \mathit{nOutputsSapling} + \mathit{nA\kern-0.05em ctionsOrchard} > 0, \\ + 0, &\!\!\text{otherwise} + \end{cases} + \\[4ex] + \mathit{contribution}_{\,\mathsf{Transparent}} &=& \mathsf{max}\big(\mathsf{ceiling}\big(\frac{\mathit{tx\_in\_total\_size}}{\mathit{p2pkh\_standard\_input\_size}}\big),\, + \mathsf{ceiling}\big(\frac{\mathit{tx\_out\_total\_size}}{\mathit{p2pkh\_standard\_output\_size}}\big)\big) \\ + \mathit{contribution}_{\,\mathsf{Sprout}} &=& 2 \cdot \mathit{nJoinSplit} \\ + \mathit{contribution}_{\,\mathsf{Sapling}} &=& \mathsf{max}(\mathit{nSpendsSapling},\, \mathit{nOutputsSapling}) \\ + \mathit{contribution}_{\,\mathsf{Orchard}} &=& \mathit{nA\kern-0.1em ctionsOrchard} \\ + \mathit{contribution}_{\,\mathsf{ZSAIssuance}} &=& \mathit{nZS\kern-0.1em AIssueNotes} \\ + \mathit{contribution}_{\,\mathsf{ZSACreation}} &=& \mathit{creation\_cost} \cdot \mathit{nA\kern-0.1em ssetCreations} \\ + \mathit{contribution}_{\,\mathsf{Memos}} &=& \mathsf{max}\big(0, \mathit{nMemoChunks} - \mathit{free\_memo\_chunks}\big) \\ + \\ + \mathit{logical\_actions} &=& \mathit{contribution}_{\,\mathsf{Transparent}} + + \mathit{contribution}_{\,\mathsf{Sprout}} + + \mathit{contribution}_{\,\mathsf{Sapling}} + + \mathit{contribution}_{\,\mathsf{Orchard}} \\ + & & \hspace{1em} +\; \mathit{contribution}_{\,\mathsf{ZSAIssuance}} + + \mathit{contribution}_{\,\mathsf{ZSACreation}} + + \mathit{contribution}_{\,\mathsf{Memos}} \\ \\ - logical\_actions &=& contribution_{\,\mathsf{Transparent}} + - contribution_{\,\mathsf{Sprout}} + - contribution_{\,\mathsf{Sapling}} + - contribution_{\,\mathsf{Orchard}} \\ - conventional\_fee &=& marginal\_fee \cdot \mathsf{max}(grace\_actions,\, logical\_actions) + \mathit{conventional\_fee} &=& \mathit{marginal\_fee} \cdot \mathsf{max}(\mathit{grace\_actions},\, \mathit{logical\_actions}) \\[6ex] \end{array} The inputs to this formula are taken from transaction fields defined in the Zcash protocol specification [#protocol-txnencoding]_: -============================ ====== =========================================== -Input Units Description -============================ ====== =========================================== -:math:`tx\_in\_total\_size` bytes total size in bytes of the ``tx_in`` field -:math:`tx\_out\_total\_size` bytes total size in bytes of the ``tx_out`` field -:math:`nJoinSplit` number the number of Sprout JoinSplits -:math:`nSpendsSapling` number the number of Sapling spends -:math:`nOutputsSapling` number the number of Sapling outputs -:math:`nActionsOrchard` number the number of Orchard actions -============================ ====== =========================================== +============================================= ====== ==================================================================== +Input Units Description +============================================= ====== ==================================================================== +:math:`\mathit{tx\_in\_total\_size}` bytes total size in bytes of the ``tx_in`` field +:math:`\mathit{tx\_out\_total\_size}` bytes total size in bytes of the ``tx_out`` field +:math:`\mathit{nJoinSplit}` number the number of Sprout JoinSplits +:math:`\mathit{nSpendsSapling}` number the number of Sapling spends +:math:`\mathit{nOutputsSapling}` number the number of Sapling outputs +:math:`\mathit{nA\kern-0.1em ctionsOrchard}` number the number of Orchard actions +:math:`\mathit{nZS\kern-0.1em AIssueNotes}` number the number of ``IssueNote`` outputs +:math:`\mathit{nA\kern-0.1em ssetCreations}` number the number of Custom Assets newly added to the Global Issuance State +:math:`\mathit{nMemoChunks}` number the number of memo chunks +============================================= ====== ==================================================================== It is not a consensus requirement that fees follow this formula; however, wallets SHOULD create transactions that pay this fee, in order to reduce @@ -158,7 +180,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 $\mathit{inputs} + \mathit{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 @@ -178,9 +200,6 @@ Rationale for the chosen parameters
    Click to show/hide -Grace Actions -~~~~~~~~~~~~~ - **Why not just charge per-action, without a grace window?** * This ensures that there is no penalty to padding a 1-action @@ -190,7 +209,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 $\mathit{marginal\_fee}$ *is* worth including, if a second input is available that covers both the primary output amount and the conventional transaction fee. @@ -202,38 +221,37 @@ 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 $\mathit{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, $\mathit{min\_actions} = 2$. -Having a grace window size greater than :math:`min\_actions` would +Having a grace window size greater than $\mathit{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 $\mathit{marginal\_fee}$ are +bounded above by $B / \mathsf{max}(\mathit{min\_actions}, \mathit{grace\_actions})$. +Therefore, the optimal choice of $\mathit{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 $\mathit{grace\_actions} = \mathit{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 -~~~~~~~~~~~~~~~~~~~~~~~~ +**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}(\mathit{transparent\_inputs}, \mathit{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 $\mathit{p2pkh\_standard\_input\_size}$ and +$\mathit{p2pkh\_standard\_output\_size}$ are based on the maximum encoded length for P2PKH inputs and outputs, as follows: -* :math:`p2pkh\_standard\_input\_size` +* $\mathit{p2pkh\_standard\_input\_size}$ * outpoint: 36 bytes * script: 110 bytes @@ -242,7 +260,7 @@ length for P2PKH inputs and outputs, as follows: * sequence: 4 bytes -* :math:`p2pkh\_standard\_output\_size` +* $\mathit{p2pkh\_standard\_output\_size}$ * value: 8 bytes * script: 26 bytes @@ -254,14 +272,39 @@ may be larger than P2PKH inputs. For example a 2-of-3 multisig input is around 70% larger, and is counted as such when computing the number of logical actions. -Marginal Fee -~~~~~~~~~~~~ +**Marginal Fee** This returns the conventional fee for a minimal transaction (as described above) to the original conventional fee of 10000 zatoshis specified in [#zip-0313]_, and imposes a non-trivial cost for potential denial-of-service attacks. +**ZSA Creation Cost** + +Every newly created Custom Asset adds a new row to the Global Issuance +State [#zip-0227-global-issuance-state]_ that full validators need to +track in perpetuity. Subsequent issuance, finalization, or burn of +existing Custom Assets only changes the values in the corresponding row. +Imposing a higher cost on Custom Asset creation events disincentivizes +the creation of "junk" assets. + +**Memo Chunks** + +Making the fee linear in the number of memo 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. + +Combined with the memo bundle size restriction, the maximum additional fee for +a ZIP 231 memo bundle [#zip-0231]_ over prior transactions is 0.0019 ZEC. + .. raw:: html
    @@ -275,7 +318,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 $\mathit{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 @@ -285,7 +328,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 $\mathit{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. @@ -299,47 +342,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 $\mathit{weight\_ratio\_cap} = 4$ and +$\mathit{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 $\mathit{conventional\_fee}(\mathit{tx})$ be the conventional fee for transaction +$\mathit{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 $\mathit{unpaid\_actions}(\mathit{tx}) = \begin{cases}\mathsf{max}\!\left(0,\, \mathsf{max}(\mathit{grace\_actions},\, \mathit{tx.logical\_actions}) - \mathsf{floor}\!\left(\frac{\mathit{tx.fee}}{\mathit{marginal\_fee}}\right)\right),&\textsf{if }\mathit{tx}\textsf{ is a non-coinbase transaction} \\ 0,&\textsf{if }\mathit{tx}\textsf{ is a coinbase transaction.}\end{cases}$ -Let :math:`block\_unpaid\_actions(block) = \sum_{tx \,\in\, block}\, unpaid\_actions(tx)`. +Let $\mathit{block\_unpaid\_actions}(\mathit{block}) = \sum_{\mathit{tx} \,\in\, \mathit{block}}\, \mathit{unpaid\_actions}(\mathit{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 $\mathit{tx}$ in the mempool, calculate + $\mathit{tx.weight\_ratio} = \mathsf{min}\!\left(\frac{\mathsf{max}(1,\, \mathit{tx.fee})}{\mathit{conventional\_fee}(\mathit{tx})},\, \mathit{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 $\mathit{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 $\mathit{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 $\mathit{block\_unpaid\_actions}(B) \leq \mathit{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, @@ -357,40 +400,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 $\mathit{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 $\mathit{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 $\mathit{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 $\mathit{tx.weight\_ratio}$ in terms of $\mathsf{max}(1,\, \mathit{tx.fee})$ +rather than just $\mathit{tx.fee}$ avoids needing to define "with probability in direct +proportion to its $\mathit{weight\_ratio}$" for the case where all remaining candidate +transactions would have $\mathit{weight\_ratio} = 0$. Incentive compatibility for miners '''''''''''''''''''''''''''''''''' @@ -437,7 +480,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 $\mathit{low\_fee\_penalty}$ threshold described in `Mempool size limiting`_ immediately. Nodes supporting block template construction SHOULD deploy the new @@ -471,7 +514,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 $\mathit{block\_unpaid\_action\_limit}$ by `zcashd` can be overridden using the ``-blockunpaidactionlimit`` configuration parameter. @@ -508,7 +551,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: @@ -536,16 +579,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 +* $\mathit{marginal\_fee} = 250$ in @nuttycom's proposal. +* $\mathit{marginal\_fee} = 1000$ adapted from @madars' proposal [#madars-1]_. +* $\mathit{marginal\_fee} = 2500$ in @daira's proposal. +* $\mathit{marginal\_fee} = 1000$ for Shielded, Shielding and De-shielding + transactions, and $\mathit{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` +$\mathit{base\_fee}$ parameter that caused the relationship between fee and number +of inputs/outputs to be non-proportional above the $\mathit{grace\_actions}$ threshold. This is no longer expressible with the formula specified above.) @@ -579,5 +622,7 @@ References .. [#protocol-txnencoding] `Zcash Protocol Specification, Version 2022.3.8. Section 7.1: Transaction Encoding and Consensus `_ .. [#sigop-limit] `zcash/zips issue #568 - Document block transparent sigops limit consensus rule `_ .. [#madars-1] `Madars concrete soft-fork proposal `_ +.. [#zip-0227-global-issuance-state] `ZIP 227: Issuance of Zcash Shielded Assets — Global Issuance State `_ +.. [#zip-0231] `ZIP 231: Memo Bundles `_ .. [#zip-0313] `ZIP 313: Reduce Conventional Transaction Fee to 1000 zatoshis `_ .. [#zip-0401] `ZIP 401: Addressing Mempool Denial-of-Service `_ diff --git a/zips/zip-0318.rst b/zips/zip-0318.rst deleted file mode 100644 index 02a3c3aba..000000000 --- a/zips/zip-0318.rst +++ /dev/null @@ -1,11 +0,0 @@ -:: - - ZIP: 318 - Title: Associated Payload Encryption - Owners: Kris Nuttycombe - Daira-Emma Hopwood - Status: Reserved - Category: Standards Track - Created: 2022-09-19 - License: MIT - Discussions-To: diff --git a/zips/zip-0319.rst b/zips/zip-0319.rst index da5134ecf..5359ee4c0 100644 --- a/zips/zip-0319.rst +++ b/zips/zip-0319.rst @@ -2,8 +2,8 @@ ZIP: 319 Title: Options for Shielded Pool Retirement - Owners: Nathan Wilcox - Daira-Emma Hopwood + Owners: Nathan Wilcox + Daira-Emma Hopwood Status: Reserved Category: Informational Created: 2022-09-20 diff --git a/zips/zip-0320.rst b/zips/zip-0320.rst index 19d4e4968..0d87206ce 100644 --- a/zips/zip-0320.rst +++ b/zips/zip-0320.rst @@ -2,10 +2,10 @@ ZIP: 320 Title: Defining an Address Type to which funds can only be sent from Transparent Addresses - Owners: Daira-Emma Hopwood + Owners: Daira-Emma Hopwood Kris Nuttycombe Credits: Hanh - Status: Proposed + Status: Active Category: Standards / Wallet Created: 2024-01-12 License: MIT @@ -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.: @@ -247,9 +247,9 @@ References .. [#hanh-suggestion] `Ywallet developer @hanh's proposal `_ .. [#zip-0032] `ZIP 32: Shielded Hierarchical Deterministic Wallets `_ .. [#zip-0316] `ZIP 316: Unified Addresses and Unified Viewing Keys `_ -.. [#zip-0316-terminology] `ZIP 316: Unified Addresses and Unified Viewing Keys — Terminology `_ -.. [#zip-0316-revision-1] `ZIP 316: Unified Addresses and Unified Viewing Keys — Revision 1 `_ -.. [#zip-0316-address-expiry] `ZIP 316: Unified Addresses and Unified Viewing Keys — Address Expiration Metadata `_ +.. [#zip-0316-terminology] `ZIP 316: Unified Addresses and Unified Viewing Keys — Terminology `_ +.. [#zip-0316-revision-1] `ZIP 316: Unified Addresses and Unified Viewing Keys — Revision 1 `_ +.. [#zip-0316-address-expiry] `ZIP 316: Unified Addresses and Unified Viewing Keys — Address Expiration Metadata `_ .. [#protocol-networks] `Zcash Protocol Specification, Version 2023.4.0. Section 3.12: Mainnet and Testnet `_ .. [#protocol-transparentaddrencoding] `Zcash Protocol Specification, Version 2023.4.0. Section 5.6.1.1 Transparent Addresses `_ .. [#binance-address-expiry] `Zcash Community Forum post describing motivations for address expiry `_ diff --git a/zips/zip-0321.rst b/zips/zip-0321.rst index 42f0be20a..9be1a94de 100644 --- a/zips/zip-0321.rst +++ b/zips/zip-0321.rst @@ -2,10 +2,10 @@ ZIP: 321 Title: Payment Request URIs - Owners: Kris Nuttycombe - Daira-Emma Hopwood + Owners: Kris Nuttycombe + Daira-Emma Hopwood Credits: Francisco Gindre - Status: Proposed + Status: Active Category: Standards / Wallet Created: 2020-08-28 Discussions-To: @@ -16,13 +16,16 @@ Terminology =========== -The key words "MUST", "REQUIRED", "MUST NOT", "SHOULD", "RECOMMENDED", 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 key words "MUST", "REQUIRED", "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 terms "Testnet" and "Mainnet" are to be interpreted as described in section 3.11 of the Zcash Protocol Specification [#protocol-networks]_. +The terms "Custom Asset", "Asset Identifier", and "asset description" in this +document are to be interpreted as described in ZIP 227 [#zip-0227]_. + The terms below are to be interpreted as follows: payment @@ -45,15 +48,15 @@ Motivation ========== In order for a robust transactional ecosystem to evolve for Zcash, it is -necessary for vendors to be able to issue requests for payment. At present, the -best option available is to manually specify a payment address, a payment -amount, and potentially memo field content. Of these three components, existing -wallets only provide functionality for reading payment addresses in a -semi-automated fashion. It is then necessary for the user to manually enter -payment amounts and any associated memo information, which is tedious and may -be error-prone, particularly if a payment is intended for multiple recipients -or the memo field information contains structured data that must be faithfully -reproduced. +necessary for vendors to be able to issue requests for payment. At the time +of first writing this ZIP, the best option available was to manually specify +a payment address, a payment amount, and potentially memo field content. +Of these three components, existing wallets only provided functionality for +reading payment addresses in a semi-automated fashion. It was then necessary +for the user to manually enter payment amounts and any associated memo +information, which is tedious and may be error-prone, particularly if a +payment is intended for multiple recipients or the memo field information +contains structured data that must be faithfully reproduced. This ZIP seeks to eliminate these issues by proposing a standard format that wallet vendors may support so that human intervention is required only for @@ -76,8 +79,8 @@ Requirements The format must be a valid URI format [#RFC3986]_. -The format must permit the representation of one or more (payment address, amount, -memo) tuples. +The format must permit the representation of one or more tuples of +payment address, amount, asset (if applicable), and optional memo. Specification @@ -93,17 +96,18 @@ The following syntax specification uses ABNF [#RFC5234]_. zcashurn = "zcash:" ( zcashaddress [ "?" zcashparams ] / "?" zcashparams ) zcashaddress = 1*( ALPHA / DIGIT ) zcashparams = zcashparam [ "&" zcashparams ] - zcashparam = [ addrparam / amountparam / memoparam / messageparam / labelparam / reqparam / otherparam ] + zcashparam = [ addrparam / amountparam / assetparam / memoparam / messageparam / labelparam / otherreqparam / otherparam ] NONZERO = %x31-39 DIGIT = %x30-39 paramindex = "." NONZERO 0*3DIGIT - addrparam = "address" [ paramindex ] "=" zcashaddress - amountparam = "amount" [ paramindex ] "=" 1*DIGIT [ "." 1*8DIGIT ] - labelparam = "label" [ paramindex ] "=" *qchar - memoparam = "memo" [ paramindex ] "=" *base64url - messageparam = "message" [ paramindex ] "=" *qchar + addrparam = "address" [ paramindex ] "=" zcashaddress + amountparam = "amount" [ paramindex ] "=" 1*DIGIT [ "." 1*8DIGIT ] + assetparam = "req-asset" [ paramindex ] "=" *base64url + labelparam = "label" [ paramindex ] "=" *qchar + memoparam = "memo" [ paramindex ] "=" *base64url + messageparam = "message" [ paramindex ] "=" *qchar paramname = ALPHA *( ALPHA / DIGIT / "+" / "-" ) - reqparam = "req-" paramname [ paramindex ] [ "=" *qchar ] + otherreqparam = "req-" paramname [ paramindex ] [ "=" *qchar ] otherparam = paramname [ paramindex ] [ "=" *qchar ] qchar = unreserved / pct-encoded / allowed-delims / ":" / "@" allowed-delims = "!" / "$" / "'" / "(" / ")" / "*" / "+" / "," / ";" @@ -120,7 +124,7 @@ production ``x``. Productions of the form ``*x`` indicate at least `` a at most `` instances of production ``x``. Note that this grammar does not allow percent encoding outside the productions -that use ``qchar``, i.e. the values of label, message, ``reqparam``, and +that use ``qchar``, i.e. the values of label, message, ``otherreqparam``, and ``otherparam`` parameters. Purported ZIP 321 URIs that cannot be parsed according to the above grammar @@ -161,6 +165,9 @@ If there are any non-address parameters having a given ``paramindex``, then the URI MUST contain an address parameter having that ``paramindex``. There MUST NOT be more than one occurrence of a given parameter and ``paramindex``. +A URI containing both an ``amount`` parameter and a ``req-asset`` parameter +at the same ``paramindex`` MUST be rejected. + Implementations SHOULD check that each instance of ``zcashaddress`` is a valid string encoding of an address, other than a Sprout address, as specified in the subsections of section 5.6 (Encoding of Addresses and Keys) of the Zcash protocol @@ -192,24 +199,103 @@ to satisfy requests for payment to a Sprout address. If the same rationale applies to other address types in future, consideration should be given to updating this ZIP to exclude these types, as part of their deprecation. -Transfer amount ---------------- +Custom Assets +------------- + +The ``req-asset`` parameter permits the specification of both an Asset Identifier +and an amount for a payment. It is encoded as follows: + +$\hspace{2em}\mathtt{asset} = \mathsf{base64url}\big([\mathtt{0x00}] \,||\, \mathsf{I2LEOSP}_{64}(value) \,||\, \mathsf{EncodeAssetId}(\mathsf{AssetId})\big)$ + +The leading version byte (``0x00``) indicates the encoding format. For version +``0x00``, the next 8 bytes represent the amount as an unsigned 64-bit integer in +little-endian byte order, followed by the encoded $\mathsf{AssetId}$, as defined +in ZIP 227 [#zip-0227-asset-identifier]_. + +Future versions MAY define different structures or lengths after the version +byte; implementations MUST use the version value to determine how to decode +the remainder of the parameter. + +If no ``req-asset`` parameter is present, the payment MUST be considered to +be for ZEC, and the transfer amount in ZEC is specified using the ``amount`` +parameter. + +Only Orchard receivers are valid for Custom Asset payments. Therefore, a payment +request for a Custom Asset MUST use a Unified Address that encodes at least one +Orchard receiver. + +Example +~~~~~~~ + +.. raw:: html + +
    + Click to show/hide + +Suppose the asset description is "USD testing", with an invented digest and +issuer key as inputs. The resulting 66-byte value is: + +:: + + 0000deadbeefdeadbeefdeadbeefdeadbeefdeadbeefdeadbeefdeadbeefdeadbeef + 11223344556677889900aabbccddeeff00112233445566778899aabbccddeeff + +We want to create a URI to request a payment of ``10055`` minimal units of +this asset (hypothetically representing 100.55 USD): + +:: + + 100.55 USD = 10055 minimal units + = 0x0000000000002747 + = 47 27 00 00 00 00 00 00 (8 bytes, little-endian) + +Concatenating the version byte, amount, and asset id gives (hex): + +:: + + 00 + 4727000000000000 + 0000deadbeefdeadbeefdeadbeefdeadbeefdeadbeefdeadbeefdeadbeefdeadbeef + 11223344556677889900aabbccddeeff00112233445566778899aabbccddeeff -If an amount is provided, it MUST be specified in decimal ZEC. If a decimal fraction -is present then a period (`.`) MUST be used as the separating character to separate -the whole number from the decimal fraction, and both the whole number and the -decimal fraction MUST be nonempty. No other separators (such as commas for -grouping or thousands) are permitted. Leading zeros in the whole number or trailing -zeros in the decimal fraction are ignored. There MUST NOT be more than 8 digits in -the decimal fraction. +Base64url-encoded (unpadded) for the entire 75-byte blob, this becomes +(100 characters): + +:: + + AEcnAAAAAAAAAADerb7v3q2-796tvu_erb7v3q2-796tvu_erb7v3q2-7xEiM0RVZneImQCqu8zd7v8AESIzRFVmd4iZqrvM3e7_ + +A payment URI using this ``req-asset`` could look like: + +:: + + zcash:utest1q9d6gqg...7y0d9zj7ns2ceqk4j0d6ngqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqq7e4t0p + ?req-asset=AEcnAAAAAAAAAADerb7v3q2-796tvu_erb7v3q2-796tvu_erb7v3q2-7xEiM0RVZneImQCqu8zd7v8AESIzRFVmd4iZqrvM3e7_ + +.. raw:: html + +
    + +ZEC Transfer Amount +------------------- + +If an ``amount`` parameter is provided, its value is interpreted as decimal ZEC. + +If a decimal fraction is present then a period (`.`) MUST be used as the separating +character to separate the whole number from the decimal fraction, and both the +whole number and the decimal fraction MUST be nonempty. No other separators (such +as commas for grouping or thousands) are permitted. Leading zeros in the whole +number or trailing zeros in the decimal fraction are ignored. There MUST NOT be +more than 8 digits in the decimal fraction. For example, - * ``amount=50.00`` or ``amount=50`` or ``amount=050`` is treated as 50 ZEC; - * ``amount=0.5`` or ``amount=00.500`` is treated as 0.5 ZEC; and - * ``amount=50,000.00`` or ``amount=50,00`` or ``amount=50.`` or ``amount=.5`` - or ``amount=0.123456789`` are invalid. -The amount MUST NOT be greater than 21000000 ZEC (in general, monetary amounts +* ``amount=50.00`` or ``amount=50`` or ``amount=050`` is treated as 50 ZEC; +* ``amount=0.5`` or ``amount=00.500`` is treated as 0.5 ZEC; and +* ``amount=50,000.00`` or ``amount=50,00`` or ``amount=50.`` or ``amount=.5`` + or ``amount=0.123456789`` are invalid. + +The amount MUST NOT be greater than 21000000 ZEC (in general, ZEC monetary amounts in Zcash cannot be greater than this value). Query Keys @@ -256,6 +342,23 @@ address, with a base64url-encoded memo and a message for display by the wallet. A valid payment request with one transparent and one shielded Sapling recipient address, with a base64url-encoded Unicode memo for the shielded recipient. +:: + + zcash:?address=utest1qpsw0d7s6e5t7dv8x8yyw5e4v4jh8p5kux6g5v4kthh0nngwh2c5ue2x8p3wxy7qsqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqq7egr7p + &req-asset=AEcnAAAAAAAAAADerb7v3q2-796tvu_erb7v3q2-796tvu_erb7v3q2-7xEiM0RVZneImQCqu8zd7v8AESIzRFVmd4iZqrvM3e7_ + &address.1=utest1qplk9cnv5u2r0z8a3g7yyjv4x3v5h4d0nx3uq36zj2u4p6h9ty4g8r9xk2q0d2n7qqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqq4u3aq + &req-asset.1=AJAIAwAAAAAAADerb7v3q2-796tvu_erb7v3q2-796tvu_erb7v3q2-7xEiM0RVZneImQCqu8zd7v8AESIzRFVmd4iZqrvM3e7_ + +This is a valid payment request with two recipients, each using a distinct Unified +Address that includes an Orchard receiver. Each ``req-asset`` value encodes, in order, +a version byte (``0x00``), an 8-byte unsigned integer amount in minimal units, and +a 66-byte ``EncodeAssetId``. + +In this example both payments reference the same asset: the first requests 10 055 +minimal units (100.55 "USD testing"), and the second requests 250 000 minimal +units (2 500.00 "USD testing"). + + Invalid Examples ~~~~~~~~~~~~~~~~ @@ -303,6 +406,21 @@ Invalid; the grammar does not allow ``//``. ZIP 321 URIs are not "hierarchical URIs" in the sense defined in [#RFC3986]_ section 1.2.3, and do not have an "authority component". +:: + + zcash:?address=ztestsapling10yy2ex5dcqkclhc7z7yrnjq2z6feyjad56ptwlfgmy77dmaqqrl9gyhprdx59qgmsnyfska2kez + &amount=5 + &req-asset=not@valid!chars + +Invalid: + +* A Sapling address is used with a ``req-asset`` parameter. Sapling receivers do not + support Custom Asset payments (only Unified Addresses with an Orchard receiver do). +* The ``req-asset`` value contains characters (e.g., ``@``, ``!``) that are not + permitted in base64url. +* The ``amount`` parameter is present together with ``req-asset``. These parameters + are mutually exclusive. + Forward compatibility --------------------- @@ -344,6 +462,8 @@ References .. [#base58check] `Bitcoin Wiki: Base58Check encoding `_ .. [#zip-0173] `ZIP 173: Bech32 Format `_ .. [#zip-0211] `ZIP 211: Disabling Addition of New Value to the Sprout Value Pool `_ +.. [#zip-0227] `ZIP 227: Issuance of Zcash Shielded Assets `_ +.. [#zip-0227-asset-identifier] `ZIP 227: Issuance of Zcash Shielded Assets — Asset Identifier `_ .. [#zip-0316] `ZIP 316: Unified Addresses and Unified Viewing Keys `_ .. [#protocol-networks] `Zcash Protocol Specification, Version 2023.4.0. Section 3.11: Mainnet and Testnet `_ .. [#protocol-saplingbalance] `Zcash Protocol Specification, Version 2023.4.0. Section 4.12: Balance and Binding Signature (Sapling) `_ diff --git a/zips/zip-0322.rst b/zips/zip-0322.rst index adc37295f..1431bf27b 100644 --- a/zips/zip-0322.rst +++ b/zips/zip-0322.rst @@ -2,8 +2,8 @@ ZIP: 322 Title: Generic Signed Message Format - Owners: Jack Grigg - Daira-Emma Hopwood + Owners: Jack Grigg + Daira-Emma Hopwood Status: Reserved Category: Standards / RPC / Wallet Discussions-To: diff --git a/zips/zip-0323.rst b/zips/zip-0323.rst index 5e5465e6f..9bad3cc1d 100644 --- a/zips/zip-0323.rst +++ b/zips/zip-0323.rst @@ -2,8 +2,8 @@ ZIP: 323 Title: Specification of getblocktemplate for Zcash - Owners: Daira-Emma Hopwood - Jack Grigg + Owners: Daira-Emma Hopwood + Jack Grigg Status: Reserved Category: RPC / Mining Discussions-To: diff --git a/zips/zip-0324.rst b/zips/zip-0324.rst index 93f861e56..75a174305 100644 --- a/zips/zip-0324.rst +++ b/zips/zip-0324.rst @@ -2,9 +2,9 @@ ZIP: 324 Title: URI-Encapsulated Payments - Owners: Jack Grigg - Daira-Emma Hopwood - Kris Nuttycombe + Owners: Jack Grigg + Daira-Emma Hopwood + Kris Nuttycombe Original-Authors: Ian Miers Eran Tromer Jack Grigg @@ -19,6 +19,7 @@ Category: Standards / Wallet Created: 2019-07-17 License: MIT + Discussions-To: Terminology @@ -386,7 +387,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-0325.md b/zips/zip-0325.md new file mode 100644 index 000000000..41541af88 --- /dev/null +++ b/zips/zip-0325.md @@ -0,0 +1,205 @@ + + ZIP: 325 + Title: Account Metadata Keys + Owners: Jack Grigg + Daira-Emma Hopwood + Kris Nuttycombe + Status: Draft + Category: Standards / Wallet + Created: 2025-02-18 + License: MIT + Discussions-To: + Pull-Request: + + +# Terminology + +The key words "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. + + +# Abstract + +This ZIP specifies the key tree for Account Metadata Keys. These are derived +from the same seed as a ZIP 32 [^zip-0032] account, and can be used by wallets +to derive encryption keys for local / off-chain metadata. + + +# Motivation + +A wallet's main data source is the Zcash chain: from this it can detect notes +received by an account, determine whether those notes are spent, build witnesses +for spending, recover on-chain memo data, and so on. However, wallets also +generate significant quantities of off-chain metadata as they are used, such as: + +- Local annotations about transactions in the wallet. +- Mappings between Zcash addresses and user-meaningful recipient names. +- The exchange rate from ZEC to another currency that was used to determine how + much ZEC to send in a payment. + +This metadata is valuable to users, and highly desirable to ensure to be backed up. +If the user's device is wiped or lost and the user recovers their wallet from a +backed-up mnemonic phrase, they will lose all of this metadata if it is not +stored somewhere. + +For other kinds of mobile device data, it is expected by users that their device's +normal backup storage will have saved (most of) their data, such that access to +e.g. the associated Apple or Google account will be sufficient for data recovery. +However, metadata such as mappings between Zcash addresses and recipient names can +be particularly sensitive, meaning that users may not want these to be backed up +unencrypted in their device's normal backup storage. Similarly, the inability to +alter on-chain data means that permanently storing metadata in transaction memo +fields may also not be an option. + +Additionally, it is currently the case that users only need to back up a single +secret (a mnemonic seed phrase), once, in order to recover all information for +accounts derived from that secret. If metadata were encrypted using independent +key material, these keys would also need to be backed up, leading to fragility +of wallet restoration. + + +# Requirements + +- The user should not need to update their existing backups of secret material. +- It should be possible to store metadata about accounts for which we don't + control spend authority (i.e. imported UFVKs). +- The key tree must be future-extensible. + + +# Specification + +## Metadata key tree + +This ZIP registers the following ZIP 32 Registered Key Derivation [^zip-0032-rkd] +tree: + +- $\mathsf{ContextString} = \texttt{“MetadataKeys”}$ +- $\mathsf{ZipNumber} = 325$ + +The tree has the following general structure, specified in more detail below: + +- $m_{\mathsf{metadata}}$: Metadata Key tree + - $m_{\mathsf{metadata}} / 325' / \mathsf{coinType}' / \mathsf{account}'$ - Account Metadata Key + - $\ldots / 0'$ - Account-level Inherent Metadata Key + - $\ldots / \ldots$ - (Reserved for future updates to this ZIP) + - $\ldots / (\mathtt{0x7FFFFFFF}', \mathsf{PrivateUseSubject})$ - Private-use Inherent Metadata Key + - $\ldots / 1'$ - Account-level External Metadata Key + - $\ldots / (0', \mathsf{FVKTypedItem})$ - Imported UFVK Metadata Key + - $\ldots / \ldots$ - (Reserved for future updates to this ZIP) + - $\ldots / (\mathtt{0x7FFFFFFF}', \mathsf{PrivateUseSubject})$ - Private-use External Metadata Key + - $\ldots / \ldots$ - (Reserved for future updates to this ZIP) + - $\ldots / \ldots$ - (Reserved for future updates to this ZIP) + +Non-leaf keys in the key tree MUST NOT be used directly to encrypt metadata. +Encryption keys are leaves in this key tree. The sole exception to this is +private-use keys (for which part of their key derivation is outside the scope of +this specification): encryption keys MAY be derived from the private-use key +leaves. + +### Account Metadata Key + +The Account Metadata Key is the root of a subtree that corresponds to a ZIP 32 +account represented elsewhere in the overall tree. It is derived from the seed +$\mathsf{S}$ as: + +$\mathsf{AccountMetadataKey} = \mathsf{CKDreg}(\mathsf{CKDreg}(\mathsf{RegKD}(\texttt{“MetadataKeys”}, \mathsf{S}, 325), \mathsf{coinType}, [\,]), \mathsf{account}, [\,])$ + +or, in path notation: + +``` +m_metadata / 325' / coin_type' / account' +``` + +### Inherent metadata keys + +The Account-level Inherent Metadata Key's subtree contains keys used for +metadata associated with the Account Metadata Key's corresponding account. The +key is derived as: + +$\mathsf{CKDreg}(\mathsf{AccountMetadataKey}, 0, [\,])$ + +### External metadata keys + +The Account-level External Metadata Key's subtree contains keys used for +metadata associated with imported UFVKs. Unlike the inherent metadata keys which +can leverage the inherent domain separation provided by the account index, here +domain separation between metadata keys is provided by the UFVKs themselves. + +As UFVKs may in general change over time (due to the inclusion of new +higher-preference FVK items, or removal of older deprecated FVK items), there is +no guarantee that the exact same set of FVK items will be present at both backup +creation time and recovery time. Instead, the most preferred FVK item within a +UFVK is used as the domain in which keys can be generated, and the Imported +UFVK Metadata Key is derived as: + +$\mathsf{CKDreg}(\mathsf{CKDreg}(\mathsf{AccountMetadataKey}, 1, [\,]), 0, \mathsf{FVKTypedItem})$ + +where $\mathsf{FVKTypedItem}$ is the encoding of the most preferred FVK +item within the ZIP 316 raw encoding of a UFVK. [^zip-0316] + +Usage of the Imported UFVK Metadata Key trees SHOULD follow ZIP 316 preference +order: [^zip-0316] + +- For encryption-like usage, the key tree corresponding to the most preferred + FVK item within a UFVK SHOULD be used. +- For decryption-like usage, each key tree SHOULD be tried in preference order + until metadata can be recovered. If metadata is recovered via an FVK item that + is not the most preferred, wallets SHOULD update their metadata backups by + re-encrypting the metadata using the key tree corresponding to the most + preferred FVK item. + +## Standardised metadata protocols + +The following metadata protocols have been standardised: + +- None at time of writing. + +The remaining range of child indices from 0 to $\texttt{0x7FFFFFFE}$ inclusive +are reserved for future updates to this ZIP. Wallet developers can propose new +standardised metadata protocols by writing a 2000-series ZIP that specifies the +protocol as an update to this ZIP. + +## Private-use metadata keys + +In some contexts there is a need for deriving ad-hoc key trees for private use +by wallets, without ecosystem coordination and without any kind of compatibility +guarantees. This ZIP reserves child index $\mathtt{0x7FFFFFFF}$ (the maximum +valid hardened child index) within its key tree for this purpose. + +- Let $K$ be either the Account-level Inherent Metadata Key, or an Imported UFVK + Metadata Key. +- Let $\mathsf{PrivateUseSubject}$ be a globally unique non-empty sequence of at + most 252 bytes that identifies the desired private-use context. +- Return $\mathsf{CKDreg}(K, \mathtt{0x7FFFFFFF}, \mathsf{PrivateUseSubject})$ + +
    + +It is the responsibility of wallet developers to ensure that they do not use +colliding $\mathsf{PrivateUseSubject}$ values, and to analyse their private use for +any security risks related to potential cross-protocol attacks (in the event that +two wallet developers happen to select a colliding $\mathsf{PrivateUseSubject}$). +Wallet developers that are unwilling to accept these risks SHOULD propose new +standardised metadata protocols instead, to benefit from ecosystem coordination +and review. + +
    + +Zashi uses the string $\texttt{“metadata”}$ for one of its $\mathsf{PrivateUseSubject}$ use cases. +This is an example of a bad choice of private-use name, since it does not include +a wallet-specific prefix such as $\texttt{“Zashi”}$, or a version number. + +# Reference implementation + +- https://github.com/Electric-Coin-Company/zcash-android-wallet-sdk/pull/1686 + + +# 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"](https://www.rfc-editor.org/info/bcp14) + +[^zip-0032]: [ZIP 32: Shielded Hierarchical Deterministic Wallets](zip-0032.rst) + +[^zip-0032-rkd]: [ZIP 32: Shielded Hierarchical Deterministic Wallets, Section: Registered key derivation](zip-0032.rst#specification-registered-key-derivation) + +[^zip-0316]: [ZIP 316: Unified Addresses and Unified Viewing Keys](zip-0316.rst) diff --git a/zips/zip-0332.rst b/zips/zip-0332.rst index 27ee7e630..af71ca03d 100644 --- a/zips/zip-0332.rst +++ b/zips/zip-0332.rst @@ -2,8 +2,8 @@ ZIP: 332 Title: Wallet Recovery from zcashd HD Seeds - Owners: Kris Nuttycombe - Daira-Emma Hopwood + Owners: Kris Nuttycombe + Daira-Emma Hopwood Status: Reserved Category: Wallet Discussions-To: diff --git a/zips/zip-0339.rst b/zips/zip-0339.rst index aa1cb8bc6..bc5dd37d0 100644 --- a/zips/zip-0339.rst +++ b/zips/zip-0339.rst @@ -2,7 +2,7 @@ ZIP: 339 Title: Wallet Recovery Words - Owners: Daira-Emma Hopwood + Owners: Daira-Emma Hopwood Status: Reserved Category: Wallet Discussions-To: diff --git a/zips/zip-0350.md b/zips/zip-0350.md new file mode 100644 index 000000000..e9f230ae5 --- /dev/null +++ b/zips/zip-0350.md @@ -0,0 +1,5 @@ + ZIP: 350 + Title: Bech32m + Status: Reserved + Category: Standards / Wallet + Discussions-To: diff --git a/zips/zip-0401.rst b/zips/zip-0401.rst index e319996a8..d86663304 100644 --- a/zips/zip-0401.rst +++ b/zips/zip-0401.rst @@ -2,7 +2,7 @@ ZIP: 401 Title: Addressing Mempool Denial-of-Service - Owners: Daira-Emma Hopwood + Owners: Daira-Emma Hopwood Status: Active Category: Network Created: 2019-09-09 @@ -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-0416.rst b/zips/zip-0416.rst index f8ccc6911..eb15749bc 100644 --- a/zips/zip-0416.rst +++ b/zips/zip-0416.rst @@ -2,12 +2,9 @@ ZIP: 416 Title: Support for Unified Addresses in zcashd - Owners: Daira-Emma Hopwood - Jack Grigg - Sean Bowe - Kris Nuttycombe - Ying Tong Lai - Steven Smith + Owners: Daira-Emma Hopwood + Jack Grigg + Kris Nuttycombe Status: Reserved Category: RPC / Wallet Discussions-To: diff --git a/zips/zip-1013.rst b/zips/zip-1013.rst index da3a0e05d..5ee388a20 100644 --- a/zips/zip-1013.rst +++ b/zips/zip-1013.rst @@ -117,7 +117,7 @@ expected due to: over 4 years depends completely on the continued health & growth of the Zcash ecosystem; * proven records of dedication to the Zcash project, and effective efforts on - related projects, by receipient entities & personnel – even in the absence + related projects, by recipient entities & personnel – even in the absence of formalized funding conditions. From original "Founders’ Reward"-era development-funds, roughly 15% has been diff --git a/zips/zip-1014.rst b/zips/zip-1014.rst index f6934e1f5..196af14f1 100644 --- a/zips/zip-1014.rst +++ b/zips/zip-1014.rst @@ -3,7 +3,7 @@ ZIP: 1014 Title: Establishing a Dev Fund for ECC, ZF, and Major Grants Owners: Andrew Miller - Zooko Wilcox + Zooko Wilcox Original-Authors: Eran Tromer Credits: Matt Luongo @aristarchus diff --git a/zips/zip-1015.rst b/zips/zip-1015.rst index 059441908..e6ca4e41b 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 @@ -9,7 +9,7 @@ Daira-Emma Hopwood Jack Grigg Skylar Saveland - Status: Proposed + Status: Final Category: Consensus Created: 2024-08-26 License: MIT @@ -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-1016.md b/zips/zip-1016.md new file mode 100644 index 000000000..afc97deca --- /dev/null +++ b/zips/zip-1016.md @@ -0,0 +1,174 @@ + ZIP: 1016 + Title: Community and Coinholder Funding Model + Owners: Josh Swihart + Credits: Daira-Emma Hopwood + Kris Nuttycombe + Jack Grigg + Tatyana Peacemonger + Alex Bornstein + Jason McGee + Status: Proposed + Category: Consensus / Process + Created: 2025-02-19 + License: MIT + Pull-Request: + + + +# Terminology + +The key words "MUST", "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 terms "Mainnet" and "Testnet" in this document are to be interpreted as defined in the Zcash protocol specification [^protocol-networks]. + +The terms "Electric Coin Company" (or "ECC"), "Bootstrap Project" (or "BP") and "Zcash Foundation" (or "ZF") in this document are to be interpreted as described in ZIP 1014 [^zip-1014]. + +The terms "Zcash Community Grants" (or "ZCG"), "ZCG Committee", "Financial Privacy Foundation" (or "FPF"), and "Deferred Dev Fund Lockbox" in this document are to be interpreted as defined in ZIP 1015 [^zip-1015]. + +"Shielded Labs" refers to the Assocation of that name registered in the Swiss canton of Zug under the Unique Identifier CHE-243.302.798. + +Protocol-defined Ecosystem Funding is funding from sources defined by the Zcash Protocol for development of the Zcash ecosystem. At the time of writing, Protocol-defined Ecosystem Funding is allocated from a portion of block rewards via Funding Streams [^zip-0207] and Lockbox Funding Streams [^zip-2001]. + +“ZEC” refers to the native currency of Zcash on Mainnet. + + +# Abstract + +This proposal outlines a funding model that gives the community and coin holders distinct voices in determining what, if any, grants are provided to support Zcash’s development and community efforts. + +In this model: + +* 8% of the block rewards will be allocated to the ZCG for grants by and for the Zcash Community. +* 12% of the block rewards will accrue to a fund controlled by decisions of coin holders, seeded by the Deferred Dev Fund Lockbox. + +The Coinholder-Controlled Fund may be used to distribute larger grants to ecosystem participants, or left at rest. + +This model would be activated through until the 3rd halving, allowing enough time to determine whether it should be changed or codified for longer. + + +# Motivation + +If no action is taken, in November 2025 funds from block subsidies will stop being directed to Zcash Community Grants [^zip-1015-zcg] and to the Deferred Dev Fund Lockbox established by ZIP 2001 [^zip-2001]. If the block subsidies stop, it will risk a gap in funding of Zcash development organisations, either via ZCG grants or via potential future disbursements from the Deferred Dev Fund Lockbox. + +This proposal aims to: +* decentralize decision-making, +* hold stakeholders accountable for outcomes, +* be dynamic enough to allow for change, and +* provide clarity on decision-making. + +It would immediately increase coinholders’ voice, minimize governance confusion, and simplify decision-making. + +# Requirements + +* There is a well-defined, publically agreed, process for evaluation and community feedback on grant proposals. +* Funds are held in a multisig resistant to compromise of some of the parties' keys, up to a given threshold. +* No single party's non-cooperation or loss of keys is able to cause any Protocol-defined Ecosystem Funding to be locked up unrecoverably. +* During the period of this proposal, the block rewards are distributed as described in the [Abstract] above. +* The funds from the 8% funding stream will be usable immediately on activation of this ZIP. +* The funds in the Deferred Dev Fund Lockbox will be usable immediately on activation of this ZIP. +* Any use of Deferred Dev Fund Lockbox funds is consistent with the purpose specified in [^zip-1015-lockbox] of "funding grants to ecosystem participants". + +# Non-requirements + +* Any changes to the ZCG or its governance, such as its expansion to include more members, may be desired but are specifically outside this proposal’s scope. +* Any changes to Zcash protocol governance, specifically what changes are made to consensus node software, are outside this proposal’s scope. + +# Specification + +This proposal empowers both the community (through ZCG) and coin holders to independently determine what, if anything, should be funded through development fund grants. + +The funding streams described below will be defined in a new revision of ZIP 214 [^zip-0214]. + +## Zcash Community Grants + +A funding stream will be established for Zcash Community Grants, consisting of 8% of the block subsidy, and subject to all of the same rules currently specified in ZIP 1015 [^zip-1015-zcg]. + +On Mainnet, this funding stream will start on expiry of the existing ``FS_FPF_ZCG`` funding stream [^zip-1015-funding-streams], and last for a further 1,260,000 blocks (approximately 3 years), ending at Zcash's 3rd halving. + +## Coinholder-Controlled Fund + +A pool of multisig-controlled funds, seeded from the existing contents of the ZIP 1015 Deferred Dev Fund Lockbox [^zip-1015-lockbox] and supplemented with a funding stream consising of 12% of the block subsidy for the same time period as the Zcash Community Grants stream, forms a new Coinholder-Controlled Fund. The mechanisms for the creation and management of this fund are described by the Deferred Dev Fund Lockbox Disbursement proposal [^zip-271]. This proposal sets the $\mathsf{stream\_value}$ parameter of that proposal to 12%, and the $\mathsf{stream\_end\_height}$ parameter to Mainnet block height 4406400, equal to that of the Zcash Community Grants stream so that both streams end at Zcash's 3rd halving. + +### Requirements on use of the Coinholder-Controlled Fund + +The Key-Holder Organizations SHALL be bound by a legal agreement to only use funds held in the Coinholder-Controlled Fund according to the specifications in this ZIP, expressed in suitable legal language. In particular, all requirements on the use of Deferred Dev Fund Lockbox funds in ZIP 1015 [^zip-1015-lockbox] MUST be followed for the Coinholder-Controlled Fund. + +The Key-Holder Organizations collectively administer the Coinholder-Controlled Fund based on decisions taken by coinholder voting, following a model decided by the community and specified in another ZIP [TBD]. + +### Disbursement process + +1. Anyone can submit a grant application via a process agreed upon by the Key-Holder Organizations. +2. Coinholders will vote on grant applications every three months. Grant applications must be submitted for community review 30 days prior to coinholder voting. +3. If a grant application is not [vetoed](#veto-process) and proceeds to a coinholder vote according to the agreed process, then coinholders will be asked to vote on it. +4. If the vote passes, then as payments are scheduled for the grant, then (subject to the [Veto process]) the Key-Holder Organizations SHOULD sign the corresponding transactions for disbursement from the Coinholder-Controlled Fund. + +For coinholder votes, a minimum of 420,000 ZEC (2% of the total eventual supply) MUST be voted, with a simple majority cast in favor, for a grant proposal to be approved. Upon approval, the grants are paid to the recipient per the terms of the grant proposal. In the case that multiple grant proposals are submitted that are in competition with one another, a single winner will be selected by holding a separate coinholder vote for each proposal, with the approved proposal having the highest total ZEC value committed in support being the winner. It is the responsibility of the Key-Holder Organizations to determine whether proposals are in competition with one another when organizing coinholder votes. + +Each coinholder vote (including in cases where multiple grants are in competition) is independent, and coins used in one vote are also allowed to be used in another; this approach is necessary to avoid vote-splitting scenarios that can result in an option being selected that achieves only a plurality (not a majority) of coinholder support. + +Coinholders SHOULD take account of the same factors considered by the ZCG Committee (described in points 2, 3, and 4 of [^zip-1015-zcg]) in deciding whether to fund a grant. If any contentious issue arises in connection with a grant (such as milestones not being met), or periodically for grants of indefinite duration, the Key-Holder Organizations SHOULD hold additional coinholder votes to determine whether funding should continue. + +Coinholders are not obligated to fund any grants and MAY leave the funds at rest. + +No organizations or individuals are restricted from voting their coins. + +### Veto process + +A grant is vetoed if: + +* any Key-Holder Organization declares that funding the grant would violate any of its legal or reporting obligations; or +* two or more Key-Holder Organizations declare that they have a principled objection to it on the basis of potential harm to Zcash users, or because it is antithetical to the values of the Zcash community. + +If a grant is vetoed after passing a coinholder vote, then payments for it MUST be stopped. This is expected to be an unusual situation that would only occur if new adverse information came to light, or in the case of a change in the law or unanticipated legal proceedings. + +The Key-holder Organizations cannot veto coinholder rejection of a proposal. + +Vetos are intended for exceptional cases and SHOULD be accompanied by a thorough rationale. + +## Administrative obligations and constraints + +All provisions of ZIP 1015 imposing obligations and constraints on Bootstrap Project, Electric Coin Company, Zcash Foundation, Financial Privacy Foundation, the ZCG Committee, and grant recipients relating to the previous ``FS_FPF_ZCG`` funding stream, SHALL continue in effect for Zcash Community Grants. + +These obligations and constraints will be extended to all Key-Holder Organizations in respect of the Coinholder-Controlled Fund. + +The provisions after the first paragraph of the section "Zcash Community Grants (ZCG)" also apply to the Key-Holder Organizations' administration of the Coinholder-Controlled Fund, with coinholder voting replacing the role of the ZCG Committee. + +Note: Nothing forces developers of Zcash consensus node software to implement any particular proposal. The aim of a process specification like this one is only to indicate social consensus. It fundamentally cannot affect the autonomy of developers of Zcash consensus node software to publish (or not) the software they want to publish, or the autonomy of node operators to run (or not) the software they want to run. + +## Security precautions + +The Key-Holder Organizations and the ZCG Committee MUST take appropriate precautions to safeguard funds from theft or accidental loss. Any theft or loss of funds, or any loss or compromise of key material MUST be reported to the Zcash community as promptly as possible after applying necessary mitigations. + +## Testnet-specific considerations + +In order to allow the mechanism and process for coinholder voting to be tested, this process SHOULD be rehearsed on Testnet. The threshold of 420,000 ZEC applied to Mainnet coinholder votes does not apply to these rehearsals. + +# Open questions + +* Is 420,000 ZEC the right threshold for coinholder votes? + +# 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"](https://www.rfc-editor.org/info/bcp14) + +[^protocol]: [Zcash Protocol Specification, Version 2025.6.0 [NU6.1 proposal] or later](protocol/protocol.pdf) + +[^protocol-networks]: [Zcash Protocol Specification, Version 2025.6.0 [NU6.1 proposal]. Section 3.12: Mainnet and Testnet](protocol/protocol.pdf#networks) + +[^zip-0207]: [ZIP 207: Funding Streams](zip-0207.rst) + +[^zip-0214]: [ZIP 214: Consensus rules for a Zcash Development Fund](zip-0214.rst) + +[^zip-1014]: [ZIP 1014: Establishing a Dev Fund for ECC, ZF, and Major Grants](zip-1014.rst) + +[^zip-1015]: [ZIP 1015: Block Subsidy Allocation for Non-Direct Development Funding](zip-1015.rst) + +[^zip-1015-lockbox]: [ZIP 1015: Block Subsidy Allocation for Non-Direct Development Funding — Lockbox](zip-1015.rst#lockbox) + +[^zip-1015-zcg]: [ZIP 1015: Block Subsidy Allocation for Non-Direct Development Funding — Zcash Community Grants](zip-1015.rst#zcash-community-grants-zcg) + +[^zip-1015-funding-streams]: [ZIP 1015: Block Subsidy Allocation for Non-Direct Development Funding — Funding Streams](zip-1015.rst#funding-streams) + +[^zip-271]: [ZIP 271: Deferred Dev Fund Lockbox Disbursement](zip-0271.md) + +[^zip-2001]: [ZIP 2001: Lockbox Funding Streams](zip-2001.rst) diff --git a/zips/zip-2001.rst b/zips/zip-2001.rst index 0b0063bb4..8554c26e7 100644 --- a/zips/zip-2001.rst +++ b/zips/zip-2001.rst @@ -3,9 +3,9 @@ ZIP: 2001 Title: Lockbox Funding Streams Owners: Kris Nuttycombe - Credits: Daira-Emma Hopwood - Jack Grigg - Status: Proposed + Credits: Daira-Emma Hopwood + Jack Grigg + Status: Final Category: Consensus Created: 2024-07-02 License: MIT @@ -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,62 +147,60 @@ 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:: + .. math:: - \begin{array}{ll} - \mathsf{IssuedSupply}(\mathsf{height}) := &\!\!\!\!\mathsf{ChainValuePoolBalance^{Transparent}}(\mathsf{height}) \\ - &+\,\; \mathsf{ChainValuePoolBalance^{Sprout}}(\mathsf{height}) \\ - &+\,\; \mathsf{ChainValuePoolBalance^{Sapling}}(\mathsf{height}) \\ - &+\,\; \mathsf{ChainValuePoolBalance^{Orchard}}(\mathsf{height}) \\ - &+\,\; \mathsf{ChainValuePoolBalance^{Deferred}}(\mathsf{height}) - \end{array} + \begin{array}{ll} + \mathsf{IssuedSupply}(\mathsf{height}) := &\!\!\!\!\mathsf{ChainValuePoolBalance^{Transparent}}(\mathsf{height}) \\ + &+\,\; \mathsf{ChainValuePoolBalance^{Sprout}}(\mathsf{height}) \\ + &+\,\; \mathsf{ChainValuePoolBalance^{Sapling}}(\mathsf{height}) \\ + &+\,\; \mathsf{ChainValuePoolBalance^{Orchard}}(\mathsf{height}) \\ + &+\,\; \mathsf{ChainValuePoolBalance^{Deferred}}(\mathsf{height}) + \end{array} 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 @@ -227,23 +225,21 @@ wording change here. 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-overview] `Zcash Protocol Specification, Version 2024.5.1 [NU6]. Section 1.2: High-level Overview ` -.. [#protocol-transactions] `Zcash Protocol Specification, Version 2024.5.1 [NU6]. Section 3.4: Transactions and Treestates ` -.. [#protocol-coinbasetransactions] `Zcash Protocol Specification, Version 2024.5.1 [NU6]. Section 3.11: Coinbase Transactions and Issuance ` -.. [#protocol-chainvaluepoolbalances] `Zcash Protocol Specification, Version 2024.5.1 [NU6]. Section 4.17: Chain Value Pool Balances ` -.. [#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-txnconsensus] `Zcash Protocol Specification, Version 2024.5.1 [NU6]. Section 7.1.2: Transaction Consensus Rules ` -.. [#protocol-subsidies] `Zcash Protocol Specification, Version 2024.5.1 [NU6]. Section 7.8: Calculation of Block Subsidy, Funding Streams, and Founders’ Reward ` -.. [#protocol-fundingstreams] `Zcash Protocol Specification, Version 2024.5.1 [NU6]. Section 7.10: Payment of Funding Streams ` -.. [#zip-0207] `ZIP 207: Funding Streams ` -.. [#zip-0207-funding-streams] `ZIP 207: Funding Streams. Section: Funding streams ` -.. [#zip-0207-consensus-rules] `ZIP 207: Funding Streams. Section: Consensus rules ` -.. [#zip-0207-deployment] `ZIP 207: Funding Streams. Section: Deployment ` -.. [#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-overview] `Zcash Protocol Specification, Version 2024.5.1 [NU6]. Section 1.2: High-level Overview `_ +.. [#protocol-transactions] `Zcash Protocol Specification, Version 2024.5.1 [NU6]. Section 3.4: Transactions and Treestates `_ +.. [#protocol-coinbasetransactions] `Zcash Protocol Specification, Version 2024.5.1 [NU6]. Section 3.11: Coinbase Transactions and Issuance `_ +.. [#protocol-chainvaluepoolbalances] `Zcash Protocol Specification, Version 2024.5.1 [NU6]. Section 4.17: Chain Value Pool Balances `_ +.. [#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-txnconsensus] `Zcash Protocol Specification, Version 2024.5.1 [NU6]. Section 7.1.2: Transaction Consensus Rules `_ +.. [#protocol-subsidies] `Zcash Protocol Specification, Version 2024.5.1 [NU6]. Section 7.8: Calculation of Block Subsidy, Funding Streams, and Founders’ Reward `_ +.. [#protocol-fundingstreams] `Zcash Protocol Specification, Version 2024.5.1 [NU6]. Section 7.10: Payment of Funding Streams `_ +.. [#zip-0207] `ZIP 207: Funding Streams `_ +.. [#zip-0207-funding-streams] `ZIP 207: Funding Streams. Section: Funding streams `_ +.. [#zip-0207-consensus-rules] `ZIP 207: Funding Streams. Section: Consensus rules `_ +.. [#zip-0207-deployment] `ZIP 207: Funding Streams. Section: Deployment `_ +.. [#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 `_ diff --git a/zips/zip-2002.rst b/zips/zip-2002.rst new file mode 100644 index 000000000..0abbda89e --- /dev/null +++ b/zips/zip-2002.rst @@ -0,0 +1,154 @@ +:: + + ZIP: 2002 + Title: Explicit Fees + Owners: Daira-Emma Hopwood + Kris Nuttycombe + Jack Grigg + Credits: Simon Liu + Status: Draft + Category: Consensus + License: MIT + Discussions-To: + Pull-Request: + + +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 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 +======== + +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. + + +Motivation +========== + +When it comes to fee selection, it should be very hard to make mistakes. +The current transparent fee computation (inherited from Bitcoin) — input value +less output value — is prone to user error. It is very easy to forget to add an +output for a change address, make a calculation error [#bitcointalk-fee-error]_, +mix up units etc. + +In addition, when signing a transaction with a hardware wallet, using an implicit +fee means that the hardware wallet must recompute the fee on its own and cannot +simply display the value being committed to. + +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 +============ + +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 +============= + +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 | ``fee`` | ``uint64`` | The fee to be paid by this transaction, in zatoshis. | ++-------+---------+------------+------------------------------------------------------+ + +Note: If both this ZIP and ZIP 233 are selected for inclusion in the same +Network Upgrade, then the ordering of fields in the transaction format will +be ``fee`` and then ``zip233Amount``. + +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: + + * [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. + + Non-normative note: The effect of these rules is that the ``fee`` field of + v6 and later coinbase transactions will always be zero. + +In § 7.1 ‘Transaction Encoding and Consensus’ [#protocol-txnconsensus]_, add: + + [NU7 onward] ``fee`` 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 ``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. + + +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. [#zip-0230]_ + + +Reference implementation +======================== + +TBD + + +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 2025.6.2 [NU6.1] or later `_ +.. [#protocol-transactions] `Zcash Protocol Specification, Version 2025.6.2 [NU6.1]. Section 3.4: Transactions and Treestates `_ +.. [#protocol-networks] `Zcash Protocol Specification, Version 2025.6.2 [NU6.1]. Section 3.12: Mainnet and Testnet `_ +.. [#protocol-txnconsensus] `Zcash Protocol Specification, Version 2025.6.2 [NU6.1]. 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] `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 `_ +.. [#zip-0246] `ZIP 246: Digests for the Version 6 Transaction Format `_ diff --git a/zips/zip-2003.rst b/zips/zip-2003.rst new file mode 100644 index 000000000..1648d51ff --- /dev/null +++ b/zips/zip-2003.rst @@ -0,0 +1,145 @@ +:: + + ZIP: 2003 + Title: Disallow version 4 transactions + Owners: Daira-Emma Hopwood + Status: Draft + Category: Consensus + License: MIT + Discussions-To: + Pull-Request: + + +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 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 +======== + +This proposal disallows v4 transactions. The v5 transaction format introduced +in the NU5 network upgrade [#zip-0225]_ does not support Sprout, and so this +will have the effect of disabling the ability to spend Sprout funds. + +It is not proposed in this ZIP to unissue, burn, or otherwise make Sprout funds +permanently unavailable. This leaves open the possibility of re-enabling v4 +transactions, or of adding another facility to retrieve these funds if the Zcash +community considers it worthwhile. However, since it is possible the ability to +spend Sprout funds will never be re-enabled, holders of these funds should move +them out of the Sprout pool without delay. + + +Motivation +========== + +Zcash is an extremely complex protocol. Some of that complexity comes from +functionality that is now obsolete. + +The Sprout shielded protocol was the first large-scale deployment of +general-purpose zero-knowledge proofs, but suffered from long proving times +and high memory requirements that limited its practicality. Its successors, +the Sapling and Orchard shielded protocols, made substantial optimizations +[#cultivating-sapling]_ and added new functionality such as viewing keys and +diversified addresses. As a result, Sprout is essentially unused at this point. + +In the Sapling network upgrade, the proving system and the pairing-friendly +curves used for Sprout were changed to be the same as for the Sapling shielded +protocol, i.e. Groth16 and BLS12-381. So that part of the attack surface is +shared between Sprout and Sapling. The magnitude of potential balance violation +due to any weakness in Sprout’s cryptography is also limited by the “turnstile” +mechanism defined in ZIP 209 [#zip-0209]_. + +Nevertheless, the parts of Sprout that are not shared with Sapling, such as the +JoinSplit circuit and the handling of Sprout nullifiers and note commitments, +still impose a substantial burden on the complexity and attack surface of the +Zcash protocol and of full node implementations. For instance, verification of +transactions involving Sprout JoinSplit descriptions also has to be taken into +account for potential denial-of-service attacks. Because of Sprout’s lack of use, +there is little incentive for node implementations to optimize its verification, +which may lead to such attacks imposing greater cost than they otherwise would. + +The deprecation of zcashd, planned to be in advance of NU7, will also remove +the only maintained software that still provides wallet functionality for Sprout, +which would in any case make it impractical to move funds out of the Sprout pool. +It is therefore necessary in any case to give holders of Sprout funds sufficient +warning that they may be unable to retrieve them after zcashd deprecation. + + +Requirements +============ + +It must become possible to remove the complexity and attack surface of Sprout +from Zcash specifications and node implementations. + + +Specification +============= + +In § 7.1.2 ‘Transaction Consensus Rules’ [#protocol-txnconsensus]_, change the +applicability of the following rule: + + * [N​U​5 onward] The transaction version number MUST be 4 or 5. If the transaction + version number is 4 then the version group ID MUST be ``0x892F2085``. If the + transaction version number is 5 then the version group ID MUST be ``0x26A7270A``. + +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 +([#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 +========== + +This ZIP is proposed to be deployed with NU7. + + +Reference implementation +======================== + +TBD + + +Acknowledgements +================ + +The author would like to thank Jack Grigg and Kris Nuttycombe for discussions leading +to the submission of this ZIP, and everyone else whose work made it feasible to +deprecate Sprout. Particular credit goes to the four people who were put under a +unique kind of stress during Sapling’s development: Ariel Gabizon, Sean Bowe, +Nathan Wilcox, and Zooko Wilcox. + + +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 2025.6.2 [NU6.1] or later `_ +.. [#protocol-networks] `Zcash Protocol Specification, Version 2025.6.2 [NU6.1]. Section 3.12: Mainnet and Testnet `_ +.. [#protocol-txnconsensus] `Zcash Protocol Specification, Version 2025.6.2 [NU6.1]. Section 7.1.2: Transaction Consensus Rules `_ +.. [#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 `_ +.. [#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 new file mode 100644 index 000000000..3e1e71925 --- /dev/null +++ b/zips/zip-2004.rst @@ -0,0 +1,153 @@ +:: + + ZIP: 2004 + Title: Remove the dependency of consensus on note encryption + Owners: Daira-Emma Hopwood + Status: Draft + Category: Consensus + Created: 2024-10-22 + License: MIT + Discussions-To: + Pull-Request: + + +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 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 +======== + +ZIP 213 [#zip-0213]_ 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. + +This proposal disentangles note encryption from consensus, by instead requiring +coinbase outputs for v6 and later transaction versions to be unencrypted. The +disentanglement will be complete once earlier transaction versions are no longer +allowed on the network, which is likely to happen in some later upgrade. + + +Motivation +========== + +In the original design of Zcash, the consensus protocol was carefully isolated +from the details of note encryption. This property, which was preserved through +the Overwinter, Sapling, and Blossom upgrades, reduces the complexity and attack +surface of the consensus protocol. It also potentially allows changes to note +encryption to be made outside network upgrades. + +A dependency on note encryption crept into the consensus protocol as a result +of the changes to support shielded coinbase outputs in ZIP 213 [#zip-0213]_, +deployed in the Heartwood network upgrade. These changes added the requirement +that it must be possible to decrypt Sapling and Orchard outputs in coinbase +transactions using a sequence of 32 zero bytes as the outgoing viewing key. + +The complexity impact of this change was overlooked. This became apparent during +the design of ZIP 212 [#zip-0212]_ for the Heartwood network upgrade. In fact +for a time there were separate and slightly diverging implementations of note +decryption for the consensus checks in `zcashd`, and in `librustzcash`. This +could have led to a chain fork between `zcashd` and `zebrad` before the +implementations were reconciled. + +This ZIP restores the originally intended design property. + + +Requirements +============ + +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 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}$. + + Define $\mathsf{NullSym.Decrypt_K}(\mathsf{C})$ as follows: + + * 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; $\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 $\mathsf{Sym}$ be the encryption scheme instantiated in + § 5.4.3 'Symmetric Encryption'. + +to + + let $\mathsf{NoteSym}$ and $\mathsf{NullSym}$ be as + instantiated in § 5.4.3 'Symmetric Encryption'. + + [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 $\mathsf{Sym}$ be + $\mathsf{NullSym}$, otherwise let it be $\mathsf{NoteSym}$. + +These changes apply identically to Mainnet and Testnet. + +TODO: specify the handling of the ``ephemeralKey`` field. + + +Deployment +========== + +This ZIP is proposed to be deployed with the next transaction version change, +which is assumed to be v6. [#zip-0230]_ + + +Reference implementation +======================== + +TBD. + + +Acknowledgements +================ + +The author would like to thank Jack Grigg and Kris Nuttycombe for discussions leading +to the submission of this ZIP. + + +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 2025.6.2 or later [NU6.1] `_ +.. [#protocol-networks] `Zcash Protocol Specification, Version 2025.6.2 [NU6.1]. Section 3.12: Mainnet and Testnet `_ +.. [#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-2005.md b/zips/zip-2005.md new file mode 100644 index 000000000..ce0250e76 --- /dev/null +++ b/zips/zip-2005.md @@ -0,0 +1,2144 @@ + + ZIP: 2005 + Title: Orchard Quantum Recoverability + Owners: Daira-Emma Hopwood + Jack Grigg + Credits: Sean Bowe + Dev Ojha + Kris Nuttycombe + Status: Proposed + Category: Consensus + Created: 2025-03-31 + License: MIT + Discussions-To: + Pull-Request: + + + + +# Terminology + +The key words "MUST", "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] + +We use the convention followed in the protocol specification that an +$\underline{\mathsf{underlined}}$ variable indicates a byte sequence, +and a variable suffixed with $\star$ indicates a bit-sequence encoding of +an elliptic curve point. + +The notation ${k \choose n}$ denotes the binomial coefficient — the +number of ways of choosing $n$ items from a set of $k$, equal to +$\frac{k!}{n!(k-n)!}$ for $0 \leq n \leq k$. + +For brevity, in the discussion sections of this ZIP we abbreviate +$\mathsf{H^{rcm,Orchard}}$ as $\mathsf{H^{rcm}}$, +$\mathsf{PRF^{nfOrchard}}$ as $\mathsf{PRF^{nf}}$, +$\mathcal{K}^{\mathsf{Orchard}}$ as $\mathcal{K}$, +and similarly for other Orchard-specific hash function names. The changes +to the protocol specification and to other ZIPs use the full forms. + +The term "Zcash Shielded Assets" or "ZSAs" refers to the extension to +the Orchard shielded protocol described in ZIPs 226 and 227 [^zip-0226] [^zip-0227]. + +The term "Orchard[ZSA]" in this document refers to the Orchard shielded +protocol before the deployment of ZSAs, and to the OrchardZSA shielded +protocol after the deployment of ZSAs. + +The terms "recoverable note" and "recoverable note plaintext" refer to a +note or note plaintext that was created according to this proposal. As +initially deployed, these are necessarily Orchard notes or note plaintexts. + +The term "Recovery Protocol" refers to a potential new shielded protocol +that would allow recovery of funds held in recoverable Orchard[ZSA] notes. +This ZIP describes the Recovery Protocol in outline but not in detail: +many of its design decisions are intentionally left open. + + +# Abstract + +This ZIP proposes a change to the construction of Orchard[ZSA] notes, +designed to improve Zcash's long-term resilience against a significant +potential threat to its security from quantum computers. It does not +by itself make the protocol secure against quantum adversaries, but is +intended to support a smoother transition to future versions of Zcash +designed to be so. + +Specifically, if it were necessary to disable the current Orchard[ZSA] +shielded protocol in order to prevent a discrete-log-breaking adversary +from stealing or forging funds, this change would make it possible to use +a Recovery Protocol to recover existing Orchard funds. This Recovery Protocol +is expected to remain secure against discrete-log-breaking and quantum +adversaries. + +If the Orchard[ZSA] protocol needed to be disabled for this reason, the +Sapling protocol would need to be disabled as well, which would make all +Sapling funds inaccessible. Sapling funds should be migrated to Orchard in +order to take advantage of this change. + + +# Motivation + +If quantum computers —or any other attack that allows finding discrete +logarithms on the elliptic curves used in Zcash— were to become practical, +it would raise difficult issues for the Zcash community. An adversary able +to compute discrete logarithms could cause arbitrary inflation or steal +users' funds. + +Critically, the note commitment algorithms used by the Sapling and Orchard +shielded protocols are not post-quantum binding. This means that even if +the proof system were upgraded to one that is believed to be secure against +quantum computers, and even if the note commitment tree were to be +reconstructed (from public information) to use a suitable hash function, +it would still be possible for a quantum or discrete-log-breaking adversary +to forge and spend notes that are not actually in the commitment tree — +thus breaking the Balance property. + +This ZIP proposes a small change to the way Orchard[ZSA] notes are derived. +If this change is made in advance of quantum computers becoming viable, +then users' Orchard[ZSA] funds could remain safe and recoverable after a +post-quantum transition. This would not require any change to the Orchard +or proposed OrchardZSA *circuits* for the time being, and would not require +deciding on the particular proof system or note commitment tree hash used +in the future protocol. + +Recovering Orchard[ZSA] funds after the post-quantum transition would +involve checking a more expensive and complicated statement in zero +knowledge, but it is expected that this will be entirely practical for the +intended usage of recovering funds into another shielded pool. The current +privacy properties of Orchard would be retained against pre-quantum +adversaries, and also against post-quantum adversaries without knowledge +of the notes' addresses. [^pq-zcash] + +To reduce overall protocol complexity and analysis effort, we do *not* +propose a similar change for Sapling. Instead, Sapling funds can be +migrated to Orchard in order to make them quantum-recoverable. (Note +that this analysis effort needs to include the child and internal key +derivations defined in ZIP 32, which differ significantly between +Sapling [^zip-0032-sapling-child-key-derivation] [^zip-0032-sapling-internal-key-derivation] +and Orchard [^zip-0032-orchard-child-key-derivation] [^zip-0032-orchard-internal-key-derivation].) + +This proposal is implementable at low risk, and required changes to existing +libraries and wallets are small. It is compatible with Memo Bundles [^zip-0231] +and/or ZSAs [^zip-0226]. + + +# Requirements + +* Orchard[ZSA] notes constructed according to this proposal should be + spendable via a Recovery Protocol (to be introduced, potentially, + in a future upgrade) that is expected to be secure against + discrete-log-breaking and quantum adversaries. +* No particular choice of post-quantum proving system or commitment + tree hash should be assumed for that alternate protocol. +* The proposed scheme should be fully compatible with FROST threshold + multisignatures [^zip-0312], hardware wallets, and the combination of + both. +* The proposed scheme should not require regeneration of existing + non-multisignature keys or addresses. +* The changes made to the pre-quantum protocol should not cause a + significant regression in performance, applicability, or security + against any given adversary class, or require significant re-analysis + of that protocol's pre-quantum security. +* The Recovery Protocol should ensure no loss of security against + pre-quantum adversaries — including when FROST threshold multisignatures + and/or hardware wallets are used. +* Recovery of funds from hardware wallets that support this protocol + should not require exposing the pre-quantum spend authorizing key + $\mathsf{ask}$ to theft. +* The proposal should be compatible with Zcash Shielded Assets with + minimal additional complexity [^zip-0226] [^zip-0227]. + + +# Non-requirements + +* It is not required to address discrete-log-breaking or quantum + attacks on *privacy* with this proposal, as long as it does not + cause any regression in privacy properties. +* It is not required to add support for the Recovery Protocol to + consensus rules now. +* It is not required for spends using the Recovery Protocol to be + as efficient as spends using the Orchard, OrchardZSA, or Sapling + protocols. +* It is not anticipated that spends using the Recovery Protocol will + need to be indistinguishable from non-Recovery spends. + + +# High-level summary of changes + +This subsection and the flow diagram below are non-normative. + +This proposal defines a new note plaintext format for Orchard notes, +with lead byte $\mathtt{0x03}.$ The $\mathsf{pre\_rcm}$ value is computed +differently for this new format, by including all of the note fields in +$\mathsf{pre\_rcm}$. This means that an adversary constrained to treat +the PRF used to derive $\mathsf{rcm}$ from $\mathsf{pre\_rcm}$ as a +random oracle, could not vary any note field without producing a +different $\mathsf{rcm}$. This lets us argue that the overall +commitment scheme is post-quantum binding, as long as the new +derivation of $\mathsf{rcm}$ is checked in the Recovery Protocol. + +Essentially the same technique also needs to be applied to the +function $\mathsf{Commit^{ivk}}$ that is used to derive Orchard +incoming viewing keys. The randomness $\mathsf{rivk}$ in +$\mathsf{Commit^{ivk}}$ is derived directly or indirectly from +$\mathsf{rivk\_ext}$, which is in turn derived from one of two random +oracles, depending on which key material the user holds: + +* For existing Orchard keys, $\mathsf{rivk\_ext}$ is derived from + the secret key $\mathsf{sk}$ via $\mathsf{H^{rivk\_legacy}}(\mathsf{sk})$, + with $\mathsf{ak}$ and $\mathsf{nk}$ also derived from $\mathsf{sk}$. + The Recovery Protocol checks all three derivations. +* For keys generated via FROST distributed key generation, or for + hardware wallets where exporting $\mathsf{sk}$ is undesirable, an + alternative "quantum spending key" $\mathsf{qsk}$ and "quantum + intermediate key" $\mathsf{qk}$ are used, with + $\mathsf{rivk\_ext} = \mathsf{H^{rivk\_ext}_{qk}}(\mathsf{ak}, \mathsf{nk})$. + The Recovery Protocol checks this derivation together with a + $\mathsf{SoK^{qsk}}$ proof of knowledge of $\mathsf{qsk}$ such that + $\mathsf{H^{qk}}(\mathsf{qsk}) = \mathsf{qk}$. + +Both branches (and both cases +$\mathsf{rivk} \in \big\{ \mathsf{rivk\_ext},\, \mathsf{H^{rivk\_int}_{rivk\_ext}}(\mathsf{ak}, \mathsf{nk}) \big\}$) +are covered uniformly by the +[Security argument for key binding](#securityargumentforkeybinding): +each binds the keys $(\mathsf{ak}, \mathsf{nk}, \mathsf{rivk})$ — and, +when in use, $\mathsf{qk}$ — to the incoming-viewing key $\mathsf{ivk}$ +post-quantumly, up to a small advantage against collision-finding in +the random oracles used for $\mathsf{rivk}$ derivation. The FROST and +hardware-wallet use cases are described in +[Usage with FROST](#usagewithfrost) and +[Usage with hardware wallets](#usagewithhardwarewallets). + +## Flow diagram for the Orchard protocol + +This diagram shows, approximately, the derivation of Orchard keys, +addresses, notes, note commitments, and nullifiers. All of the flow +diagrams in this ZIP omit type conversions between curve points, field +elements, byte sequences, and bit sequences, and so are not sufficiently +precise to be used directly as a guide for implementation. + +```mermaid +--- +title: "Key to flow diagrams" +--- +graph BT + classDef default stroke:#111111; + classDef func fill:#d0ffb8; + classDef cefunc fill:#a0e0a0; + classDef sensitive fill:#ffb0b0; + classDef semi_sensitive fill:#ffb0ff; + classDef keybox stroke:#808080, fill:#ffffff; + classDef spacer opacity:0; + + key([sensitive key]):::sensitive ~~~ function:::func + value([value]) ~~~ cond{{conditional value}} + dummyA( ) -->|existing| dummyB( ) + dummyC( ) ==>|new| dummyD( ) + dummyE( ) -.->|optional| dummyF( ) +``` + +The bold lines are changes introduced by this ZIP, which all take the form +of additional inputs to derivation functions or alternative derivations. +The derivations shown in the box labelled [Proposed Recovery Statement](#proposedrecoverystatement) +are, roughly speaking, those enforced by the section of that name. The +diagram shows the recoverable-note case ($\mathsf{leadByte} = \mathtt{0x03}$); +for $\mathsf{leadByte} = \mathtt{0x02}$ the existing Orchard derivation +$\mathsf{rcm} = \mathsf{ToScalar^{Orchard}}\big(\mathsf{PRF^{expand}_{rseed}}([\mathtt{0x05}] \,||\, \underline{\text{ρ}})\kern-0.1em\big)$ +applies, and the additional fields feeding into $\mathsf{pre\_rcm}$ +are absent. + +```mermaid +graph BT + classDef default stroke:#111111; + classDef func fill:#d0ffb8; + classDef cefunc fill:#a0e0a0; + classDef sensitive fill:#ffb0b0; + classDef semi_sensitive fill:#ffb0ff; + classDef circuit stroke:#000000, fill:#fffff0; + classDef spacer opacity:0; + + PostQC:::circuit + subgraph PostQC[
    Proposed Recovery Statement
    ] + direction BT + rivk_ext([rivk_ext]) --> Hrivk_int[Hrivk_int]:::func + ak([ak]) --> Hrivk_int[Hrivk_int]:::func + nk --> Hrivk_int + rivk_ext -->|¬is_internal_rivk| rivk + Hrivk_int -->|is_internal_rivk| rivk{{rivk}} + rivk --> Commitivk[Commitivk]:::func + ak([ak]) ----> Commitivk + nk([nk]) ----> Commitivk + Commitivk ---> ivk([ivk]) + gd ---> ivkmul[[ivk]gd ]:::func + ivk --> ivkmul + rseed --> Hpsi[Hψ]:::func + rho --> Hpsi + v([#8239;v#8239;]) ==> pre_rcm([pre_rcm]) + pkd ====> pre_rcm + gd ==> pre_rcm + psi ===> pre_rcm + rho([#8239;ρ#8239;]) --> pre_rcm + v ~~~~ rcm + ivkmul --> pkd([pkd]) + pre_rcm --> Hrcm[Hrcm]:::func + rseed([rseed]) --> Hrcm + Hrcm --> rcm([rcm]) + Hpsi --> psi([#8239;ψ#8239;]) + gd --> NoteCommit:::func + pkd --> NoteCommit + psi --> NoteCommit + v --> NoteCommit + rcm --> NoteCommit + rho --> NoteCommit + cm --> DeriveNullifier:::func + psi --> DeriveNullifier + rho --> DeriveNullifier + nk --> DeriveNullifier + NoteCommit --> cm([cm]) + DeriveNullifier --> nf([nf]) + cm --> cmx([cmx]) + end + + d([#8239;d#8239;]) --> HashToCurve:::func ------> gd([gd]) +``` + +# Specification + +## Proactive movement of funds to recoverable notes + +Once this proposal is deployed, wallets SHOULD move all of the funds they +control (including transparent, Sprout, and Sapling funds) into recoverable +Orchard notes as soon as practically possible. This does not depend on support +from other wallets for receiving recoverable notes, because wallet-internal +addresses can be used. + +Non-recoverable funds may be received after existing funds have been made +recoverable. Wallets SHOULD therefore treat the movement of funds to +recoverable notes as an ongoing process. + +## Usage with FROST + +When generating Orchard keys for FROST, $\mathsf{ak}$ will be derived jointly +from the participants' shares of $\mathsf{ask}$ according to the FROST +Distributed Key Generation (DKG) protocol. + +This ZIP further constrains FROST key generation for Orchard as follows: +participants MUST privately agree on a value $\mathsf{sk}$, and then use it +with $\mathsf{use\_qsk} = \mathsf{true}$ to derive $\mathsf{nk}$, $\mathsf{qsk}$, +$\mathsf{qk}$, and (using the $\mathsf{ak}$ output by the DKG protocol) +$\mathsf{rivk\_ext}$, as specified in § 4.2.3 ‘Orchard Key Components’ [^protocol-orchardkeycomponents]. + +```mermaid +graph BT + classDef default stroke:#111111; + classDef func fill:#d0ffb8; + classDef cefunc fill:#a0e0a0; + classDef sensitive fill:#ffb0b0; + classDef semi_sensitive fill:#ffb0ff; + classDef circuit stroke:#000000, fill:#fffff0; + classDef spacer opacity:0; + + sk([sk]):::sensitive --> Hnk[Hnk]:::func ----> nk([nk]) + sk --> Hqsk[Hqsk]:::func --> qsk([qsk]):::sensitive + qk ==> Hrivk_ext + nk ==> Hrivk_ext + FROST_DKG --> ak([ak]) --> FROST_Sign + FROST_DKG ~~~ s( ):::spacer ~~~ FROST_Sign + FROST_DKG --> ask([aski]):::sensitive --> FROST_Sign + ak ==> Hrivk_ext[Hrivk_ext]:::func + Hrivk_ext ==>|use_qsk| rivk_ext([rivk_ext]) + + HWW1:::circuit + subgraph HWW1[









    SoKqsk
    ] + qsk([qsk]):::sensitive ==> Hqk[Hqk]:::cefunc + Hqk ==> qk([qk]):::semi_sensitive + end +``` + +The protocol MUST ensure that all participants obtain the same values for +$\mathsf{ak}$, $\mathsf{nk}$, and $\mathsf{rivk\_ext}$. (Provided that the +participants have followed § 4.2.3, this implies that they have the same +$\mathsf{qsk}$ and $\mathsf{qk}$, by collision resistance of $\mathsf{H^{qk}}$ +and $\mathsf{H^{rivk\_ext}}$.) + +Each participant MUST treat $\mathsf{qsk}$ as a secret held at least as +securely and reliably as $\mathsf{ask}$. Note that $\mathsf{qsk}$ will +not be needed to sign unless and until the Recovery Protocol is needed, +but it is essential that it be retained, otherwise funds could be lost if +and when the current Orchard protocol is disabled. + +The Recovery Protocol will still require a RedDSA signature verifiable by +the Spend validating key $\mathsf{ak}$, in addition to knowledge of +$\mathsf{qsk}$. RedDSA is not secure in the long term against a quantum +or discrete-log-breaking adversary. However, during any period in which +the adversary cannot find discrete logarithms on the Pallas curve, +checking this RedDSA signature will ensure that spend authorization +continues to require a $t$-of-$n$ threshold of participants. +An important advantage of FROST —that the parties can sign using their +shares *without* reconstructing $\mathsf{ask}$, the Spend authorizing +key— is retained. + +Note that a quantum adversary may be able to steal the funds with only +access to $\mathsf{qsk}$, which is held by every participant (see below +for more detail on [Key storage options](#keystorageoptionsandanalysis)). +Therefore, it is RECOMMENDED that as soon as a fully post-quantum protocol +that supports threshold multisignatures is available, all funds held under +FROST keys be transferred into that protocol's shielded pool. + +## Usage with hardware wallets + +The same $\mathsf{use\_qsk}$ option can help to improve the efficiency of +using the [Recovery Protocol](#proposedrecoveryprotocol) with hardware +wallets. If the keys $\mathsf{rivk\_ext},$ $\mathsf{nk},$ and $\mathsf{ak}$ +are generated from $\mathsf{sk},$ then the circuit for the Recovery Protocol +will need to prove their correct derivation using $\mathsf{H^{rivk\_legacy}},$ +$\mathsf{H^{nk}},$ $\mathsf{H^{ask}},$ and $\mathsf{DerivePublic}$ as shown +in the $\mathsf{SoK^{sk}}$ box of the diagram below. + +```mermaid +graph BT + classDef default stroke:#111111; + classDef func fill:#d0ffb8; + classDef cefunc fill:#a0e0a0; + classDef sensitive fill:#ffb0b0; + classDef semi_sensitive fill:#ffb0ff; + classDef circuit stroke:#000000, fill:#fffff0; + classDef spacer opacity:0; + + HWW1:::circuit + subgraph HWW1[

















    SoKsk
    ] + sk --> Hrivk_legacy[Hrivk_legacy]:::func ----> rivk_legacy + DerivePublic --> ak([ak]) + sk([sk]):::sensitive --> Hnk[Hnk]:::func ----> nk([nk]) + sk --> Hask[Hask]:::func --> ask([ask]):::sensitive + ask --> DerivePublic:::func + end + + HWW2:::circuit + subgraph HWW2[









    SoKqsk
    ] + qsk([qsk]):::sensitive ==> Hqk[Hqk]:::cefunc + Hqk ==> qk([qk]):::semi_sensitive + end + + sk -.-> Hqsk[Hqsk]:::func -.-> qsk + qk ==> Hrivk_ext[Hrivk_ext]:::func + nk([nk]) ==> Hrivk_ext + ak ==> Hrivk_ext + Hrivk_ext ==>|use_qsk| rivk_ext{{rivk_ext}} + rivk_legacy([rivk_legacy]) -->|¬use_qsk| rivk_ext +``` + + +When $\mathsf{use\_qsk}$ is used, on the other hand, it is possible for +the Recovery Protocol to support spend authorization using a simpler +statement that only uses $\mathsf{H^{qk}}$ and a commitment scheme. +For example, for some hiding and collapse-binding commitment +$$\mathsf{c_{link}} = \mathsf{LinkCommit}_r(\mathsf{qk}, \mathsf{sighash})$$ +the hardware wallet could prove knowledge of $(\mathsf{qsk}, r)$ such that +$$\mathsf{c_{link}} = \mathsf{LinkCommit}_r(\mathsf{H^{qk}}(\mathsf{qsk}), \mathsf{sighash}).$$ +This statement, labelled as $\mathsf{SoK^{qsk}}$ in the diagram, can be +implemented in a much smaller circuit, so it might be feasible to do the +proof in quite constrained hardware. + +The commitment $\mathsf{c_{link}}$ would be a public input opened to +$(\mathsf{qk}, \mathsf{sighash})$ in the [Recovery Statement](#proposedrecoverystatement), +ensuring that the hardware wallet has authorized the spend for the correct +key. Because $\mathsf{LinkCommit}$ is hiding and the proofs are zero knowledge, +no information is leaked about which $\mathsf{qk}$ is being used. + +### Key storage options and analysis + +By *host wallet*, we mean the device that builds the spend transaction and +produces the rest of the Recovery Statement proof. In a multi-signer FROST +setup, this would be the Coordinator [^zip-0312-threat-model]. The host wallet +is given $\mathsf{nk},$ $\mathsf{ak},$ and (assuming $\mathsf{use\_qsk}$ is true) +$\mathsf{qk}$, for use in the Recovery Statement. Then two options are possible +for storage of $\mathsf{qsk}$: + +**Option A** — The $\mathsf{SoK^{qsk}}$ proof is produced inside the hardware +wallet, and $\mathsf{qsk}$ is retained there. + +**Option B** — Alternatively, if the hardware wallet is unable to support +proving $\mathsf{SoK^{qsk}}$, it could be updated to permit exporting +$\mathsf{qsk}$ to the host wallet, and the $\mathsf{SoK^{qsk}}$ proof would be +produced there. + +In either option, $\mathsf{ask}$ would remain on the hardware wallet which +would continue to produce RedDSA spend authorization signatures (or perform +its part of the FROST multi-signing protocol). + +#### Threat model + +The [Recovery Statement](#proposedrecoverystatement) is assumed below to +require both of: + +* an $\mathsf{SoK^{qsk}}$ proof verifying knowledge of $\mathsf{qsk}$ + such that $\mathsf{H^{qk}}(\mathsf{qsk}) = \mathsf{qk}$ for the + spent note's $\mathsf{qk}$; and +* a RedDSA signature on $\mathsf{ak}$, which under FROST is + constructed by cooperation of $t$-of-$n$ hardware-wallet signers, + each contributing using its share of $\mathsf{ask}$. + +Under this assumed structure, with FROST + hardware-wallet deployment, +spend authorization is broken only by either: + +1. **$\mathsf{qsk}$ possession + finding discrete logarithms on the + Pallas curve.** The variants differ only in *how* $\mathsf{qsk}$ + is obtained: + + + 1. the adversary is an authorized FROST signer — they hold a copy + of $\mathsf{qsk}$ by construction; + 2. $\mathsf{qsk}$ is extracted from a hardware wallet, defeating + Option A by a physical-device or side-channel attack; + 3. $\mathsf{qsk}$ is obtained after export to the host wallet, by + compromising the host wallet or intercepting it during export. + +2. **Breaking a primitive or scheme.** RedDSA, FROST, the DKG, or the + proving system has a cryptographic weakness or implementation flaw. + +#### Choosing between Options A and B + +Option A is preferred where the target hardware wallet is capable of +proving $\mathsf{SoK^{qsk}}$ on-device. Option B is a fallback for +cases where it cannot — for instance, due to memory or secure-element +constraints, uncertainty about the proof system that will be chosen +and what will be tractable on small devices, or the device having been +obsoleted before firmware support could be added. + +Under Option A, the host wallet holds only the full viewing key +($\mathsf{ak}$, $\mathsf{nk}$) —which the pre-Quantum-Recoverability +protocol already entrusted to it— plus $\mathsf{qk}$. The $\mathsf{qsk}$ +attack surface is then 1.a. or 1.b. only. + +Option B additionally places $\mathsf{qsk}$ on the host wallet, admitting +case 1.c. as well. This has the disadvantage that host-wallet compromise +is a substantially larger attack surface than hardware-wallet extraction. +However, even with $\mathsf{qsk}$ in hand, an adversary would still need +to break RedDSA or find discrete logarithms on the Pallas curve to steal +funds. + +Note: with ZIP 32 hierarchical derivation, $\mathsf{qsk}$ need not be +backed up separately from the seed phrase. When $\mathsf{use\_qsk}$ is +true, $\mathsf{qsk} = \mathsf{H^{qsk}}(\mathsf{sk})$ where $\mathsf{sk}$ +is the HD-derived spending key, and so $\mathsf{qsk}$ can be re-derived +from the seed phrase (with or without SLIP 39 Shamir backup [^slip-0039]). +A deployment that does not use ZIP 32 is responsible for the security of +its own backup arrangements. + +## Usage with other proposals requiring note plaintext format changes + +This proposal was originally designed to be deployed alongside ZSAs [^zip-0226] +[^zip-0227] and memo bundles [^zip-0231], which also defined a new note +plaintext format. Since this proposal now defines lead byte $\mathtt{0x03}$, +those proposals will need to use a new lead byte value or values. + +## Specification Updates + +This is written as a set of changes to version 2025.6.2 of the protocol +specification, and to the contents of ZIPs as of May 2026. + +### Changes to the Protocol Specification + +#### § 3.2.1 ‘Note Plaintexts and Memo Fields’ + +Replace the paragraph + +> Define $\mathsf{allowedLeadBytes^{protocol}}(\mathsf{height}, \mathsf{txVersion}) =$ +> $\hspace{2em} \begin{cases} +> \{ \mathtt{0x01} \},&\!\!\!\text{if } \mathsf{height} < \mathsf{CanopyActivationHeight} \\ +> \{ \mathtt{0x01}, \mathtt{0x02} \},&\!\!\!\text{if } \mathsf{CanopyActivationHeight} \leq \mathsf{height} < \mathsf{CanopyActivationHeight} + \mathsf{ZIP212GracePeriod} \\ +> \{ \mathtt{0x02} \},&\!\!\!\text{otherwise.} +> \end{cases}$ + +with + +> Let the constant $\mathsf{ZIP2005ActivationHeight}$ be as defined in +> [[ZIP 2005, Deployment]](#deployment). +> +> Define $\mathsf{allowedLeadBytes^{protocol}}(\mathsf{height}, \mathsf{txVersion}) =$ +> $\hspace{2em} \begin{cases} +> \{ \mathtt{0x01} \},&\!\!\!\text{if } \mathsf{height} < \mathsf{CanopyActivationHeight} \\ +> \{ \mathtt{0x01}, \mathtt{0x02} \},&\!\!\!\text{if } \mathsf{CanopyActivationHeight} \leq \mathsf{height} < \mathsf{CanopyActivationHeight} + \mathsf{ZIP212GracePeriod} \\ +> \{ \mathtt{0x02} \},&\!\!\!\text{if } \mathsf{CanopyActivationHeight} + \mathsf{ZIP212GracePeriod} \leq \mathsf{height} \text{ and } \\ +> &\;\; (\mathsf{height} < \mathsf{ZIP2005ActivationHeight} \text{ or } \mathsf{protocol} \neq \mathsf{Orchard}) \\ +> \{ \mathtt{0x02}, \mathtt{0x03} \},&\!\!\!\text{if } \mathsf{ZIP2005ActivationHeight} \leq \mathsf{height} \text{ and } \mathsf{protocol} = \mathsf{Orchard} \text{ and } \mathsf{txVersion} < 6 \\ +> \{ \mathtt{0x03} \},&\!\!\!\text{otherwise.} +> \end{cases}$ + +Replace + +> Senders SHOULD choose the highest note plaintext lead byte allowed under this +> condition. + +with + +> $\mathsf{ZIP2005ActivationHeight}$ specifies the first block height at which +> recoverable note plaintexts with lead byte $\mathtt{0x03}$ are allowed to +> occur in Orchard outputs. Orchard note plaintexts sent to *wallet-internal* +> addresses SHOULD use lead byte $\mathtt{0x03}$ starting from this height. +> Orchard note plaintexts in v5 transactions sent to *external* addresses +> SHOULD use lead byte $\mathtt{0x02}$ until wallet support for receiving note +> plaintexts with lead byte $\mathtt{0x03}$ is widespread in the Zcash ecosystem. +> +> In other cases, senders of non-dummy note plaintexts SHOULD choose the +> highest note plaintext lead byte allowed according to $\mathsf{allowedLeadBytes}.$ +> For dummy note plaintexts, any of the allowed lead bytes MAY be used (it does +> not matter which). + +Delete the non-normative note: + +> * It is intentional that the definition of $\mathsf{allowedLeadBytes}$ does +> not currently depend on $\mathsf{protocol}$ or $\mathsf{txVersion}.$ It +> might do so in future. + +Add the non-normative note: + +> * For Orchard note plaintexts sent in v6 transactions [^zip-0248], the only +> allowed lead byte value is $\mathtt{0x03}.$ + +It is assumed for these changes that v6 transactions will not activate before +$\mathsf{ZIP2005ActivationHeight}$. + +#### § 4.1.2 ‘Pseudo Random Functions’ + +In the list of places where $\mathsf{PRF^{expand}}$ is used: + +Replace + +> * [**NU5** onward] in § 4.2.3 ‘Orchard Key Components’ [^protocol-orchardkeycomponents], +> with inputs $[\mathtt{0x06}]$, $[\mathtt{0x07}]$, $[\mathtt{0x08}]$, and with +> first byte $\mathtt{0x82}$; +> * in the processes of sending (§ 4.7.2 ‘Sending Notes (Sapling)’ [^protocol-saplingsend] +> and § 4.7.3 ‘Sending Notes (Orchard)’ [^protocol-orchardsend]) and of receiving +> (§ 4.20 ‘In-band secret distribution (Sapling and Orchard)’ [^protocol-saplingandorchardinband]) +> notes, for Sapling with inputs $[\mathtt{0x04}]$ and $[\mathtt{0x05}]$, +> and for Orchard $[t] || \underline{\text{ρ}}$ with +> $t \in \{ \mathtt{0x05}, \mathtt{0x04}, \mathtt{0x09} \}$; + +with + +> * [**NU5** onward] in § 4.2.3 ‘Orchard Key Components’ [^protocol-orchardkeycomponents], +> with inputs $[\mathtt{0x06}]$, $[\mathtt{0x07}]$, $[\mathtt{0x08}]$, and with +> first byte in $\{ \mathtt{0x0C}, \mathtt{0x0D}, \mathtt{0x82} \}$ +> ($\mathtt{0x0C}$ and $\mathtt{0x0D}$ are also specified in [ZIP 2005]); +> * in the processes of sending (§ 4.7.2 ‘Sending Notes (Sapling)’ [^protocol-saplingsend] +> and § 4.7.3 ‘Sending Notes (Orchard)’ [^protocol-orchardsend]) and of receiving +> (§ 4.20 ‘In-band secret distribution (Sapling and Orchard)’ [^protocol-saplingandorchardinband]) +> notes, for Sapling with inputs $[\mathtt{0x04}]$ and $[\mathtt{0x05}]$, +> and for Orchard with first byte in +> $\{ \mathtt{0x05}, \mathtt{0x04}, \mathtt{0x09}, \mathtt{0x0A}, \mathtt{0x0B} \}$ +> ($\mathtt{0x0A}$ and $\mathtt{0x0B}$ are also specified in [ZIP 2005]); + +Add + +> * in [ZIP 2005], with first byte in +> $\{ \mathtt{0x0A}, \mathtt{0x0B}, \mathtt{0x0C}, \mathtt{0x0D} \}$. + +#### § 4.2.3 ‘Orchard Key Components’ + +Add $\ell_{\mathsf{qsk}}$ and $\ell_{\mathsf{qk}}$ to the constants obtained +from § 5.3 ‘Constants’ [^protocol-constants]. + +Replace from "From this spending key" up to and including the line +"let $\mathsf{ak} = \mathsf{Extract}_{\mathbb{P}}(\mathsf{ak}^{\mathbb{P}})$" +in the algorithm with: + +> Under normal circumstances, the Spend authorizing key +> $\mathsf{ask} \;{\small ⦂}\; \mathbb{F}^{*}_{r_{\mathbb{P}}}$ is derived +> directly from $\mathsf{sk}$. However, this might not be the case for +> protocols that require distributed generation of shares of $\mathsf{ask}$, +> such as FROST's Distributed Key Generation [^zip-0312-key-generation] +> (see [[ZIP 2005, Usage with Frost]](#usagewithfrost) for further +> discussion). To support this we define an alternative derivation method +> using an additional "quantum spending key", $\mathsf{qsk}$, and +> "quantum intermediate key", $\mathsf{qk}$. +> +> There can also be advantages to not deriving $\mathsf{ask}$ directly from +> $\mathsf{sk}$ for hardware wallets, in order to separate the authority to +> make proofs for the Recovery Protocol from the spend authorization key +> that is kept on the device (see +> [[ZIP 2005, Usage with hardware wallets]](#usagewithhardwarewallets)). +> The derivation from $\mathsf{qsk}$ can also be used in that case. +> +> Let $\mathsf{use\_qsk} \;{\small ⦂}\; \mathbb{B}$ be a flag indicating +> whether $\mathsf{qsk}$ and $\mathsf{qk}$ are generated and used in the +> derivation of $\mathsf{rivk}$. (In cases where it is desired for the +> generation of key components to match versions of this specification +> prior to {{ fill in version }}, $\mathsf{use\_qsk}$ needs to be set to +> false.) +> +> Define: +> * $\mathsf{H^{ask}}(\mathsf{sk}) = \mathsf{ToScalar^{Orchard}}\big(\mathsf{PRF^{expand}_{sk}}([\mathtt{0x06}])\kern-0.1em\big)$ +> * $\mathsf{H^{nk}}(\mathsf{sk}) = \mathsf{ToBase^{Orchard}}\big(\mathsf{PRF^{expand}_{sk}}([\mathtt{0x07}])\kern-0.1em\big)$ +> * $\mathsf{H^{rivk}}(\mathsf{sk}) = \mathsf{ToScalar^{Orchard}}\big(\mathsf{PRF^{expand}_{sk}}([\mathtt{0x08}])\kern-0.1em\big)$ +> * $\mathsf{H^{qsk}}(\mathsf{sk}) = \mathsf{truncate}_{32}\big(\mathsf{PRF^{expand}_{sk}}([\mathtt{0x0C}])\kern-0.1em\big)$ +> * $\mathsf{H^{qk}}(\mathsf{qsk}) = \mathsf{BLAKE3.derive\_key}(\texttt{“Zcash ZIP 2005 qk-derivation v1”}, \mathsf{qsk}, 32)$ [^BLAKE3]. +> * $\mathsf{H}^{\mathsf{rivk\_ext}}_{\mathsf{qk}}(\mathsf{ak}, \mathsf{nk}) = \mathsf{ToScalar^{Orchard}}\big(\mathsf{PRF^{expand}_{qk}}\big([\mathtt{0x0D}] \,||\, \mathsf{I2LEOSP}_{256}(\mathsf{ak}) \,||\, \mathsf{I2LEOSP}_{256}(\mathsf{nk})\kern-0.1em\big)\kern-0.15em\big)$. +> +> $\mathsf{ask} \;{\small ⦂}\; \mathbb{F}^{*}_{r_{\mathbb{P}}}$, +> the Spend validating key $\mathsf{ak} \;{\small ⦂}\; \{ 1\,..\,q_{\mathbb{P}}-1 \}$, +> the nullifier deriving key $\mathsf{nk} \;{\small ⦂}\; \mathbb{F}_{q_{\mathbb{P}}}$, +> the optional quantum spending key $\mathsf{qsk} \;{\small ⦂}\; \mathbb{B}^{{\kern-0.1em\tiny\mathbb{Y}}[\ell_{\mathsf{qsk}}/8]} \cup \{\bot\}$ +> and quantum intermediate key $\mathsf{qk} \;{\small ⦂}\; \mathbb{B}^{{\kern-0.1em\tiny\mathbb{Y}}[\ell_{\mathsf{qk}}/8]} \cup \{\bot\}$ +> the $\mathsf{Commit^{ivk}}$ randomness $\mathsf{rivk} \;{\small ⦂}\; \mathbb{F}_{r_{\mathbb{P}}}$, +> the diversifier key $\mathsf{dk} \;{\small ⦂}\; \mathbb{B}^{{\kern-0.1em\tiny\mathbb{Y}}[\ell_{\mathsf{dk}}/8]}$, +> the $\mathsf{KA^{Orchard}}$ private key $\mathsf{ivk} \;{\small ⦂}\; \{ 1\,..\,q_{\mathbb{P}}-1 \}$, +> the outgoing viewing key $\mathsf{ovk} \;{\small ⦂}\; \mathbb{B}^{{\kern-0.1em\tiny\mathbb{Y}}[\ell_{\mathsf{ovk}}/8]}$, +> and corresponding “internal” keys MUST be derived as follows: +> +> $\hspace{1.0em}$ let $\mathsf{nk} = \mathsf{H^{nk}}(\mathsf{sk})$
    +> $\hspace{1.0em}$ if $\mathsf{use\_qsk}$:
    +> $\hspace{2.5em}$ obtain a $\mathsf{SpendAuthSig^{Orchard}}$ public key $\mathsf{ak}^{\mathbb{P}} \;{\small ⦂}\; \mathbb{P}^*$ by any suitably secure
    +> $\hspace{3.5em}$ method that ensures the last bit of $\mathsf{repr}_{\mathbb{P}}(\mathsf{ak}^{\mathbb{P}})$ is $0$ (see below).
    +> $\hspace{2.5em}$ let $\mathsf{ak} = \mathsf{Extract}_{\mathbb{P}}(\mathsf{ak}^{\mathbb{P}})$
    +> $\hspace{2.5em}$ let $\mathsf{qsk} = \mathsf{H^{qsk}}(\mathsf{sk})$
    +> $\hspace{2.5em}$ let $\mathsf{qk} = \mathsf{H^{qk}}(\mathsf{qsk})$
    +> $\hspace{2.5em}$ let $\mathsf{rivk} = \mathsf{H}^{\mathsf{rivk\_ext}}_{\mathsf{qk}}(\mathsf{ak}, \mathsf{nk})$
    +> $\hspace{1.0em}$ else:
    +> $\hspace{2.5em}$ let mutable $\mathsf{ask} \leftarrow \mathsf{H^{ask}}(\mathsf{sk})$
    +> $\hspace{2.5em}$ let $\mathsf{ak}_{\mathbb{P}} = \mathsf{SpendAuthSig^{Orchard}.DerivePublic}(\mathsf{ask})$
    +> $\hspace{2.5em}$ if the last bit (that is, the $\tilde{y}$ bit) of $\mathsf{repr}_{\mathbb{P}}(\mathsf{ak}_{\mathbb{P}})$ is $1$:
    +> $\hspace{4.0em}$ set $\mathsf{ask} \leftarrow -\mathsf{ask}$ +> +> $\hspace{2.5em}$ let $\mathsf{ak} = \mathsf{Extract}_{\mathbb{P}}(\mathsf{ak}_{\mathbb{P}})$
    +> $\hspace{2.5em}$ let $\mathsf{qsk} = \mathsf{qk} = \bot$ (there are no quantum spending/intermediate keys in this case)
    +> $\hspace{2.5em}$ let $\mathsf{rivk} = \mathsf{H^{rivk}}(\mathsf{sk})$ + +Add before "As explained in § 3.1": + +> When $\mathsf{use\_qsk}$ is true, possible methods of generating +> $\mathsf{ak}^{\mathbb{P}}$ include direct generation of an Orchard Spend +> authorizing key $\mathsf{ask} \;{\small ⦂}\; \mathbb{F}^{*}_{r_{\mathbb{P}}}$ followed by +> $\mathsf{ak}^{\mathbb{P}} = \mathsf{SpendAuthSig^{Orchard}.DerivePublic}(\mathsf{ask})$, +> or FROST distributed key generation [^zip-0312-key-generation] in which the +> corresponding spend-authorization material is $t$-of-$n$ shared among the +> participants. + +Add the following notes: + +> * If $\mathsf{ask}$, $\mathsf{ak}$, $\mathsf{nk}$, $\mathsf{rivk}$, and +> $\mathsf{rivk\_internal}$ are not generated as specified in this section, +> then it may not be possible to recover the resulting notes as specified in +> [ZIP 2005] in the event that attacks using quantum computers become +> practical. In addition, to recover notes it is necessary to retain, or be +> able to rederive $\mathsf{sk}$, and also to know whether $\mathsf{use\_qsk}$ +> was used to derive the $\mathsf{ivk}$ and addresses. When FROST is being +> used, it is also necessary to retain the group verifying key $\mathsf{ak}$ +> and (collectively among the signers) the key material needed to make +> spend authorization signatures that can be verified using $\mathsf{ak}$. +> +> See [[ZIP 2005, Key storage options and analysis]](#keystorageoptionsandanalysis) +> for further discussion of storage requirements for $\mathsf{sk}$ and +> $\mathsf{qsk}$. + +#### § 4.7.2 ‘Sending Notes (Sapling)’ + +Add after the definition of $\mathsf{leadByte}$: + +> Define $\mathsf{Derive\_rcm^{Sapling}_{rseed}}(\mathsf{leadByte}) = \begin{cases} +> \mathsf{LEOS2IP}_{256}(\mathsf{rseed}),&\!\!\!\text{if } \mathsf{leadByte} = \mathtt{0x01} \\ +> \mathsf{ToScalar^{Sapling}}\big(\mathsf{PRF^{expand}_{rseed}}([\mathtt{0x04}])\kern-0.1em\big),&\!\!\!\text{if } \mathsf{leadByte} = \mathtt{0x02} +> \end{cases}$ +> +> Define $\mathsf{H^{esk,Sapling}_{rseed}}(\_) = \mathsf{ToScalar^{Sapling}}\big(\mathsf{PRF^{expand}_{rseed}}([\mathtt{0x05}])\kern-0.1em\big)$. +> +> ($\mathsf{H^{esk,Sapling}}$ intentionally takes an argument that is unused.) + +Replace the lines deriving $\mathsf{rcm}$ and $\mathsf{esk}$ with + +> Derive $\mathsf{rcm} = \mathsf{Derive\_rcm^{Sapling}_{rseed}}(\mathsf{leadByte})$ +> +> Derive $\mathsf{esk} = \mathsf{H^{esk,Sapling}_{rseed}}(\bot)$ + +#### § 4.7.3 ‘Sending Notes (Orchard)’ + +Add before "For each Action description": + +> Define $\mathsf{H^{rcm,Orchard}_{rseed}}(\mathsf{g}\star_{\mathsf{d}}, \mathsf{pk}\star_{\mathsf{d}}, \mathsf{v}, \underline{\text{ρ}}, \text{ψ}) =$ +> $\mathsf{ToScalar^{Orchard}}\big(\mathsf{PRF^{expand}_{rseed}}(\mathsf{pre\_rcm})\kern-0.1em\big)$ +> +> where $\mathsf{pre\_rcm} = [\mathtt{0x0B}] \,||\, \mathsf{LEBS2OSP}_{256}(\mathsf{g}\star_{\mathsf{d}}) \,||\, \mathsf{LEBS2OSP}_{256}(\mathsf{pk}\star_{\mathsf{d}}) \,||\, \mathsf{I2LEOSP}_{64}(\mathsf{v}) \,||\, \underline{\text{ρ}} \,||\, \mathsf{I2LEOSP}_{256}(\text{ψ})$. +> +> Define $\mathsf{Derive\_rcm^{Orchard}_{rseed}}(\mathsf{leadByte}, \mathsf{g}\star_{\mathsf{d}}, \mathsf{pk}\star_{\mathsf{d}}, \mathsf{v}, \underline{\text{ρ}}, \text{ψ}) = \begin{cases} +> \mathsf{ToScalar^{Orchard}}\big(\mathsf{PRF^{expand}_{rseed}}([\mathtt{0x05}] \,||\, \underline{\text{ρ}})\kern-0.1em\big),&\!\!\!\text{if } \mathsf{leadByte} = \mathtt{0x02} \\ +> \mathsf{H^{rcm,Orchard}_{rseed}}(\mathsf{g}\star_{\mathsf{d}}, \mathsf{pk}\star_{\mathsf{d}}, \mathsf{v}, \underline{\text{ρ}}, \text{ψ}),&\!\!\!\text{if } \mathsf{leadByte} = \mathtt{0x03} +> \end{cases}$ +> +> Define $\mathsf{H^{esk,Orchard}_{rseed}}(\underline{\text{ρ}}) = \mathsf{ToScalar^{Orchard}}\big(\mathsf{PRF^{expand}_{rseed}}([\mathtt{0x04}] \,||\, \underline{\text{ρ}})\kern-0.1em\big)$. +> +> Define $\mathsf{H^{\text{ψ},Orchard}_{rseed}}(\underline{\text{ρ}}) = \mathsf{ToBase^{Orchard}}\big(\mathsf{PRF^{expand}_{rseed}}([\mathtt{0x09}] \,||\, \underline{\text{ρ}})\kern-0.1em\big)$. + +The first-byte domain separator $\mathtt{0x0A}$ for $\mathsf{PRF^{expand}}$ is reserved by this ZIP for use by split notes in ZIP 226 [^zip-0226-split-notes]. + +Insert before the derivation of $\mathsf{esk}$: + +> Let $\mathsf{g}\star_{\mathsf{d}} = \mathsf{repr}_{\mathbb{P}}(\mathsf{g_d})$, +> and $\mathsf{pk}\star_{\mathsf{d}} = \mathsf{repr}_{\mathbb{P}}(\mathsf{pk_d})$. + +and use these in the inputs to $\mathsf{NoteCommit^{Orchard}}$. + +Replace the lines deriving $\mathsf{esk}$, $\mathsf{rcm}$, and $\text{ψ}$ +with + +> Derive $\mathsf{esk} = \mathsf{H^{esk,Orchard}_{rseed}}(\underline{\text{ρ}})$ + +> Derive $\mathsf{rcm} = \mathsf{Derive\_rcm^{Orchard}_{rseed}}(\mathsf{leadByte}, \mathsf{g}\star_{\mathsf{d}}, \mathsf{pk}\star_{\mathsf{d}}, \mathsf{v}, \underline{\text{ρ}}, \text{ψ})$ + +> Derive $\text{ψ} = \mathsf{H^{\text{ψ},Orchard}_{rseed}}(\underline{\text{ρ}})$ + +#### § 4.8.2 ‘Dummy Notes (Sapling)’ + +Add + +> Let $\mathsf{Derive\_rcm^{Sapling}}$ be as defined in +> § 4.7.2 ‘Sending Notes (Sapling)’. + +Replace the line deriving $\mathsf{rcm}$ with + +> Derive $\mathsf{rcm} = \mathsf{Derive\_rcm^{Sapling}_{rseed}}(\mathsf{leadByte})$ + +#### § 4.8.3 ‘Dummy Notes (Orchard)’ + +Insert before "The spend-related fields ...": + +> Let $\mathsf{Derive\_rcm^{Orchard}}$ and $\mathsf{H^{\text{ψ},Orchard}}$ be +> as defined in § 4.7.3 ‘Sending Notes (Orchard)’. + +Replace the lines deriving $\mathsf{rcm}$ and $\text{ψ}$ with + +> Let $\mathsf{g}\star_{\mathsf{d}} = \mathsf{repr}_{\mathbb{P}}(\mathsf{g_d})$, +> and $\mathsf{pk}\star_{\mathsf{d}} = \mathsf{repr}_{\mathbb{P}}(\mathsf{pk_d})$. +> +> Derive $\mathsf{rcm} = \mathsf{Derive\_rcm^{Orchard}_{rseed}}(\mathsf{leadByte}, \mathsf{g}\star_{\mathsf{d}}, \mathsf{pk}\star_{\mathsf{d}}, \mathsf{v}, \underline{\text{ρ}}, \text{ψ})$ +> +> Derive $\text{ψ} = \mathsf{H^{\text{ψ},Orchard}_{rseed}}(\underline{\text{ρ}})$ + +and use $\mathsf{g}\star_{\mathsf{d}}$, $\mathsf{pk}\star_{\mathsf{d}}$, +in the inputs to $\mathsf{NoteCommit^{Orchard}}$. + +Per § 3.2.1, use $\mathsf{leadByte} = \mathtt{0x03}$ starting from +$\mathsf{ZIP2005ActivationHeight}$. The choice is operationally irrelevant +for dummy notes, since their plaintexts cannot be decrypted. + +#### § 4.20.2 and § 4.20.3 ‘Decryption using an Incoming/Full Viewing Key (Sapling and Orchard)’ + +For both § 4.20.2 and § 4.20.3, add before the decryption procedure: + +> Let $\mathsf{Derive\_rcm^{Sapling}}$ and $\mathsf{H^{esk,Sapling}}$ be +> as defined in § 4.7.2 ‘Sending Notes (Sapling)’. +> +> Let $\mathsf{Derive\_rcm^{Orchard}}$, $\mathsf{H^{esk,Orchard}}$, +> and $\mathsf{H^{\text{ψ},Orchard}}$ be as defined in +> § 4.7.3 ‘Sending Notes (Orchard)’. + +For § 4.20.3, replace + +> $\hspace{1.0em}$ if $\mathsf{esk} \geq r_{\mathbb{G}}$ or $\mathsf{pk_d} = \bot$, return $\bot$ + +with + +> $\hspace{1.0em}$ if $\mathsf{esk} \geq r_{\mathbb{G}}$ or $\mathsf{pk_d} = \bot$ or (for Sapling) $\mathsf{pk_d} \not\in \mathbb{J}^{(r)*}$ +> (see note below), return $\bot$ + +and in the note containing "However, this is technically redundant with the +later check that returns $\bot$ if $\mathsf{pk_d} \not\in \mathbb{J}^{(r)*}$", +delete the word "later". + +For both § 4.20.2 and § 4.20.3, replace + +> $\hspace{1.0em}$ for Sapling, let $\mathsf{pre\_rcm} = [4]$ and $\mathsf{pre\_esk} = [5]$
    +> $\hspace{1.0em}$ for Orchard, let $\underline{\text{ρ}} = \mathsf{I2LEOSP}_{256}(\mathsf{nf^{old}}$ from the same Action description $\!)$, $\mathsf{pre\_rcm} = [5] \,||\, \underline{\text{ρ}}$, and $\mathsf{pre\_esk} = [4] \,||\, \underline{\text{ρ}}$ + +with + +> $\hspace{1.0em}$ let $\underline{\text{ρ}} = \mathsf{I2LEOSP}_{256}(\mathsf{nf^{old}}$ from the same Action description $\!)$ + +For § 4.20.2, replace + +> $\hspace{1.0em}$ let $\mathsf{rcm} = \begin{cases} +> \mathsf{LEOS2IP}_{256}(\mathsf{rseed}),&\!\!\!\text{if } \mathsf{leadByte} = \mathtt{0x01} \\ +> \mathsf{ToScalar}\big(\mathsf{PRF^{expand}_{rseed}}(\mathsf{pre\_rcm})\kern-0.1em\big),&\!\!\!\text{otherwise} +> \end{cases}$
    +> $\hspace{1.0em}$ if $\mathsf{rcm} \geq r_{\mathbb{G}}$, return $\bot$
    +> $\hspace{1.0em}$ let $\mathsf{g_d} = \mathsf{DiversifyHash}(\mathsf{d})$. if (for Sapling) $\mathsf{g_d} = \bot$, return $\bot$
    +> $\hspace{1.0em}$ [**Canopy** onward] if $\mathsf{leadByte} \neq \mathtt{0x01}$:
    +> $\hspace{2.5em}$ $\mathsf{esk} = \mathsf{ToScalar^{protocol}}\big(\mathsf{PRF^{expand}_{rseed}}(\mathsf{pre\_esk})\kern-0.1em\big)$
    +> $\hspace{2.5em}$ if $\mathsf{repr}_{\mathbb{G}}\big(\mathsf{KA.DerivePublic}(\mathsf{esk}, \mathsf{g_d})\kern-0.1em\big) \neq \mathtt{ephemeralKey}$, return $\bot$ +> +> $\hspace{1.0em}$ let $\mathsf{pk_d} = \mathsf{KA.DerivePublic}(\mathsf{ivk}, \mathsf{g_d})$ + +with + +> $\hspace{1.0em}$ let $\mathsf{g_d} = \mathsf{DiversifyHash}(\mathsf{d})$. if (for Sapling) $\mathsf{g_d} = \bot$, return $\bot$
    +> $\hspace{1.0em}$ [**Canopy** onward] if $\mathsf{leadByte} \neq \mathtt{0x01}$:
    +> $\hspace{2.5em}$ let $\mathsf{esk} = \mathsf{H^{esk,protocol}_{rseed}}(\underline{\text{ρ}})$
    +> $\hspace{2.5em}$ if $\mathsf{repr}_{\mathbb{G}}\big(\mathsf{KA.DerivePublic}(\mathsf{esk}, \mathsf{g_d})\kern-0.1em\big) \neq \mathtt{ephemeralKey}$, return $\bot$
    +> +> $\hspace{1.0em}$ let $\mathsf{pk_d} = \mathsf{KA.DerivePublic}(\mathsf{ivk}, \mathsf{g_d})$
    +> $\hspace{1.0em}$ let $\mathsf{g}\star_{\mathsf{d}} = \mathsf{repr}_{\mathbb{P}}(\mathsf{g_d})$, $\mathsf{pk}\star_{\mathsf{d}} = \mathsf{repr}_{\mathbb{P}}(\mathsf{pk_d})$
    +> $\hspace{1.0em}$ let $\text{ψ} = \mathsf{H^{\text{ψ},Orchard}_{rseed}}(\underline{\text{ρ}})$ for Orchard or $\bot$ for Sapling
    +> $\hspace{1.0em}$ let $\mathsf{rcm} = \begin{cases} +> \mathsf{Derive\_rcm^{Sapling}_{rseed}}(\mathsf{leadByte}),&\!\!\!\text{if } \mathsf{protocol} = \mathsf{Sapling} \\ +> \mathsf{Derive\_rcm^{Orchard}_{rseed}}(\mathsf{leadByte}, \mathsf{g}\star_{\mathsf{d}}, \mathsf{pk}\star_{\mathsf{d}}, \mathsf{v}, \underline{\text{ρ}}, \text{ψ}),&\!\!\!\text{if } \mathsf{protocol} = \mathsf{Orchard} +> \end{cases}$
    +> $\hspace{1.0em}$ if $\mathsf{rcm} \geq r_{\mathbb{G}}$, return $\bot$ + +The order of operations has to be altered because the derivation of +$\mathsf{rcm}$ can depend on $\mathsf{g_d}$ and $\mathsf{pk_d}$. +The definitions of $\mathsf{pre\_rcm}$ and $\mathsf{pre\_esk}$ are moved or inlined +into § 4.7.2 ‘Sending Notes (Sapling)’ and § 4.7.3 ‘Sending Notes (Orchard)’ which +define $\mathsf{Derive\_rcm^{\{Sapling,Orchard\}}}$ and $\mathsf{H^{esk,\{Sapling,Orchard\}}}$. + +For § 4.20.3, replace + +> $\hspace{1.0em}$ let $\mathsf{rcm} = \begin{cases} +> \mathsf{LEOS2IP}_{256}(\mathsf{rseed}),&\!\!\!\text{if } \mathsf{leadByte} = \mathtt{0x01} \\ +> \mathsf{ToScalar}\big(\mathsf{PRF^{expand}_{rseed}}(\mathsf{pre\_rcm})\kern-0.1em\big),&\!\!\!\text{otherwise} +> \end{cases}$
    +> $\hspace{1.0em}$ if $\mathsf{rcm} \geq r_{\mathbb{G}}$, return $\bot$
    +> $\hspace{1.0em}$ let $\mathsf{g_d} = \mathsf{DiversifyHash}(\mathsf{d})$. if (for Sapling) $\mathsf{g_d} = \bot$ or $\mathsf{pk_d} \not\in \mathbb{J}^{(r)*}$ (see note below), return $\bot$ + +with + +> $\hspace{1.0em}$ let $\mathsf{g_d} = \mathsf{DiversifyHash}(\mathsf{d})$. if (for Sapling) $\mathsf{g_d} = \bot$, return $\bot$
    +> $\hspace{1.0em}$ let $\mathsf{g}\star_{\mathsf{d}} = \mathsf{repr}_{\mathbb{P}}(\mathsf{g_d})$, $\mathsf{pk}\star_{\mathsf{d}} = \mathsf{repr}_{\mathbb{P}}(\mathsf{pk_d})$
    +> $\hspace{1.0em}$ let $\text{ψ} = \mathsf{H^{\text{ψ},Orchard}_{rseed}}(\underline{\text{ρ}})$ for Orchard or $\bot$ for Sapling
    +> $\hspace{1.0em}$ let $\mathsf{rcm} = \begin{cases} +> \mathsf{Derive\_rcm^{Sapling}_{rseed}}(\mathsf{leadByte}),&\!\!\!\text{if } \mathsf{protocol} = \mathsf{Sapling} \\ +> \mathsf{Derive\_rcm^{Orchard}_{rseed}}(\mathsf{leadByte}, \mathsf{g}\star_{\mathsf{d}}, \mathsf{pk}\star_{\mathsf{d}}, \mathsf{v}, \underline{\text{ρ}}, \text{ψ}),&\!\!\!\text{if } \mathsf{protocol} = \mathsf{Orchard} +> \end{cases}$
    +> $\hspace{1.0em}$ if $\mathsf{rcm} \geq r_{\mathbb{G}}$, return $\bot$ + +and delete "where $\text{ψ} = \mathsf{ToBase^{Orchard}}\big(\mathsf{PRF^{expand}_{rseed}}([9] \,||\, \underline{\text{ρ}})\kern-0.1em\big)$". + +#### § 5.3 ‘Constants’ + +Add the definitions + +> $\ell_{\mathsf{qsk}} \;{\small ⦂}\; \mathbb{N} := 256$
    +> $\ell_{\mathsf{qk}} \;{\small ⦂}\; \mathbb{N} := 256$ + +### Changes to ZIPs + +#### ZIP 32 + +Add a $\ast$ to the arrows leading to $\mathsf{ask}$ and $\mathsf{rivk}$ +in the diagram in section ‘Orchard internal key derivation’ +[^zip-0032-orchard-internal-key-derivation], with the following note: + +> $\ast$ The derivations of $\mathsf{ask}$ and $\mathsf{rivk}$ shown in +> the diagram are not the only possibility. For further detail see +> § 4.2.3 ‘Orchard Key Components’ in the protocol specification. +> However, if $\mathsf{ask}$, $\mathsf{ak}$, $\mathsf{nk}$, $\mathsf{rivk}$, +> and $\mathsf{rivk\_internal}$ are not generated as in the diagram, then +> it may not be possible to recover the resulting notes as specified in +> [ZIP 2005] in the event that attacks using quantum computers become +> practical. + +#### ZIP 212 + +Add a note before the Abstract: + +
    + +This ZIP reflects the changes made to note encryption for the Canopy upgrade. +It does not include subsequent changes in [ZIP 2005]. + +# Rationale + +## Cryptographic background + +This rationale is written primarily for cryptologists and protocol +designers familiar with the Zcash shielded protocols. It is recommended +to first read the slides of, and/or watch the following presentations: + +* *Understanding Zcash Security* at Zcon3 [^zcash-security] +* *Post-Quantum Zcash* at ZconVI [^pq-zcash] + +To understand the modelling of hash function and commitment security +against a quantum adversary we also recommend [^Unruh2015] and [^Unruh2016]. + +## Proposed Recovery Protocol + +The details of the protocol in this section are subject to change. This +description is meant to facilitate analysis of whether the specification +changes to be adopted now are likely to be sufficient to securely support +a Recovery Protocol. + +The proposed Recovery Protocol works, roughly speaking, by enforcing the +derivations given in the [Flow diagram for the Orchard protocol], and we +suggest having that diagram open in another window to refer to it. + +### Proposed Recovery Statement + +Import this definition from § 4.2.3 ‘Orchard Key Components’ [^protocol-orchardkeycomponents]: + +> Define $\mathsf{H}^{\mathsf{rivk\_ext}}_{\mathsf{qk}}(\mathsf{ak}, \mathsf{nk}) = \mathsf{ToScalar^{Orchard}}\big(\mathsf{PRF^{expand}_{qk}}\big([\mathtt{0x0D}] \,||\, \mathsf{I2LEOSP}_{256}(\mathsf{ak}) \,||\, \mathsf{I2LEOSP}_{256}(\mathsf{nk})\kern-0.1em\big)\kern-0.15em\big)$. + +Import this definition from ZIP 32 [^zip-0032-orchard-internal-key-derivation]: + +> $\mathsf{H^{rivk\_int}_{rivk\_ext}}(\mathsf{ak}, \mathsf{nk}) = \mathsf{ToScalar^{Orchard}}\big(\mathsf{PRF^{expand}_{rivk\_ext}}\big([\mathtt{0x83}] \,||\, \mathsf{I2LEOSP}_{256}(\mathsf{ak}) \,||\, \mathsf{I2LEOSP}_{256}(\mathsf{nk})\kern-0.1em\big)\kern-0.15em\big)$ + +Import these definitions from § 4.7.3 ‘Sending Notes (Orchard)’ [^protocol-orchardsend]: + +> Define $\mathsf{H^{rcm,Orchard}_{rseed}}(\mathsf{g}\star_{\mathsf{d}}, \mathsf{pk}\star_{\mathsf{d}}, \mathsf{v}, \underline{\text{ρ}}, \text{ψ}) =$ +> $\mathsf{ToScalar^{Orchard}}\big(\mathsf{PRF^{expand}_{rseed}}(\mathsf{pre\_rcm})\kern-0.1em\big)$ +> +> where $\mathsf{pre\_rcm} = [\mathtt{0x0B}] \,||\, \mathsf{LEBS2OSP}_{256}(\mathsf{g}\star_{\mathsf{d}}) \,||\, \mathsf{LEBS2OSP}_{256}(\mathsf{pk}\star_{\mathsf{d}}) \,||\, \mathsf{I2LEOSP}_{64}(\mathsf{v}) \,||\, \underline{\text{ρ}} \,||\, \mathsf{I2LEOSP}_{256}(\text{ψ})$. +> +> Define $\mathsf{H^{\text{ψ},Orchard}_{rseed}}(\underline{\text{ρ}}) = \mathsf{ToBase^{Orchard}}\big(\mathsf{PRF^{expand}_{rseed}}([\mathtt{0x09}] \,||\, \underline{\text{ρ}})\kern-0.1em\big)$. + +Import this definition from § 5.4.7.1 ‘Spend Authorization Signature (Sapling and Orchard)’ [^protocol-concretespendauthsig]: + +> Define $\mathcal{G}^{\mathsf{Orchard}} = \mathsf{GroupHash}^{\mathbb{P}}(\texttt{“z.cash:Orchard”}, \texttt{“G”})$. + +A valid instance of a Recovery Statement assures that given a primary input: + +$\begin{array}{rl} + \hspace{4.1em} ( \mathsf{rt^{Orchard}} \!\!\!\!&{\small ⦂}\; \{ 0\,..\,q_{\mathbb{P}}-1 \}, \\ + \mathsf{rk} \!\!\!\!&{\small ⦂}\; \mathsf{SpendAuthSig^{Orchard}.Public} ), \\ + \mathsf{nf} \!\!\!\!&{\small ⦂}\; \mathbb{F}_{q_{\mathbb{P}}}, \\ + \mathsf{SigHash} \!\!\!\!&{\small ⦂}\; \mathsf{MessageHash} ) +\end{array}$ + +the prover knows an auxiliary input: + +$\begin{array}{rl} + \hspace{4em} ( \mathsf{path} \!\!\!\!&{\small ⦂}\; \{ 0\,..\,q_{\mathbb{P}}-1 \}^{[\mathsf{MerkleDepth^{Orchard}}]}, \\ + \mathsf{pos} \!\!\!\!&{\small ⦂}\; \{ 0\,..\,2^{\mathsf{MerkleDepth^{Orchard}}}-1 \}, \\ + K \!\!\!\!&{\small ⦂}\; \mathbb{B}^{[\ell_{\mathsf{sk}}]}, \\ + \mathsf{\alpha} \!\!\!\!&{\small ⦂}\; \mathbb{F}_{r_{\mathbb{P}}}, \\ + \mathsf{ak}^{\mathbb{P}} \!\!\!\!&{\small ⦂}\; \mathbb{P}^*, \\ + \mathsf{nk} \!\!\!\!&{\small ⦂}\; \mathbb{F}_{q_{\mathbb{P}}}, \\ + \mathsf{rivk\_ext} \!\!\!\!&{\small ⦂}\; \mathbb{F}_{r_{\mathbb{P}}}, \\ + \mathsf{rivk} \!\!\!\!&{\small ⦂}\; \mathbb{F}_{r_{\mathbb{P}}}, \\ + (\mathsf{qk}, \sigma_{\mathsf{qsk}}) \!\!\!\!&{\small ⦂}\; \big(\mathbb{B}^{{\kern-0.1em\tiny\mathbb{Y}}[\ell_{\mathsf{qk}}/8]} \times \mathsf{SoK^{qsk}}\big((\mathsf{qk}), \mathsf{SigHash}\big)\big) \cup \{(\bot, \bot)\}, \\ + \sigma_{\mathsf{sk}} \!\!\!\!&{\small ⦂}\; \mathsf{SoK^{sk}}\big((\mathsf{ak}^{\mathbb{P}}, \mathsf{nk}, \mathsf{rivk\_ext}), \mathsf{SigHash}\big) \cup \{\bot\}, \\ + \mathsf{rseed} \!\!\!\!&{\small ⦂}\; \mathbb{B}^{{\kern-0.1em\tiny\mathbb{Y}}[32]}, \\ + \mathsf{g_d} \!\!\!\!&{\small ⦂}\; \mathbb{P}^*, \\ + \mathsf{v} \!\!\!\!&{\small ⦂}\; \{ 0\,..\,2^{\ell_{\mathsf{value}}}-1 \}, \\ + \text{ρ} \!\!\!\!&{\small ⦂}\; \mathbb{F}_{q_{\mathbb{P}}} ) +\end{array}$ + +where + +$\begin{array}{rll} + \hspace{1em}\mathsf{BindKeys^{sk}}(\mathsf{sk}, \mathsf{ak}^{\mathbb{P}}, \mathsf{nk}, \mathsf{rivk\_ext}) = + \big(&\!\!\!\! \mathsf{ak}^{\mathbb{P}} = [\mathsf{H^{ask}}(\mathsf{sk})]\, \mathcal{G}^{\mathsf{Orchard}} \\ + &\!\!\!\! \wedge\; \mathsf{nk} = \mathsf{H^{nk}}(\mathsf{sk}) \\ + &\!\!\!\! \wedge\; \mathsf{rivk\_ext} = \mathsf{H^{rivk\_legacy}}(\mathsf{sk}) \,\big) +\end{array}$ + +and + +$\begin{array}{rll} + \hspace{1em}\mathsf{SoK^{qsk}.Statement} \!\!\!&=\, \big\{\,\mathsf{qsk} \;{\small ⦂}\; \mathbb{B}^{{\kern-0.1em\tiny\mathbb{Y}}[\ell_{\mathsf{qsk}}/8]} &\!\!\!\!|\;\, \mathsf{qk} = \mathsf{H^{qk}}(\mathsf{qsk}) \,\big\} \\ + \hspace{1em}\mathsf{SoK^{sk}.Statement} \!\!\!&=\, \big\{\,\mathsf{sk} \;{\small ⦂}\; \mathbb{B}^{[\ell_{\mathsf{sk}}]} &\!\!\!\!|\;\, \mathsf{BindKeys^{sk}}(\mathsf{sk}, \mathsf{ak}^{\mathbb{P}}, \mathsf{nk}, \mathsf{rivk\_ext}) \,\big\} +\end{array}$ + +such that the following conditions hold: + +$\begin{array}{l} +\{\;\, \mathsf{rk} = \mathsf{SpendAuthSig^{Orchard}.RandomizePublic}(\alpha, \mathsf{ak}^{\mathbb{P}}) \vphantom{\big(}\\ +\wedge\; \mathsf{ak} = \mathsf{Extract}_{\mathbb{P}}(\mathsf{ak}^{\mathbb{P}}) \vphantom{\Big(}\\ +\wedge\; \big((\mathsf{qk}, \sigma_{\mathsf{qsk}}) = (\bot, \bot)\big) \neq \big(\sigma_{\mathsf{sk}} = \bot\big) \vphantom{\big(}\\ +\wedge\; (\mathsf{qk}, \sigma_{\mathsf{qsk}}) \neq (\bot, \bot) \Rightarrow \big(\, \mathsf{SoK^{qsk}.Validate}\big((\mathsf{qk}), \mathsf{SigHash}, \sigma_{\mathsf{qsk}}\big) \kern0.05em\wedge\, \mathsf{rivk\_ext} = \mathsf{H^{rivk\_ext}_{qk}}(\mathsf{ak}, \mathsf{nk})\kern0.05em\big) \vphantom{\Big(}\\ +\wedge\; \sigma_{\mathsf{sk}} \neq \bot \Rightarrow \mathsf{SoK^{sk}.Validate}\big((\mathsf{ak}^{\mathbb{P}}, \mathsf{nk}, \mathsf{rivk\_ext}), \mathsf{SigHash}, \sigma_{\mathsf{sk}}\big) \vphantom{\big(}\\ +\wedge\; \mathsf{rivk} \in \big\{\, \mathsf{rivk\_ext},\, \mathsf{H^{rivk\_int}_{rivk\_ext}}(\mathsf{ak}, \mathsf{nk}) \,\big\} \vphantom{\Big(}\\ +\wedge\; \text{let } \mathsf{ivk} = \mathsf{Commit^{ivk}_{rivk}}(\mathsf{ak}, \mathsf{nk}) \vphantom{\big(}\\ +\wedge\; \mathsf{ivk} \not\in \{0, \bot\} \vphantom{\Big(}\\ +\wedge\; \text{let } \mathsf{pk_d} = [\mathsf{ivk}]\, \mathsf{g_d} \vphantom{\big(}\\ +\wedge\; \text{let } \text{ψ} = \mathsf{H^{\text{ψ},Orchard}_{rseed}}(\underline{\text{ρ}}) \vphantom{\Big(}\\ +\wedge\; \text{let } \mathsf{noterepr} = \big(\mathsf{repr}_{\mathbb{P}}(\mathsf{g_d}), \mathsf{repr}_{\mathbb{P}}(\mathsf{pk_d}), \mathsf{v}, \underline{\text{ρ}}, \text{ψ}\big) \vphantom{\big(}\\ +\wedge\; \text{let } \mathsf{rcm} = \mathsf{H^{rcm,Orchard}_{rseed}}\big(\mathtt{0x03}, \mathsf{noterepr}\big) \vphantom{\Big(}\\ +\wedge\; \text{let } \mathsf{cm} = \mathsf{NoteCommit^{Orchard}_{rcm}}(\mathsf{noterepr}) \vphantom{\big(}\\ +\wedge\; \mathsf{cm} \neq \bot \vphantom{\Big(}\\ +\wedge\; \text{let } \mathsf{cm}_x = \mathsf{Extract}_{\mathbb{P}}(\mathsf{cm}) \vphantom{\big(}\\ +\wedge\; \text{let } \mathsf{leaf} = \mathsf{MerkleCRH}(\mathsf{cm}_x, \text{ρ}) \vphantom{\Big(}\\ +\wedge\; \mathsf{path} \text{ is a path to } \mathsf{leaf} \text{ in the rehashed commitment tree} \vphantom{\big(}\\ +\wedge\; \mathsf{nf} = \mathsf{DeriveNullifier_{nk}}(\text{ρ}, \text{ψ}, \mathsf{cm}) \vphantom{\Big(}\\ +\} +\end{array}$ + +and $\mathsf{nf}$ is the revealed nullifier. + +(We don't need to check the derivation of $\mathsf{g_d}$ from $\mathsf{d}$.) + +### Cost + +Note that in the "$\mathsf{use\_qsk}$" case, one BLAKE2b compression is required +to compute $\mathsf{rivk\_ext}$ (provided $\ell_{\mathsf{qk}} \leq 504$ bits, so +that the input $\mathsf{qk} \,||\, [\mathtt{0x0D}] \,||\, \mathsf{ak} \,||\, \mathsf{nk}$ +fits in a single 128-byte BLAKE2b block), and in the "not $\mathsf{use\_qsk}$" +case, three BLAKE2b compressions in total are required to compute $\mathsf{H^{ask}}$, +$\mathsf{H^{nk}}$, and $\mathsf{H^{rivk\_legacy}}$. Since these cases are mutually +exclusive, it is possible to multiplex the same three compression function instances. +So, supporting "$\mathsf{use\_qsk}$" in addition to "not $\mathsf{use\_qsk}$" costs +very little extra. + +All of the operations below need to be implemented with complete additions, +even if they are incomplete in the current Orchard[ZSA] statement/circuit. + +In $\mathsf{SoK^{sk}}$ and the main circuit: +* 7 BLAKE2b-512 compressions: + * 3 multiplexed between $\mathsf{H^{rivk\_ext}}$ when $\mathsf{use\_qsk}$ is true (1 compression), + and $\mathsf{H^{ask}}$ + $\mathsf{H^{nk}}$ + $\mathsf{H^{rivk\_legacy}}$ when $\mathsf{use\_qsk}$ is false (3 compressions) + * 1 to compute $\mathsf{H^{rivk\_int}}$ + * 1 to compute $\mathsf{H^{\text{ψ}}}$ + * 2 to compute $\mathsf{H^{rcm}}$ +* 1 use of $\mathsf{Commit^{ivk}}$ ($\mathsf{SinsemillaShortCommit}$) +* 1 use of $\mathsf{NoteCommit}$ ($\mathsf{SinsemillaCommit}$) +* 1 full-width fixed-base Pallas scalar multiplication, $[\mathsf{ask}]\, \mathcal{G}^{\mathsf{Orchard}}$ +* 1 full-width variable-base Pallas scalar multiplication, $[\mathsf{ivk}]\, \mathsf{g_d}$ +* 1 Merkle tree path check +* 1 additional use of $\mathsf{MerkleCRH}$ to compute $\mathsf{leaf}$. + +In $\mathsf{SoK^{qsk}}$: +* 1 BLAKE3 compression for $\mathsf{H^{qk}}$ (with the $\mathsf{derive\_key}$ context key precomputed as a constant) + +plus, potentially, [linking commitments](#linking-commitments) between +the circuits. + +The expensive parts of this are the 7 BLAKE2b compressions. + +## Security analysis + +Let us consider the security of the Orchard protocol against a +discrete-log-breaking adversary — which by definition includes quantum +adversaries. Similar attacks apply to the Sapling protocol. + +Suppose that the proof system has been replaced by one that is +post-quantum knowledge-sound. + +### Repairing the note commitment Merkle tree + +$\mathsf{MerkleCRH}$ is instantiated using +$\mathsf{SinsimillaHash}$ [^protocol-concretesinsemillahash]. +Its collision resistance depends on the Discrete Logarithm Relation Problem +on the Pallas curve [^protocol-sinsemillasecurity], and so it is not +post-quantum collision-resistant or collapsing. However, because the note +commitment tree is public, it is possible to re-hash all of its leaves to +construct a new Merkle tree using a collapsing hash function. +Suppose this has been done. + +> The post-quantum security of Merkle trees —considered as position-binding +> vector commitments which is the property required by Zcash [^zcash-security]— +> is proven under reasonable assumptions in [^CMSZ2021], [^GM2022], and +> [^CDDGS2025]. + +Note: when we rehash the commitment tree, we could include both $\text{ρ}$ and +$\mathsf{cm}_x$ for each note (i.e. what is currently the leaf layer becomes +$\mathsf{MerkleCRH}(\text{ρ}, \mathsf{cm}_x)$ where $\mathsf{MerkleCRH}$ +is collapsing). This change might not be necessary; it just removes potential +complications due to duplicate commitments for the same note. + +### Attacks against binding of note commitments + +We still face the problem that $\mathsf{NoteCommit}$ is not +binding against a discrete-log-breaking adversary: given the discrete +logarithm relations between bases, we can easily write a linear equation +in the scalar field with multiple solutions of the inputs for a given +commitment. + +This allows an adversary to find two distinct notes corresponding to +openings of $\mathsf{NoteCommit}$ on the same commitment. +They create one note as an output and spend the other note — which may +have a greater value, or a value in a different ZSA asset, breaking the +Balance property. + +### Repairing note commitments + +We prefer to fix this without changing $\mathsf{NoteCommit}$ itself. +Instead we change how $\mathsf{rcm}$ is computed to be a hash of $\mathsf{rseed}$ and +$\mathsf{noterepr} = (\mathsf{g}\star_{\mathsf{d}}, \mathsf{pk}\star_{\mathsf{d}}, \mathsf{v}, \underline{\text{ρ}}, \text{ψ})$, +as detailed in the [Specification] section. +Specifically, when $\mathsf{leadByte} = \mathtt{0x03}$ we have: + +$\hspace{2em}\mathsf{rcm} = \mathsf{H^{rcm}_{rseed}}(\mathsf{noterepr}) = \mathsf{ToScalar}(\mathsf{PRF^{expand}_{rseed}}(\mathsf{pre\_rcm}))$ + +$\text{where } \mathsf{pre\_rcm} = [\mathtt{0x0B}] \,||\, \mathsf{encode}(\mathsf{noterepr})$ + +### Informal security argument for binding of note commitments + +For the formal versions of these arguments and their adaptation to the +post-quantum setting, see the [key-binding](#thm-key-binding-rom) and +[Spendability](#thm-spendability-collide) theorems below, and +[§ Adaptation to the quantum setting](#adaptationtothequantumsetting). + +We can view the output of $\mathsf{NoteCommit_{rcm}}$ for +$\mathsf{notetuple} = (\mathsf{rseed}, \mathsf{noterepr})$ +as the point addition of a randomization term +$[\mathsf{H^{rcm}_{rseed}}(\mathsf{noterepr})]\, \mathcal{R}$, +and some other function of $\mathsf{notetuple}$. + +Without loss of generality, we can write that function as +$[\mathsf{f}(\mathsf{notetuple})]\, \mathcal{R}$, +by expanding each of the Sinemilla bases +$\mathcal{C}_j = \mathcal{Q}(D) \text{ or } \mathcal{S}(j)$ used by +[$\mathsf{HashToSinsimillaPoint}$](https://zips.z.cash/protocol/protocol.pdf#concretesinsemillahash) +as $\mathcal{C}_j = [c_j]\, \mathcal{R}$ for some $c_j$. That is, +the note commitment for $\mathsf{notetuple}$ is +$$[\mathsf{H^{rcm}_{rseed}}(\mathsf{noterepr}) + \mathsf{f}(\mathsf{notetuple})]\, \mathcal{R}.$$ + +We will model $\mathsf{H^{rcm}}$ as a random oracle independent of $\mathsf{f}$ with +uniform output on $\mathbb{F}_{r_{\mathbb{P}}}.$ This is reasonable because +$\mathsf{H^{rcm}}$ cannot depend on any of the $c_j$, and in any case it is +instantiated using BLAKE2b, a conventional hash function not related to the +Pallas curve. + +> The fact that $\mathsf{NoteCommit}$ has +> $\text{ψ} = \mathsf{H}^{\text{ψ}}_{\mathsf{rseed}}(\text{ρ})$ as an +> input does not affect the analysis provided that $\mathsf{H^{rcm}}$ and +> $\mathsf{H}^{\text{ψ}}$ can be treated as independent. In practice both +> are defined in terms of $\mathsf{PRF^{expand}}$, but with strict domain +> separation, and so the assumption of independence is reasonable as long +> as BLAKE2b-512 can be modelled as a random oracle. Note that since the +> input to $\mathsf{H^{rcm}}$ needs more than one BLAKE2b input block, we +> require that a HAIFA sponge can be modelled as a random oracle which is +> justified by [^ACMT2025]. It is possible that there could be +> better-than-generic quantum attacks against BLAKE2b-512, but none have +> been published to our knowledge. In practice, we consider it reasonable to +> assume that BLAKE2b-512 has the properties needed for $\mathsf{H^{rcm}}$ +> to be collapsing. Taking the 512-bit BLAKE2b output modulo +> $r_{\mathbb{P}} \approx 2^{254}$ cannot introduce a problem. + +For each $\mathsf{H^{rcm}}$ oracle query the adversary chooses +$\mathsf{notetuple} = (\mathsf{rseed}, \mathsf{noterepr})$ +and obtains a "random" +$\mathsf{rcm} = \mathsf{H^{rcm}_{rseed}}(\mathsf{noterepr})$. + +We have $\mathsf{cm}_x = \mathsf{Extract}_{\mathbb{P}}([\mathsf{H^{rcm}_{rseed}}(\mathsf{noterepr}) + \mathsf{f}(\mathsf{notetuple})]\, \mathcal{R})$. + +Over all Pallas curve points $P$, the number of outputs of +$\mathsf{Extract}_{\mathbb{P}}(P)$ is $(\mathbb{F}_{r_\mathbb{P}} + 1)/2 \approx 2^{253}$ — +one for each possible $x$-coordinate of Pallas curve points, plus one for the +zero point $\mathcal{O}_{\mathbb{P}}$ which is mapped to $0$. + +> Only one point maps to $0$, as opposed to two points mapping to every +> other possible output of $\mathsf{Extract}_{\mathbb{P}}$, but that has +> negligible effect. + +There are two values of $\mathsf{cm}$ that match $\mathsf{cm}_x$ in their $x$-coordinate. +Because the output of $\mathsf{NoteCommit_{rcm}}$ for $\mathsf{notetuple}$ is +of the form $\mathsf{cm} = [\mathsf{f}(\mathsf{notetuple}) + \mathsf{rcm}]\, \mathcal{R}$, +for any given note we have exactly two values of $\mathsf{rcm}$ that will pass +the commitment check. + +Suppose there are $N$ legitimate notes in the tree. The adversary is trying +to find a note that will pass the commitment check without actually being a +note in the tree. As argued above, the distribution of $\mathsf{rcm}$ is +indistinguishable from uniform-random on $\mathbb{F}_{r_\mathbb{P}}$. The +success probability for each attempt in a classical search is therefore +$2N/r_{\mathbb{P}}$ where $r_{\mathbb{P}}$ is the order of the Pallas curve, +and that is negligible because $N \leq 2^{32} \ll r_{\mathbb{P}}$. + +We're not finished yet because we also have to prove that the nullifier is +computed deterministically for a given note. + +All of the inputs to $\mathsf{DeriveNullifier}$ are things we committed to +in the protocol so far *except* $\mathsf{nk}$. By the same argument used +pre-quantumly, there is only one $\mathsf{ivk}$ for a given +$(\mathsf{g_d}, \mathsf{pk_d})$. So in order to just use the existing +protocol for this part, we would need to prove that there is only one +$\mathsf{nk}$ (that is feasible to find) such that +$\mathsf{Commit^{ivk}_{rivk}}(\mathsf{ak}, \mathsf{nk}) = \mathsf{ivk}$. +Unfortunately that's not true; $\mathsf{Commit^{ivk}}$ is instantiated by +$\mathsf{SinsemillaShortCommit}$ which is not post-quantum binding. + +There are two cases depending on which witness branch the adversary +uses (they can choose to attack either, or both simultaneously): + +* Case $\mathsf{sk} \neq \bot$: The spender must prove knowledge of + $\mathsf{sk}$, and that $\mathsf{ak}$, $\mathsf{nk}$, and $\mathsf{rivk}$ + are derived correctly from $\mathsf{sk}$. This works because the + derivations use post-quantum hashes (and $\mathsf{ask} \mapsto \mathsf{ak}$ + is deterministic).
    + In particular, $\mathsf{ivk}$ is an essentially random function of + $\mathsf{sk}$, and so we expect that an adversary has no better attack + than to search for values of $\mathsf{sk}$ + to find one that reproduces a given $\mathsf{ivk}$. Since $\mathsf{ivk}$ + must be an $x$-coordinate of a Pallas curve point (see the note at the end of + [§ 4.2.3 Orchard Key Components](https://zips.z.cash/protocol/protocol.pdf#orchardkeycomponents)), + it can take on $(r_{\mathbb{P}}-1)/2$ values. So if there are $T$ targets + the success probability for each attempt in a classical search is + $2T/(r_{\mathbb{P}}-1)$, which is negligible provided that + $T \ll r_{\mathbb{P}}$. + +* Case $\mathsf{qk} \neq \bot$: This case is almost the same except that + $\mathsf{ivk}$ is now an essentially random function of + $(\mathsf{nk}, \mathsf{ak}, \mathsf{qk})$. The success probability + in terms of $T$ is also the same as for the $\mathsf{sk} \neq \bot$ + case. + +The above security argument means that provided we also check the uses of +$\mathsf{H^{rcm}}$ and $\mathsf{H}^{\text{ψ}}$ in the post-quantum +[Recovery Statement](#proposedrecoverystatement), Orchard note commitments +can be considered binding on the note tuple +$(\mathsf{rseed}, \mathsf{noterepr})$. + +Note that the argument associated with +[Theorem 5.4.4](https://zips.z.cash/protocol/protocol.pdf#thmsinsemillaex) +in the protocol specification ("$\mathsf{SinsemillaHashToPoint}(\ldots) = \bot$ +yields a nontrivial discrete logarithm relation." and +"Since by assumption it is hard to find a nontrivial discrete logarithm +relation, we can argue that it is safe to use incomplete additions when +computing Sinsemilla inside a circuit.") is not applicable when it is +necessary to defend against a discrete-log-breaking or quantum adversary. +Therefore, the post-quantum [Recovery Statement](#proposedrecoverystatement) +will need to use complete curve additions to implement Sinsemilla. + +### Security argument for key binding + +The security of Orchard against several attacks depends on cryptographic +keys being bound to a recoverable note's $\mathsf{ivk}$. Different +Orchard properties need different components of the key witness pinned: + +* **Nullifier-binding** (used by the Balance argument and by the + [Spendability argument](#securityargumentforspendability) below + — the latter via the + [$\mathsf{PRF^{nf}}$-pinning lemma](#lemma-prf-nf-pinning)): + $\mathsf{nk}$ uniquely determined by $\mathsf{ivk}$. +* **Spend Authorization**: $\mathsf{ak}$ (up to $y$-sign of + $\mathsf{ak}^{\mathbb{P}}$) uniquely determined by $\mathsf{ivk}$; + and $\mathsf{qk}$ uniquely determined by $\mathsf{ivk}$ when + $\mathsf{qk} \neq \bot$ (i.e., when $\mathsf{use\_qsk} = \mathsf{true}$). + +The formal key-binding condition stated below covers both of these +uniformly: a key-binding break is a pair of distinct witnesses sharing +the same $\mathsf{ivk}$, where each witness carries the full key tuple +— $(\mathsf{ak}, \mathsf{nk}, \mathsf{rivk})$ plus whichever of +$\mathsf{qk}$ or $\mathsf{sk}$ is in use. If key binding fails, the +Balance, Spendability, and Spend Authorization arguments each lose +their corresponding pinning step. + +Relative to the situation with note commitments where it was reasonable +to only obtain quantum recoverability for newly output Orchard notes, +there is a complication. Addresses may be used over the long term and +it may not be desirable to switch to new addresses, or to avoid funds +being sent to old ones. Fortunately, the Orchard protocol specified each +of $\mathsf{ak}$, $\mathsf{nk}$, and $\mathsf{rivk}$ to be derived from +$\mathsf{sk}$ via $\mathsf{PRF^{expand}}$, which is assumed collapsing. +($\mathsf{rivk}$ is derived differently for an "internal IVK", but that +is also via $\mathsf{PRF^{expand}}$.) + +Classically, the binding of $\mathsf{Commit^{ivk}}$ —instantiated via +Sinsemilla— fails against a discrete-log-breaking adversary, similarly +to $\mathsf{NoteCommit}$. We use essentially the same fix as for +$\mathsf{NoteCommit}$, with the $\mathsf{rivk}$-derivation hashes +playing the role of $\mathsf{H^{rcm}}$. The Recovery Statement checks +the derivation of $\mathsf{rivk}$: + +* When $\mathsf{qk} \neq \bot$, + $\mathsf{rivk\_ext} = \mathsf{H^{rivk\_ext}_{qk}}(\mathsf{ak}, \mathsf{nk})$. +* When $\mathsf{sk} \neq \bot$, + $\mathsf{rivk\_ext} = \mathsf{H^{rivk\_legacy}}(\mathsf{sk})$, with + $\mathsf{ak}$ and $\mathsf{nk}$ also derived from $\mathsf{sk}$ via + $\mathsf{H^{ask}}$ and $\mathsf{H^{nk}}$. + +Exactly one of $\mathsf{qk}$ and $\mathsf{sk}$ is non-$\bot$ per +witness; this is equivalent to case-splitting by $\mathsf{use\_qsk}$. + +In either case, $\mathsf{rivk}$ is then either $\mathsf{rivk\_ext}$ +directly (external IVK) or +$\mathsf{H^{rivk\_int}_{rivk\_ext}}(\mathsf{ak}, \mathsf{nk})$ (internal +IVK). All of these hashes are modelled as independent random oracles for +the key-binding argument. + +As in the [Recovery Statement](#proposedrecoverystatement), we have: + +$\begin{array}{rll} + \hspace{1em}\mathsf{BindKeys^{sk}}(\mathsf{sk}, \mathsf{ak}^{\mathbb{P}}, \mathsf{nk}, \mathsf{rivk\_ext}) = + \big(&\!\!\!\! \mathsf{ak}^{\mathbb{P}} = [\mathsf{H^{ask}}(\mathsf{sk})]\, \mathcal{G}^{\mathsf{Orchard}} \\ + &\!\!\!\! \wedge\; \mathsf{nk} = \mathsf{H^{nk}}(\mathsf{sk}) \\ + &\!\!\!\! \wedge\; \mathsf{rivk\_ext} = \mathsf{H^{rivk\_legacy}}(\mathsf{sk}) \,\big) +\end{array}$ + +Let the key-binding condition on a witness +$w = (\mathsf{ivk}, \mathsf{qk}, \mathsf{sk}, \mathsf{ak}^{\mathbb{P}}, \mathsf{nk}, \mathsf{rivk\_ext}, \mathsf{rivk})$ be: + +$\begin{array}{l} +\;\;\; (\mathsf{sk} = \bot) \neq (\mathsf{qk} = \bot) \\ +\wedge\; \mathsf{qk} \neq \bot \Rightarrow \big(\; \mathsf{rivk\_ext} = \mathsf{H^{rivk\_ext}_{qk}}(\mathsf{ak}, \mathsf{nk}) \,\big) \\ +\wedge\; \mathsf{sk} \neq \bot \Rightarrow \mathsf{BindKeys^{sk}}(\mathsf{sk}, \mathsf{ak}^{\mathbb{P}}, \mathsf{nk}, \mathsf{rivk\_ext}) \\ +\wedge\; \mathsf{rivk} \in \big\{\, \mathsf{rivk\_ext},\, \mathsf{H^{rivk\_int}_{rivk\_ext}}(\mathsf{ak}, \mathsf{nk}) \,\big\} \\ +\wedge\; \mathsf{ivk} = \mathsf{Commit^{ivk}_{rivk}}(\mathsf{ak}, \mathsf{nk}) \\ +\wedge\; \mathsf{ivk} \not\in \{0, \bot\} +\end{array}$ + +where $\mathsf{ak} = \mathsf{Extract}_{\mathbb{P}}(\mathsf{ak}^{\mathbb{P}}).$ + +The predicate intentionally does not constrain the $y$-sign of +$\mathsf{ak}^{\mathbb{P}}$. This is consistent with Orchard's design +choice to use $\mathsf{ak}$ as a single $\mathbb{F}_{q_{\mathbb{P}}}$ +element (the $x$-coordinate $\mathsf{Extract}_{\mathbb{P}}(\mathsf{ak}^{\mathbb{P}})$), +which avoids point-decompression in places that consume $\mathsf{ak}$, +in exchange for a factor-of-2 reduction in concrete binding security. +Accordingly, the break event below identifies witnesses up to the +$y$-sign of $\mathsf{ak}^{\mathbb{P}}$. + +The flags $\mathsf{use\_qsk}$ and $\mathsf{is\_internal\_rivk}$ that +appear in the protocol diagram do not appear in this witness — nor in +the formal Recovery Statement above. Their roles are absorbed into the +witness's structural form: + +* $\mathsf{use\_qsk}$ is encoded in + $(\mathsf{sk} = \bot) \neq (\mathsf{qk} = \bot)$: exactly one of + $\mathsf{sk}$ and $\mathsf{qk}$ is non-$\bot$, and the branch-specific + constraints apply to whichever is present. +* $\mathsf{is\_internal\_rivk}$ is encoded in + $\mathsf{rivk} \in \big\{\mathsf{rivk\_ext},\, \mathsf{H^{rivk\_int}_{rivk\_ext}}(\mathsf{ak}, \mathsf{nk})\big\}$: + both $\mathsf{rivk}$ derivations are admitted simultaneously. + +This formulation is strictly stronger than a flag-conditioned one: a +key-binding break can have $w_1$ and $w_2$ in different branches across +either flag (e.g., $w_1$ with $\mathsf{qk} \neq \bot$ and $w_2$ with +$\mathsf{sk} \neq \bot$, or $w_1$ with external $\mathsf{rivk}$ and +$w_2$ with internal $\mathsf{rivk}$), provided both produce the same +$\mathsf{ivk}$. A flag-based formulation would forbid only same-branch +breaks. + +A **key-binding break** is a pair of witnesses $(w_1, w_2)$ with +shared $\mathsf{ivk}$ satisfying the key-binding condition, whose +$(\mathsf{qk}, \mathsf{sk}, \mathsf{ak}, \mathsf{nk}, \mathsf{rivk})$ +projections differ — i.e., $w_1$ and $w_2$ differ in some component +other than the $y$-sign of $\mathsf{ak}^{\mathbb{P}}$. + +The random oracles used in the key-binding condition are $\mathsf{H^{rivk\_ext}}$, +$\mathsf{H^{rivk\_legacy}}$, $\mathsf{H^{rivk\_int}}$, $\mathsf{H^{ask}}$, and +$\mathsf{H^{nk}}$. + +Let $\varepsilon_{\mathsf{kb}}(\mathcal{A}, q_{\mathsf{kb}})$ +be the probability, over $\mathcal{A}$'s randomness and at most $q_{\mathsf{kb}}$ +queries in total to these random oracles, that $\mathcal{A}$ outputs a +key-binding break. + +**Theorem (key-binding, classical ROM).** +Let $\mathcal{A}$ be a classical adversary making at most $q_{\mathsf{kb}}$ +total queries to the random oracles used in the key-binding condition. Then +$\varepsilon_{\mathsf{kb}}(\mathcal{A}, q_{\mathsf{kb}}) \leq \frac{3\, q_{\mathsf{kb}}(q_{\mathsf{kb}}-1)}{2\, r_{\mathbb{P}}}$. + +**Proof sketch.** + +*Algebraic setup.* +By § 5.4.1.10 “Sinsemilla commitments”, +$$\mathsf{Commit^{ivk}_{rivk}}(\mathsf{ak}, \mathsf{nk}) = +\mathsf{Extract}_{\mathbb{P}}\big(M' + [\mathsf{rivk}]\, \mathcal{S}\big),$$ +where $\mathcal{S}$ is the rivk-randomization base +$$\mathcal{S} := \mathsf{GroupHash}^{\mathbb{P}}(\texttt{“z.cash:Orchard-CommitIvk-r”}, \texttt{“”}),$$ +and +$$M' := \mathsf{SinsemillaHashToPoint}\big(\texttt{“z.cash:Orchard-CommitIvk-M”},\; +\mathsf{I2LEBSP}_{\ell^{\mathsf{Orchard}}_{\mathsf{base}}}(\mathsf{ak}) \,\Vert\, +\mathsf{I2LEBSP}_{\ell^{\mathsf{Orchard}}_{\mathsf{base}}}(\mathsf{nk})\big).$$ +By expanding the Sinsemilla bases used inside $\mathsf{SinsemillaHashToPoint}$ +as scalar multiples of $\mathcal{S}$, without loss of generality we have +$M' = [h(\mathsf{ak}, \mathsf{nk})]\, \mathcal{S}$ for a Pedersen-like +deterministic scalar hash $h$, so +$$\mathsf{Commit^{ivk}_{rivk}}(\mathsf{ak}, \mathsf{nk}) = +\mathsf{Extract}_{\mathbb{P}}\big([h(\mathsf{ak}, \mathsf{nk}) + \mathsf{rivk}]\, \mathcal{S}\big).$$ +Domain separation in +the protocol's BLAKE2b instantiations ensures $h$ does not query +$\mathsf{H^{rivk\_ext}}$, $\mathsf{H^{rivk\_legacy}}$, +$\mathsf{H^{rivk\_int}}$, $\mathsf{H^{ask}}$, or $\mathsf{H^{nk}}$: +$h$ depends only on fixed Sinsemilla bases and on $(\mathsf{ak}, \mathsf{nk})$. + +By the same $y^2 = Y(x)$ argument used in the Spendability proof +(using § 5.4.9.7 for the $\mathsf{Extract}_{\mathbb{P}}$-style +$x$-coordinate convention), a key-binding break implies +$$h(\mathsf{ak}, \mathsf{nk}) + \mathsf{rivk} \equiv \pm\big(h(\mathsf{ak}', \mathsf{nk}') + \mathsf{rivk}'\big) \pmod{r_{\mathbb{P}}}.$$ +Define $\mathsf{G}(w) := h(\mathsf{ak}, \mathsf{nk}) + \mathsf{rivk} \pmod{r_{\mathbb{P}}}$ +for a witness $w$, and let $G_i := \mathsf{G}(w_i)$ for $i \in \{1, 2\}$. +The break condition is +$G_1 \equiv \pm G_2 \pmod{r_{\mathbb{P}}}$. + +*Final-random-oracle structure.* +For each witness $w_i$ satisfying the key-binding condition, +$\mathsf{rivk}_i$ is the output of a *final random oracle* +$O_i \in \{\mathsf{H^{rivk\_ext}}, \mathsf{H^{rivk\_legacy}}, \mathsf{H^{rivk\_int}}\}$ +at a *final input* $x_i$, determined by the witness's branch and +IVK choice: + +* qk-branch, external IVK: $O_i = \mathsf{H^{rivk\_ext}}$, + $x_i = (\mathsf{qk}_i, \mathsf{ak}_i, \mathsf{nk}_i)$. +* sk-branch, external IVK: $O_i = \mathsf{H^{rivk\_legacy}}$, + $x_i = \mathsf{sk}_i$. +* qk-branch, internal IVK: $O_i = \mathsf{H^{rivk\_int}}$, + $x_i = (\mathsf{rivk\_ext}_i, \mathsf{ak}_i, \mathsf{nk}_i)$ where + $\mathsf{rivk\_ext}_i = \mathsf{H^{rivk\_ext}_{qk_i}}(\mathsf{ak}_i, \mathsf{nk}_i)$. +* sk-branch, internal IVK: $O_i = \mathsf{H^{rivk\_int}}$, + $x_i = (\mathsf{rivk\_ext}_i, \mathsf{ak}_i, \mathsf{nk}_i)$ where + $\mathsf{rivk\_ext}_i = \mathsf{H^{rivk\_legacy}}(\mathsf{sk}_i)$. + +In each case +$G_i = h(\mathsf{ak}_i, \mathsf{nk}_i) + O_i(x_i) \pmod{r_{\mathbb{P}}}$, +with the deterministic shift $h$ independent of $O_i$'s responses +(by non-querying). + +*Independence claim per pair.* +For distinct witnesses $w_1, w_2$ both satisfying the key-binding +condition, $G_1$ and $G_2$ are independent uniform on +$\mathbb{F}_{r_{\mathbb{P}}}$, except for a residual event of +probability at most $1/r_{\mathbb{P}}$ per pair (accounting for +upstream-RO collisions in the both-internal sub-case). By case on +$(O_1, O_2)$: + +**$O_1 \neq O_2$.** The two random oracles are domain-separated +(independent BLAKE2b instantiations), so $O_1$'s outputs are +independent of $O_2$'s outputs. Each $G_i$ is uniform on +$\mathbb{F}_{r_{\mathbb{P}}}$ marginally; the pair is independent. + +**$O_1 = O_2 \in \{\mathsf{H^{rivk\_ext}}, \mathsf{H^{rivk\_legacy}}\}$.** +Both witnesses are in the same branch and external IVK. If +$x_1 = x_2$, the predicate's functional determinations +($\mathsf{rivk\_ext}_i$ from $x_i$; $\mathsf{rivk}_i = \mathsf{rivk\_ext}_i$; +$\mathsf{ivk}_i = \mathsf{Commit^{ivk}}(\mathsf{ak}_i, \mathsf{nk}_i, \mathsf{rivk}_i)$; +in the sk-branch additionally $\mathsf{ak}_i, \mathsf{nk}_i$ from +$\mathsf{sk}_i$ via $\mathsf{H^{ask}}, \mathsf{H^{nk}}$) force the +witnesses to coincide on all fields constrained by the key-binding +condition, contradicting distinctness. Hence WLOG $x_1 \neq x_2$, so +the two RO outputs at $x_1, x_2$ are independent uniform. + +**$O_1 = O_2 = \mathsf{H^{rivk\_int}}$.** Both witnesses are +internal IVK. If $x_1 = x_2$ as $\mathsf{H^{rivk\_int}}$ inputs, then +$\mathsf{rivk}_1 = \mathsf{rivk}_2$ and $\mathsf{ivk}_1 = \mathsf{ivk}_2$. +Sub-cases on the upstream branches: + +* same upstream branch (qk×qk or sk×sk): + $\mathsf{rivk\_ext}_1 = \mathsf{rivk\_ext}_2$ either forces upstream + input coincidence (and hence witness coincidence on all constrained + fields, contradicting distinctness) or requires an upstream-RO + collision — probability at most $1/r_{\mathbb{P}}$ per pair of + upstream queries. +* cross upstream branch (qk×sk): + $\mathsf{rivk\_ext}_1 = \mathsf{rivk\_ext}_2$ requires a cross-RO + collision between $\mathsf{H^{rivk\_ext}}$ and + $\mathsf{H^{rivk\_legacy}}$, which by domain separation is + probability at most $1/r_{\mathbb{P}}$ per pair of upstream queries. + +In every sub-case the residual $x_1 = x_2$ event has probability at +most $1/r_{\mathbb{P}}$ per pair. Conditional on $x_1 \neq x_2$, +$\mathsf{H^{rivk\_int}}$'s outputs at $x_1, x_2$ are independent +uniform. + +*Bounding the break probability.* +For any pair of distinct witnesses, the break condition +$G_1 \equiv \pm G_2 \pmod{r_{\mathbb{P}}}$ holds with probability +at most $2/r_{\mathbb{P}}$ when $G_1, G_2$ are independent uniform +(one per sign), plus at most $1/r_{\mathbb{P}}$ residual for +upstream collisions in the both-internal sub-case — total at most +$3/r_{\mathbb{P}}$ per pair. + +Treating the five rivk-derivation random oracles +($\mathsf{H^{rivk\_ext}}$, $\mathsf{H^{rivk\_legacy}}$, +$\mathsf{H^{rivk\_int}}$, $\mathsf{H^{ask}}$, $\mathsf{H^{nk}}$) as a +single combined uniform random oracle on the joint query domain (each +RO contributes its outputs independently of the others), and +union-bounding over the at most ${q_{\mathsf{kb}} \choose 2}$ pairs +of distinct witnesses, +$$\varepsilon_{\mathsf{kb}}(\mathcal{A}, q_{\mathsf{kb}}) \leq \frac{3 q_{\mathsf{kb}}(q_{\mathsf{kb}}-1)}{2 r_{\mathbb{P}}}.$$ + + +## Security argument for Spendability + +DeriveNullifier is based on a Pedersen hash. In the current Orchard +protocol, the property that it is infeasible to find two distinct +Orchard notes with the same nullifier (including possible nullifiers +of split OrchardZSA notes), depends on the collision resistance of +that hash, which would not hold against a discrete-log-breaking +adversary. + +Does this mean it is possible to break Spendability for the given +Recovery Statement? As it turns out, no, but the argument is somewhat +involved. + +Since each function in the Recovery Statement is deterministic, the +free variables that the adversary can control are the sources of the +derivation digraph within that statement and either $\mathsf{SoK^{sk}}$ +or $\mathsf{SoK^{qk}}$. That is, the adversary can control all of +$$(\text{ρ}, \mathsf{g_d}, \mathsf{rseed}, \mathsf{sk}, \mathsf{nk}, \mathsf{ak}, \mathsf{qk}, \mathsf{qsk}, \mathsf{rivk})$$ +subject to $(\mathsf{sk} = \bot) \neq (\mathsf{qk} = \bot)$. The +choice between external and internal IVK is encoded in +$\mathsf{rivk}$'s value (either $\mathsf{rivk\_ext}$ or +$\mathsf{H^{rivk\_int}_{rivk\_ext}}(\mathsf{ak}, \mathsf{nk})$). + +We analyze $\mathsf{DeriveNullifier}$ as a function of these +controllable inputs. Recall that $\mathsf{DeriveNullifier}$ is defined +in § 4.16 ‘Computing ρ values and Nullifiers’ as: + +$$\mathsf{DeriveNullifier_{nk}}(\text{ρ}, \text{ψ}, \mathsf{cm}) := + \mathsf{Extract}_{\mathbb{P}}\Big( + \big[(\mathsf{PRF^{nf}_{nk}}(\text{ρ}) + \text{ψ}) \bmod q_{\mathbb{P}}\big]\, \mathcal{K} + + \mathsf{cm} + \Big)$$ + +Also recall from [Repairing note commitments] that we have + +$$\mathsf{cm} = [\mathsf{H^{rcm}_{rseed}}(\mathsf{noterepr}) + + \mathsf{f}(\mathsf{rseed}, \mathsf{noterepr})]\, \mathcal{R}.$$ + +Let $K_{\kern-.08em\mathcal{R}}$ denote the discrete logarithm of +$\mathcal{K}$ with respect to $\mathcal{R}$. This is well-defined and +nonzero: $\mathcal{R}$ generates the prime-order Pallas group, so any +non-identity Pallas point has a unique nonzero discrete logarithm with +respect to it; and $\mathcal{K}$ is non-identity by construction. + +Recall that $\text{ψ}$ is determined by $\mathsf{rseed}$ via +$\text{ψ} = \mathsf{H}^{\text{ψ}}_{\mathsf{rseed}}(\text{ρ})$. +The nullifier corresponding to +$(\mathsf{nk}, \text{ρ}, \mathsf{rseed}, \mathsf{noterepr})$ +is then +$$\mathsf{Extract}_{\mathbb{P}}\Big( + \big[ + \big((\mathsf{PRF^{nf}_{nk}}(\text{ρ}) + \text{ψ}) \bmod q_{\mathbb{P}}\big) \cdot K_{\kern-.08em\mathcal{R}} + + \mathsf{H^{rcm}_{rseed}}(\mathsf{noterepr}) + \mathsf{f}(\mathsf{rseed}, \mathsf{noterepr}) + \big]\, \mathcal{R} + \Big).$$ + +We model $\mathsf{H^{rcm}}$ as a random oracle with output uniform on +$\mathbb{F}_{r_{\mathbb{P}}}$. The functions $\mathsf{f}$, +$\mathsf{H}^{\text{ψ}}$, and $\mathsf{PRF^{nf}}$ are deterministic +functions of $\mathsf{notetuple} = (\mathsf{rseed}, \mathsf{noterepr})$ +that **do not query $\mathsf{H^{rcm}}$**: $\mathsf{f}(\mathsf{notetuple})$ +is the Sinsemilla-base lift; $\mathsf{H}^{\text{ψ}}$ and $\mathsf{PRF^{nf}}$ are +conventional hash functions. + +> The non-querying constraint rules out trivializing instantiations such +> as $\mathsf{f}({\small •}) = -\mathsf{H^{rcm}}({\small •})$. +> In the concrete protocol, it reflects that $\mathsf{f}$ depends only on +> fixed Sinsemilla bases; and that the hashes $\mathsf{H}^{\text{ψ}}$, +> $\mathsf{PRF^{nf}}$, and $\mathsf{H^{rcm}}$ use distinct domain +> separators, so can be considered unrelated to each other. + +A key-binding break is as defined above in the +[Security argument for key binding](#securityargumentforkeybinding). + +Let $\varepsilon_{\mathsf{kb}}(\mathcal{A}, q_{\mathsf{kb}})$ +be the probability, over $\mathcal{A}$'s randomness and at most +$q_{\mathsf{kb}}$ queries to the random oracles used in the +key-binding argument, that $\mathcal{A}$ outputs a key-binding break. +$\varepsilon_{\mathsf{kb}}(\mathcal{A}, q_{\mathsf{kb}})$ is +bounded separately by that argument; the bound below is unconditional, +but is only useful to the extent that +$\varepsilon_{\mathsf{kb}}(\mathcal{A}, q_{\mathsf{kb}})$ is +small. + +We give a reduction-based argument that any classical adversary +$\mathcal{A}$ in the Random Oracle Model attempting to find two valid +[Recovery Statement](#proposedrecoverystatement) witnesses with distinct +note tuples that have colliding nullifiers, succeeds with probability at most +$\frac{q_{\mathsf{rcm}}(q_{\mathsf{rcm}}-1)}{r_{\mathbb{P}}} + \varepsilon_{\mathsf{kb}}(\mathcal{A}, q_{\mathsf{kb}})$, +where $q_{\mathsf{rcm}}$ is the number of queries $\mathcal{A}$ makes +to $\mathsf{H^{rcm}}$, and $q_{\mathsf{kb}}$ is as defined above. +The bound depends only on $q_{\mathsf{rcm}}$ and on +$\varepsilon_{\mathsf{kb}}(\mathcal{A}, q_{\mathsf{kb}})$, +not on running time. + +The components $\mathsf{rseed}, \mathsf{noterepr}$ +are fields of $\mathsf{notetuple}$ by definition; and $\text{ρ}$, +$\mathsf{g_d}$, $\mathsf{pk_d}$, and $\text{ψ}$ are fields of +$\mathsf{noterepr}$, hence of $\mathsf{notetuple}$. + +**$\mathsf{ivk}$-pinning lemma.** +For any valid Recovery Statement witness $w$ with +$\mathsf{notetuple} = (\mathsf{rseed}, \mathsf{noterepr})$, +the value $\mathsf{ivk} = \log_{\mathsf{g_d}}(\mathsf{pk_d})$ is +well-defined, since $\mathsf{g_d} \neq \mathcal{O}_{\mathbb{P}}$ on the +prime-order Pallas curve and +$\mathsf{ivk} \in [0, q_{\mathbb{P}}) \subseteq [0, r_{\mathbb{P}})$; +$\mathsf{ivk}$ is therefore uniquely determined by $\mathsf{notetuple}$. + +**$\mathsf{PRF^{nf}}$-pinning lemma.** +Suppose $\mathcal{A}$'s output $(w_1, w_2)$ does not contain a +key-binding break. Then for each $i \in \{1, 2\}$, +$\mathsf{PRF^{nf}_{\mathsf{nk}_i}}(\text{ρ}_i)$ is uniquely determined +by $\mathsf{notetuple}_i$: by the conditioning, +$(\mathsf{ak}_i, \mathsf{nk}_i, \mathsf{rivk}_i)$ is the only opening of +$\mathsf{ivk}_i$ appearing in $\mathcal{A}$'s output, so $\mathsf{nk}_i$ +is a function of $\mathsf{ivk}_i$, which is in turn a function of +$\mathsf{notetuple}_i$ by the $\mathsf{ivk}$-pinning lemma; and +$\text{ρ}_i$ is a field of $\mathsf{notetuple}_i$. + +The argument here covers nullifier-binding — it argues that $\mathsf{nf}$ +binds the note tuple $(\mathsf{rseed}, \mathsf{noterepr})$ +under $\mathsf{H^{rcm}}$ modelled as a random oracle +and the [key-binding theorem](#thm-key-binding-rom). + +**Theorem (distinct-notetuple Spendability, classical ROM).** +Let $\mathcal{A}$ be a classical adversary with oracle access to +$\mathsf{H^{rcm}}$ having output uniform on $\mathbb{F}_{r_{\mathbb{P}}}$, +making at most $q_{\mathsf{rcm}}$ oracle queries. The *Spendability-collision* +game has $\mathcal{A}$ output two Recovery Statement witnesses $w_1, w_2$ +satisfying: + +**Validity of witnesses** +: both witnesses satisfy the + [Proposed Recovery Statement](#proposedrecoverystatement). + +**Distinct note tuples** +: the $\mathsf{H^{rcm}}$-input tuples + $\mathsf{notetuple}_i := (\mathsf{rseed}_i, \mathsf{noterepr}_i)$ + satisfy $\mathsf{notetuple}_1 \neq \mathsf{notetuple}_2$. + +**Colliding nullifiers** +: $\mathsf{nf}_1 = \mathsf{nf}_2$. + +Then $\mathcal{A}$ wins this game with probability at most +$$\Big({\textstyle{q_{\mathsf{rcm}}} \atop \textstyle{2}}\Big) \cdot \frac{2}{r_{\mathbb{P}}} + + \varepsilon_{\mathsf{kb}}(\mathcal{A}, q_{\mathsf{kb}}) + = \frac{q_{\mathsf{rcm}}(q_{\mathsf{rcm}}-1)}{r_{\mathbb{P}}} + \varepsilon_{\mathsf{kb}}(\mathcal{A}, q_{\mathsf{kb}}),$$ +taken over the random oracle's responses and any internal randomness of +$\mathcal{A}$. + +This bound is essentially tight against classical generic adversaries. +Maurer [^Maurer2002] (Section 2, p. 5) establishes a matching upper +bound of ${k \choose 2}/N$ on the success probability of any +classical algorithm in finding a collision against a random oracle with +an $N$-element output space using $k$ queries. Maurer's bound applies +to the *equality* event $F_i = F_j$; our win condition allows +$F_i = \pm F_j$ (two winning configurations per pair instead of one). +Applying Maurer with $N = r_{\mathbb{P}}$ (the $\mathsf{H^{rcm}}$ +output space) gives ${q_{\mathsf{rcm}} \choose 2}/r_{\mathbb{P}}$ for +the equality event; doubling for the sign relaxation gives our +$\frac{q_{\mathsf{rcm}}(q_{\mathsf{rcm}}-1)}{r_{\mathbb{P}}}$ bound. +Classical parallel collision search [^Bernstein2009] (top of p. 8) +achieves the equality-event regime up to a constant factor; the same +adversaries achieve a constant fraction of the doubled bound for the +$\pm$-equivalence event. + +**Proof sketch.** +$\mathcal{A}$ makes at most $q_{\mathsf{rcm}}$ queries to +$\mathsf{H^{rcm}}$ before outputting $(w_1, w_2)$ satisfying +[**Validity of witnesses**](#thm-spendability-validity), +[**Distinct note tuples**](#thm-spendability-distinct), and +[**Colliding nullifiers**](#thm-spendability-collide). The probability +that $(w_1, w_2)$ contains a key-binding break is at most +$\varepsilon_{\mathsf{kb}}(\mathcal{A}, q_{\mathsf{kb}})$; condition on +the complement. + +*Algebraic setup.* +Under this conditioning, define +$$\mathsf{F}(\mathsf{notetuple}) := \mathsf{H^{rcm}}(\mathsf{notetuple}) + +\mathsf{f}(\mathsf{notetuple}) + \big((\mathsf{PRF^{nf}_{nk}}(\text{ρ}) + +\text{ψ}) \bmod q_{\mathbb{P}}\big) \cdot K_{\kern-.08em\mathcal{R}} +\pmod{r_{\mathbb{P}}},$$ +where $\mathsf{rseed}, \text{ρ}, \text{ψ}$ are fields of +$\mathsf{notetuple}$ and $\mathsf{PRF^{nf}_{nk}}(\text{ρ})$ is +determined by $\mathsf{notetuple}$ via the +[$\mathsf{PRF^{nf}}$-pinning lemma](#lemma-prf-nf-pinning), and let +$F_i := \mathsf{F}(\mathsf{notetuple}_i)$ for $i \in \{1, 2\}$. + +$\mathsf{Extract}_{\mathbb{P}}$ (§ 5.4.9.7 'Coordinate Extractor for +Pallas' [^protocol-concreteextractorpallas]) is the $x$-coordinate of +its argument for non-identity points, with the identity mapping to $0$. +Since Pallas has the form $y^2 = Y(x)$ and no Pallas point has +$x$-coordinate $0$, the collision $\mathsf{nf}_1 = \mathsf{nf}_2$ +holds iff $F_1 \equiv \pm F_2 \pmod{r_{\mathbb{P}}}$. + +*Independence claim per pair.* +By [**Distinct note tuples**](#thm-spendability-distinct), +$\mathsf{notetuple}_1 \neq \mathsf{notetuple}_2$, so the +$\mathsf{H^{rcm}}$ outputs at $\mathsf{notetuple}_1, \mathsf{notetuple}_2$ +are independent uniform on $\mathbb{F}_{r_{\mathbb{P}}}$. The +deterministic shifts ($\mathsf{f}$ and the $\mathsf{PRF^{nf}}$ +contribution scaled by $K_{\kern-.08em\mathcal{R}}$) do not query +$\mathsf{H^{rcm}}$, so they are independent of its responses. Hence +$F_1$ and $F_2$ are independent uniform on $\mathbb{F}_{r_{\mathbb{P}}}$. + +*Bounding the win probability.* +The win condition $F_1 \equiv \pm F_2$ is a linear constraint on a +pair of independent uniform variables, satisfied with probability at +most $2/r_{\mathbb{P}}$ (one per sign). Union-bounding over the at +most ${q_{\mathsf{rcm}} \choose 2}$ pairs of distinct +$\mathsf{H^{rcm}}$ queries: +$$\Pr[\text{win} \mid \neg\,\text{break}] \leq \frac{q_{\mathsf{rcm}}(q_{\mathsf{rcm}}-1)}{r_{\mathbb{P}}}.$$ +Decomposing on whether a key-binding break occurs and applying +$\Pr[\text{win}] \leq \Pr[\text{win} \mid \neg\,\text{break}] + \Pr[\text{break}]$: +$$\Pr[\text{win}] \leq \frac{q_{\mathsf{rcm}}(q_{\mathsf{rcm}}-1)}{r_{\mathbb{P}}} + \varepsilon_{\mathsf{kb}}(\mathcal{A}, q_{\mathsf{kb}}).$$ +This completes the classical-ROM proof. + +The [key-binding theorem](#thm-key-binding-rom) bounds +$\varepsilon_{\mathsf{kb}}(\mathcal{A}, q_{\mathsf{kb}}) \leq \frac{3\, q_{\mathsf{kb}}(q_{\mathsf{kb}}-1)}{2\, r_{\mathbb{P}}}$. +Substituting, an adversary $\mathcal{A}$ that makes at most +$q_{\mathsf{rcm}}$ queries to $\mathsf{H^{rcm}}$ and at most +$q_{\mathsf{kb}}$ queries to the key-binding random oracles +wins the Spendability-collision game with probability at most +$\frac{q_{\mathsf{rcm}}(q_{\mathsf{rcm}}-1)}{r_{\mathbb{P}}} \;+\; \frac{3\, q_{\mathsf{kb}}(q_{\mathsf{kb}}-1)}{2\, r_{\mathbb{P}}}$. + +For the post-quantum lift of this bound and of the +[key-binding bound](#thm-key-binding-rom) above, see the next section. + +## Adaptation to the quantum setting + +The classical-ROM proofs above (for [key binding](#thm-key-binding-rom) +and [Spendability](#thm-spendability-collide)) rely on +$\mathsf{H^{rcm}}$ and the various $\mathsf{rivk}$-derivation hashes +being collision-resistant. The natural quantum analog is called the +*collapsing* property, introduced by Unruh [^Unruh2015] [^Unruh2016]. +It says that even a quantum adversary holding a *superposition* over +several preimages of a fixed output cannot tell —by any subsequent +measurement— which preimage it now has. This is the right property +for our reductions. Each proof above splits cases based on which oracle +query produced the colliding output; that case analysis works the same +classically and quantumly only if the underlying hash "collapses" the +adversary's superposition to a single classical preimage. + +Subsequent work has analyzed whether standard hash-function +constructions inherit collapsing from their compression function. Unruh +[^Unruh2016] proved this for Merkle–Damgård (with a padding +restriction); Czajkowski et al. [^CBHSU2017] for the *sponge* +construction (the absorb-then-squeeze paradigm used by SHA-3 / Keccak), +with [^ACMT2025] strengthening the sponge result via the related notion +of quantum indifferentiability. Fehr [^Fehr2018] gave a unified +algebraic framework that recovers these results and proves the +collapsing property of HAIFA, a Merkle–Damgård variant with a +per-iteration salt and counter. Gunsing and Mennink [^GM2022] extended +this kind of analysis to tree-hash constructions, relevant for the +Recovery Protocol's note-commitment tree. + +BLAKE2b uses HAIFA, so by Fehr's theorem modelling $\mathsf{H^{rcm}}$ +as collapsing reduces to modelling BLAKE2b's compression function as +collapsing. The "iv-preimage resistance" side condition Fehr's theorem +requires for arbitrary-length inputs is automatically satisfied if the +compression function is modelled as a random oracle — which is also +the modelling assumption underlying the classical-ROM analyses above. + +By the argument in [^Bernstein2009], the best known *generic* quantum +attack on a hash function is simply the classical attack of [^vOW1999]. +(In particular, the Brassard–Høyer–Tapp algorithm [^BHT1997] is +entirely unimplementable for a 253-bit output size: to achieve the +claimed speed-up, it would require running Grover's algorithm with a +quantum circuit that does random accesses to a $2^{92.3}$-bit quantum +memory.) Therefore, an output size of 253 bits does not exclude a hash +function from being collapsing. + +$\mathsf{Extract}_{\mathbb{P}}$ does not interfere with the QROM lift: +it is a deterministic 2-to-1 map on non-identity Pallas points (sending +$P$ and $-P$ to the same $x$-coordinate) and does not query +$\mathsf{H^{rcm}}$ or any other random oracle, so it composes with the +underlying random oracle the same way classically and quantumly. The +factor of 2 from the 2-to-1 reduction is already absorbed into the +break-probability bound (each $\mathsf{cm}_x$ has exactly two valid +$\mathsf{cm}$ values, hence exactly two valid $\mathsf{rcm}$ values, as +stated in the Spendability proof above). + +This factor-of-2 absorption relies on the +[fibres](https://en.wikipedia.org/wiki/Fiber_%28mathematics%29) $\{P, -P\}$ +of $\mathsf{Extract}_{\mathbb{P}}$ forming a *uniform* partition of the +non-identity points of $\mathbb{P}$ — the free $\mathbb{Z}/2$ negation action +gives every fibre for non-identity points exactly size 2 — which is what lets +birthday-style bounds substitute $r_{\mathbb{P}} \to r_{\mathbb{P}}/2$ cleanly. +A non-uniform mapping would not admit such a substitution. + +### QROM lift of the security arguments + +The classical-ROM reductions for both +[Spendability](#thm-spendability-collide) and +[key binding](#thm-key-binding-rom) satisfy the standard conditions for +a "clean" lift to the quantum random-oracle model: + +* *Straight-line.* Neither reduction rewinds the adversary or measures + intermediate state; both inspect the adversary's classical output and + bound the probability over the random oracles' randomness. + Rewinding-based QROM techniques [^CMSZ2021] [^CDDGS2025] are therefore + not needed. +* *No adaptive reprogramming.* Both reductions treat their random + oracles as fixed random functions throughout; neither reprograms + responses to adversary-queried inputs. + +**Concrete QROM bounds.** By Zhandry's compressed-oracle technique +[^Zhandry2018] (see also [^CFHL2021] for a classical-style derivation), +the classical $q^2 / N$ collision probability +transfers to $O(q^3 / N)$ in QROM: an adversary making at most $q$ +quantum queries to a random oracle with output space of size $N$ +finds a collision with probability $O(q^3 / N)$. Applied to our +reductions: + +* $\varepsilon^{\mathsf{QROM}}_{\mathsf{Spendability}} \leq O\!\left(q_{\mathsf{rcm}}^3 / r_{\mathbb{P}}\right) + \varepsilon^{\mathsf{QROM}}_{\mathsf{kb}}.$ +* $\varepsilon^{\mathsf{QROM}}_{\mathsf{kb}} \leq O\!\left(q_{\mathsf{kb}}^3 / r_{\mathbb{P}}\right).$ + +These are worst-case theoretical bounds. An adversary that saturates +them would need to mount a BHT-style attack, which is unimplementable +for a 253-bit output (as discussed above, the BHT algorithm would +require a quantum circuit randomly accessing a $2^{92.3}$-bit quantum +memory). In practice the achievable bound remains close to the +classical $q^2 / r_{\mathbb{P}}$, since the best *known* generic +quantum attack is the classical attack of [^vOW1999] — Bernstein +[^Bernstein2009] is careful to flag this as best-known rather than +provably best. + +For the parameters relevant to Zcash ($q_{\mathsf{rcm}}, +q_{\mathsf{kb}} \ll 2^{60}$ and $r_{\mathbb{P}} \approx 2^{254}$), +the $O(q^3 / r_{\mathbb{P}})$ worst-case bound is at most +$\sim 2^{-74}$, while the practically achievable +$O(q^2 / r_{\mathbb{P}})$ bound stays closer to $\sim 2^{-134}$. + +## Effects of discrete-log-breaking attacks before the switch to the Recovery Protocol + +A practical discrete-log-breaking attack —either by a sufficiently large quantum +computer running Shor's algorithm, or a major advance in classical cryptanalysis +of the discrete logarithm or Diffie–Hellman problems— would compromise the +cryptographic primitives underlying Zcash's shielded protocols. + +Note and value commitments in Orchard[ZSA] and Sapling are Pedersen-style and +lose binding; the proof systems used in the shielded protocols (Halo 2 over +Vesta in Orchard[ZSA], Groth16 over BLS12-381 in Sapling or Sprout) lose +soundness; and the RedDSA binding and spend authorization signatures in +Orchard[ZSA] and Sapling can be forged. Sprout's note commitments are +SHA-256-based and survive a discrete log break, but the broken proof system is +sufficient to forge JoinSplit statements, and the Ed25519 spend authorization +and JoinSplit signatures can be forged. In addition, the ECDSA signatures used +for transparent spend authentication can be forged. + +The combined effect is severe. An adversary can: + +* break Balance for the Sapling or Orchard pools by forging value-commitment + openings or binding signatures; +* break Balance for the Sprout, Sapling, or Orchard pools by forging Groth16 or + Halo 2 proofs of balanced transactions; +* break Spend authentication (i.e. steal funds, independently of a Balance break) + for the Sprout, Sapling, or Orchard pools by forging alternative note witnesses + for any commitment on chain, or by forging Groth16 or Halo 2 proofs of valid + spends; +* break Spend authentication for the Sapling or Orchard pools by forging RedJubjub + or RedPallas spend authorization signatures, or for the transparent pool by + forging ECDSA-over-secp256k1 signatures used in scripts; +* break Spendability via roadblock or Faerie Gold attacks, preventing users from + spending their own funds; +* break Privacy of note plaintexts by finding the $\mathsf{ivk}$ for a known + Sapling or Orchard address, or the $\mathsf{sk_{enc}}$ for a known Sprout + address, or by breaking the Diffie–Hellman-based note encryption (again only + for a known recipient address). + +Attacks on transparent spend authentication are not addressed by this proposal. +[^Google2025] discusses these attacks in the context of Bitcoin. For Zcash, we +should note that P2PK and legacy P2MS (non-P2SH) scripts have never been +supported by Zcash wallets, but Zcash is vulnerable to "on-spend" attacks in a +similar way to Bitcoin, with the additional consideration that some Zcash +wallets might be more likely to reuse transparent addresses. The discussion of +Segwit is not relevant to Zcash. + +## Effects of discrete-log-breaking attacks after the switch to the Recovery Protocol + +We assume for this section that the legacy Orchard, OrchardZSA (if deployed), +Sapling, and Sprout protocols will be switched off. Any remaining funds in +the Sapling and Sprout pools, as well as funds in non-recoverable Orchard notes, +would be rendered permanently unspendable. + +The Balance, Spend authentication, and Spendability attacks are possible only +*before* the switch to the Recovery Protocol — that is, while legacy Orchard, +Sapling, and (if ZIP 2003 is not deployed first [^zip-2003]) Sprout spends are +still accepted by the consensus rules. + +If a balance violation occurred in any pool before its protocol was switched +off, it would not necessarily be detected. The only constraint on such attacks +is the ZIP 209 turnstile mechanism [^zip-0209]. If there were evidence of +balance violation having occurred, confidence in Zcash as a whole could +potentially be undermined despite the turnstile constraints (especially if the +violation was in the largest pool, currently Orchard). Therefore, it will be +essential to ensure that the pre-quantum protocols are switched off well in +advance of the potential availability of cryptographically relevant quantum +computers. + +If the transparent protocol is not switched off, then the situation with respect +to transparent spend authentication is unchanged. Balance for the transparent +protocol cannot be violated directly by a discrete-log break (but funds created +by a balance violation in a shielded pool can be moved into the transparent pool +up to that shielded pool's turnstile limit). + +The changes made by ZIP 2005 are only intended to address Balance preservation, +Spend authentication, and Spendability for recoverable Orchard[ZSA] notes. The +situation with respect to Privacy is unchanged for any pool. + +In particular, the note encryption for Orchard[ZSA], Sapling, and Sprout pools +is subject to "Harvest Now, Decrypt Later" attacks: that is, a +discrete-log-breaking attack can be performed as long as an adversary has both +the ciphertext (which is published on the block chain) and the recipient +address. Other protocol changes are under consideration to mitigate this risk +for future transfers. + +Due to the zero-knowledge property, Groth16 and Halo 2 proofs do not leak +further information relevant to Privacy when addresses are unknown. The same is +true of Sapling or Orchard[ZSA] spend authentication signatures, due to key +rerandomization. + +## Attacks addressed by the Recovery Protocol + +The Recovery Statement's $\mathsf{BindKeys}$ constraint pins the key witness via +$\mathsf{PRF^{expand}}$ (modelled as collapsing), not via discrete-log hardness. +So (if no mistakes are made in the design or instantiation), fresh Balance, +Spend authentication, or Spendability attacks against the Recovery Protocol +should require breaking post-quantum binding rather than just discrete logs. +Funds in recoverable Orchard notes can therefore be spent through the Recovery +Protocol after the switch. However, if the adversary attacked either +Spendability (e.g. via a roadblock attack) or Spend authorization before the +switch to the Recovery Protocol, then it could affect the legitimate holder's +ability to spend the funds afterward. The window between +$\mathsf{ZIP2005ActivationHeight}$ and the switch is the critical exposure +period for recoverable Orchard funds. + +Note that we can precisely identify the set of note commitments for recoverable +Orchard notes in v6 transactions, even if we cannot decrypt them, since only +recoverable notes are allowed in that case. However, Orchard notes in v5 +transactions after $\mathsf{ZIP2005ActivationHeight}$ could be either +recoverable or not. + +We cannot identify the precise set of nullifiers for recoverable notes: an +Orchard action in a v6 transaction could be spending either a recoverable or +non-recoverable note, and their nullifier sets are indistinguishable. + +On the other hand, within the Recovery Statement we know that the note being +spent is recoverable. + +# Deployment + +Let $\mathsf{ZIP2005ActivationHeight}$ be {{TBD}}. + +As far as the author of this ZIP is aware, all existing Zcash wallets already +derive $(\mathsf{ak}, \mathsf{nk}, \mathsf{rivk})$ from a spending key +$\mathsf{sk}$ in the way specified for the $\mathsf{use\_qsk} = \mathsf{false}$ +case in § 4.2.3 ‘Orchard Key Components’ [^protocol-orchardkeycomponents]. + +FROST distributed key generation requires the $\mathsf{use\_qsk} = \mathsf{true}$ case. +There is no significant existing deployment of FROST, so we can +[write this into ZIP 312](https://github.com/zcash/zips/pull/895/files) +from the start. + +The part of the protocol that is new is the different input for +$\mathsf{pre\_rcm}$. It would have been possible to use a separate +pq-binding commitment, but $\mathsf{H^{rcm}}$ is already pq-binding and so +doing it this way involves fewer components. This also allows us to avoid +any security compromise and use 256-bit cryptovalues for both integrity +and randomization, which would otherwise have been difficult. + +Two options were considered for deployment: + +1. Deploy this change prior to the next network upgrade. This optimizes + time-to-deployment. An activation height is still needed, in order to + identify a height from which wallets must re-scan if they are missing + recoverable notes due to late deployment. +2. Deploy this change at the same time as the next network upgrade (NU7), + at the same time as v6 transactions. + +With either option, it is proposed to enforce this change with v6 transactions. +That is, every Orchard output of a v6-onward transaction will be a recoverable +note. + +This ZIP currently reflects the first option. The risk of some wallets +not having deployed support for receiving the new note plaintext format +is mitigated by initially only using that format for note plaintexts sent +to wallet-internal addresses. + +When a compliant wallet receives an Orchard note with lead byte +$\mathtt{0x02}$, the associated funds are not recoverable and need to be +spent to a recoverable note in order to make them so. + +Note: if we prioritize spending non-recoverable notes, it is +conceivable that an adversary could exploit this to improve +[arity leakage attacks](https://github.com/zcash/zcash/issues/4332). +On the other hand, adversaries can already choose note values to +manipulate the note selection algorithm to some extent. + + +# 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"](https://www.rfc-editor.org/info/bcp14) + +[^protocol]: [Zcash Protocol Specification, Version 2025.6.2 [NU6.1] or later](protocol/protocol.pdf) + +[^protocol-networks]: [Zcash Protocol Specification, Version 2025.6.2 [NU6.1]. Section 3.12: Mainnet and Testnet](protocol/protocol.pdf#networks) + +[^protocol-orchardkeycomponents]: [Zcash Protocol Specification, Version 2025.6.2 [NU6.1]. Section 4.2.3: Orchard Key Components](protocol/protocol.pdf#orchardkeycomponents) + +[^protocol-saplingsend]: [Zcash Protocol Specification, Version 2025.6.2 [NU6.1]. Section 4.7.2: Sending Notes (Sapling)](protocol/protocol.pdf#saplingsend) + +[^protocol-orchardsend]: [Zcash Protocol Specification, Version 2025.6.2 [NU6.1]. Section 4.7.3: Sending Notes (Orchard)](protocol/protocol.pdf#orchardsend) + +[^protocol-saplingandorchardinband]: [Zcash Protocol Specification, Version 2025.6.2 [NU6.1]. Section 4.20: In-band secret distribution (Sapling and Orchard)](protocol/protocol.pdf#saplingandorchardinband) + +[^protocol-constants]: [Zcash Protocol Specification, Version 2025.6.2 [NU6.1]. Section 5.3: Constants](protocol/protocol.pdf#constants) + +[^protocol-concretesinsemillahash]: [Zcash Protocol Specification, Version 2025.6.2 [NU6.1]. Section 5.4.1.9: Sinsemilla Hash Function](protocol/protocol.pdf#concretesinsemillahash) + +[^protocol-sinsemillasecurity]: [Zcash Protocol Specification, Version 2025.6.2 [NU6.1]. Section 5.4.1.9: Sinsemilla Hash Function — Security argument](protocol/protocol.pdf#sinsemillasecurity) + +[^protocol-concretespendauthsig]: [Zcash Protocol Specification, Version 2025.6.2 [NU6.1]. Section 5.4.7.1: Spend Authorization Signature (Sapling and Orchard)](protocol/protocol.pdf#concretespendauthsig) + +[^protocol-concreteextractorpallas]: [Zcash Protocol Specification, Version 2025.6.2 [NU6.1]. Section 5.4.9.7: Coordinate Extractor for Pallas](protocol/protocol.pdf#concreteextractorpallas) + +[^zip-0032-sapling-child-key-derivation]: [ZIP 32: Shielded Hierarchical Deterministic Wallets — Sapling child key derivation](zip-0032.rst#sapling-child-key-derivation) + +[^zip-0032-sapling-internal-key-derivation]: [ZIP 32: Shielded Hierarchical Deterministic Wallets — Sapling internal key derivation](zip-0032.rst#sapling-internal-key-derivation) + +[^zip-0032-orchard-child-key-derivation]: [ZIP 32: Shielded Hierarchical Deterministic Wallets — Orchard child key derivation](zip-0032.rst#orchard-child-key-derivation) + +[^zip-0032-orchard-internal-key-derivation]: [ZIP 32: Shielded Hierarchical Deterministic Wallets — Orchard internal key derivation](zip-0032.rst#orchard-internal-key-derivation) + +[^slip-0039]: [SLIP-0039: Shamir's Secret-Sharing for Mnemonic Codes](https://github.com/satoshilabs/slips/blob/master/slip-0039.md) + +[^zip-0200]: [ZIP 200: Network Upgrade Mechanism](zip-0200.rst) + +[^zip-0209]: [ZIP 209: Prohibit Negative Shielded Chain Value Pool Balances](zip-0209.rst) + +[^zip-0226]: [ZIP 226: Transfer and Burn of Zcash Shielded Assets](zip-0226.rst) + +[^zip-0226-split-notes]: [ZIP 226: Transfer and Burn of Zcash Shielded Assets — Split Notes](zip-0226.rst#split-notes) + +[^zip-0227]: [ZIP 227: Issuance of Zcash Shielded Assets](zip-0227.rst) + +[^zip-0231]: [ZIP 231: Memo Bundles](zip-0231.md) + +[^zip-0248]: [ZIP 248: Extensible Transaction Format (PR: zcash/zips#1156)](https://github.com/zcash/zips/pull/1156) + +[^zip-0312]: [ZIP 312: FROST for Spend Authorization Multisignatures](zip-0312.rst) + +[^zip-0312-key-generation]: [ZIP 312: FROST for Spend Authorization Multisignatures — Key Generation](zip-0312.rst#key-generation) + +[^zip-0312-threat-model]: [ZIP 312: FROST for Spend Authorization Multisignatures — Threat Model](zip-0312.rst#threat-model) + +[^zip-2003]: [ZIP 2003: Disallow version 4 transactions](zip-2003.rst) + +[^zcash-security]: Understanding Zcash Security ([video](https://www.youtube.com/watch?v=f6UToqiIdeY), [slides](https://raw.githubusercontent.com/daira/zcash-security/main/zcash-security.pdf)). Presentation by Daira-Emma Hopwood at Zcon3. + +[^pq-zcash]: Post-Quantum Zcash ([video](https://www.youtube.com/watch?v=T2B5f297d-Y), [slides](https://docs.google.com/presentation/d/1BHBiSOEO5zt40KWBbRXVMGIIuAcT2hfPWZQ3pT_8tm8/edit?slide=id.g335164f3026_0_113#slide=id.g335164f3026_0_113)). Presentation by Daira-Emma Hopwood at ZconVI. + +[^BHT1997]: [Quantum Algorithm for the Collision Problem. Gilles Brassard, Peter Høyer, and Alain Tapp.](https://arxiv.org/abs/quant-ph/9705002) Also published in LATIN 1998, LNCS vol. 1380, pp. 163–169. + +[^vOW1999]: [Parallel collision search with cryptanalytic applications. Paul C. van Oorschot and Michael Wiener.](https://link.springer.com/article/10.1007/PL00003816) + +[^Bernstein2009]: [Cost analysis of hash collisions: Will quantum computers make SHARCS obsolete? Daniel J. Bernstein.](https://cr.yp.to/hash/collisioncost-20090517.pdf) Presented at SHARCS 2009. + +[^BLAKE3]: [BLAKE3: One Function, Fast Everywhere. Jack O'Connor, Jean-Philippe Aumasson, Samuel Neves, and Zooko Wilcox, 2020.](https://github.com/BLAKE3-team/BLAKE3-specs/blob/master/blake3.pdf) See § 2.1.2 for the `derive_key` mode. + +[^Maurer2002]: [Indistinguishability of Random Systems. Ueli Maurer.](https://crypto.ethz.ch/publications/files/Maurer02.pdf) Also published in Advances in Cryptology — EUROCRYPT 2002, LNCS vol. 2332, pp. 110–132. + +[^Unruh2015]: [Computationally binding quantum commitments. Dominique Unruh.](https://eprint.iacr.org/2015/361) Also published in EUROCRYPT 2016, LNCS vol. 9666. + +[^Unruh2016]: [Collapse-binding quantum commitments without random oracles. Dominique Unruh.](https://eprint.iacr.org/2016/508) Also published in ASIACRYPT 2016, LNCS vol. 10032. + +[^CBHSU2017]: [Post-quantum security of the sponge construction. Jan Czajkowski, Leon Groot Bruinderink, Andreas Hülsing, Christian Schaffner, and Dominique Unruh.](https://eprint.iacr.org/2017/771) Also published in PQCrypto 2018, LNCS vol. 10786. + +[^Fehr2018]: [Classical Proofs for the Quantum Collapsing Property of Classical Hash Functions. Serge Fehr.](https://eprint.iacr.org/2018/887) Also published in TCC 2018, LNCS vol. 11240, pp. 315–338. + +[^Zhandry2018]: [How to Record Quantum Queries, and Applications to Quantum Indifferentiability. Mark Zhandry.](https://eprint.iacr.org/2018/276) Also published in CRYPTO 2019, LNCS vol. 11693. + +[^CFHL2021]: [On the Compressed-Oracle Technique, and Post-Quantum Security of Proofs of Sequential Work. Kai-Min Chung, Serge Fehr, Yu-Hsuan Huang, and Tai-Ning Liao.](https://eprint.iacr.org/2020/1305). Also published in EUROCRYPT 2021, LNCS vol. 12826. + +[^CMSZ2021]: [Post-Quantum Succinct Arguments: Breaking the Quantum Rewinding Barrier. Alessandro Chiesa, Fermi Ma, Nicholas Spooner, and Mark Zhandr.](https://eprint.iacr.org/2021/334) Also published in FOCS 2021. + +[^GM2022]: [Collapseability of Tree Hashes. Aldo Gunsing and Bart Mennink.](https://eprint.iacr.org/2022/248) Also published in PQCrypto 2020, LNCS vol. 12100, pp. 524–544. + +[^CDDGS2025]: [Quantum Rewinding for IOP-Based Succinct Arguments. Alessandro Chiesa, Marcel Dall'Agnol, Zijing Di, Ziyi Guan, and Nicholas Spooner.](https://eprint.iacr.org/2025/947) + +[^ACMT2025]: [The Sponge is Quantum Indifferentiable. Gorjan Alagic, Joseph Carolan, Christian Majenz, and Saliha Tokat.](https://eprint.iacr.org/2025/731) + +[^Google2025]: [Securing Elliptic Curve Cryptocurrencies against Quantum Vulnerabilities: Resource Estimates and Mitigations. Ryan Babbush, Adam Zalcman, Craig Gidney, Michael Broughton, Tanuj Khattar, Hartmut Neven, Thiago Bergamaschi, Justin Drake, and Dan Boneh](https://quantumai.google/static/site-assets/downloads/cryptocurrency-whitepaper.pdf) diff --git a/zips/zip-guide-markdown.md b/zips/zip-guide-markdown.md index 4cc0091cb..8a8a425e6 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 @@ -153,32 +156,38 @@ 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 +"`.. note::`" in reStructuredText or "`
    `" in Markdown +(followed by a blank line in either case), 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. +
    +"`.. warning::`" in reStructuredText or "`
    `" in +Markdown (followed by a blank line in either case), 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. -::: + +In Markdown, notes and warnings can currently only be a single paragraph. ## 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..43df16760 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 @@ -165,30 +167,39 @@ Notes and warnings ------------------ .. note:: - "``.. note::``" in reStructuredText, or "``:::info``" (terminated by - "``:::``") in Markdown, can be used for an aside from the main text. + "``.. note::``" in reStructuredText or "``
    ``" in + Markdown (followed by a blank line in either case), 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. + "``.. warning::``" in reStructuredText, or "``
    ``" + in Markdown (followed by a blank line in either case), 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. +In Markdown, notes and warnings can currently only be a single paragraph. + 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-template.md b/zips/zip-template.md new file mode 100644 index 000000000..63b69f34d --- /dev/null +++ b/zips/zip-template.md @@ -0,0 +1,84 @@ + ZIP: Unassigned {numbers are assigned by ZIP editors} + Title: {Template for new ZIPs} + Owners: First Owner + ... + Credits: First Credited + ... + Status: Draft + Category: {Consensus | Standards Track | Network | RPC | Wallet | Informational | Process} + Created: yyyy-mm-dd + License: {usually MIT} + Pull-Request: + + +# 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 [^BCP14] when, and +only when, they appear in all capitals. + +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 term "full validator" in this document is to be interpreted as defined in § 3.3 ‘The Block Chain’. [^protocol-blockchain]. + +The terms below are to be interpreted as follows: + +{Term to be defined} + +: {Definition.} + +{Another term} + +: {Definition.} + + +# Abstract + + +# Motivation + + +# Privacy Implications + + +# Requirements + + +# Non-requirements + + +# Specification + +
    + +{details heading} + + +{ details body } +
    +
    + +# Rationale + + +# Deployment + + +# Reference implementation + + +# Open issues + + +# 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"](https://www.rfc-editor.org/info/bcp14) + +[^protocol]: [Zcash Protocol Specification, Version 2025.6.3 [NU6.1] or later](protocol/protocol.pdf) + +[^protocol-blockchain]: [Zcash Protocol Specification, Version 2025.6.3 [NU6.1]. Section 3.3: The Block Chain](protocol/protocol.pdf#blockchain) + +[^protocol]: [Zcash Protocol Specification, Version 2025.6.3 [NU6.1]. Section 3.12: Mainnet and Testnet](protocol/protocol.pdf#networks)