Skip to content

Protocol spec: apply ZIP 2005, and related cleanups - #1358

Open
daira wants to merge 19 commits into
zcash:mainfrom
daira:apply-zip2005-remaining
Open

Protocol spec: apply ZIP 2005, and related cleanups#1358
daira wants to merge 19 commits into
zcash:mainfrom
daira:apply-zip2005-remaining

Conversation

@daira

@daira daira commented Sep 6, 2026

Copy link
Copy Markdown
Collaborator

Completes the application of ZIP 2005's protocol-spec and ZIP changes begun in #1336, together with cleanups that surfaced while applying them. Nothing here changes consensus for previous network upgrades. The new normative text is all under NU6.3 conditionals and reflects that upgrade as-activated.

Applied ZIP 2005 changes

  • § 4.1.2, § 4.2.3, and § 5.3: the quantum spending and intermediate keys (qsk, qk) and the use_qsk derivation branch in 'Orchard Key Components', with the named derivation functions H^ask, H^nk, H^rivk, H^qsk, H^qk (BLAKE3 derive_key), and H^rivk_ext; the ℓ_qsk and ℓ_qk constants, placed after ℓ_dk in § 5.3 and in § 2's constants inventory; and the updated PRF^expand usage list. References for BLAKE3, ZIP 226, and ZIP 312 are added to the bibliography.
  • § 4.7.2 and § 4.8.2: Derive_rcm^Sapling and H^esk,Sapling, used for the rcm and esk derivations in Sapling sending and dummy notes.
  • § 4.20.2 and § 4.20.3: the receive-side re-derivations route through the lead-byte-dependent derivation functions, with the derivation order changed so that rcm can depend on g_d and pk_d, the protocol metavariable bound per pool, and the Orchard-pool guards widened to Orchard-like pools so that Ironwood-pool notes are covered.
  • § 3.2.1: the "Let pool" sentence moves directly above the allowedLeadBytes definition, matching its position in the ZIP.
  • § 3.2.1 notes: Orchard-pool note plaintexts have lead byte 0x02 exactly (rather than ≥ 0x02; unconditional, since no other lead byte has been allowed since Orchard was introduced), and from NU6.3 a note says that the Orchard-pool and Ironwood-pool allowed lead-byte sets must remain disjoint. Both get Change History entries.
  • ZIP 32: ∗ marks on the sk → ask and sk → rivk arrows of the Orchard internal key derivation diagram (matching the protocol spec's key components diagram), with the note explaining that other derivations are possible but may forfeit ZIP 2005 note recovery; the PNG is regenerated with rsvg-convert, whose text layout differs subtly from the original Inkscape export (outer-label size and subscript spacing) — a re-export on that pipeline would restore exact fidelity.
  • ZIP 212: the note that ZIP 2005's changes are not reflected there.

Several fixes are synced into ZIP 2005 itself: the use_qsk = false branch regains the deployed "if ask = 0, discard" step; § 4.1.2's usage list no longer lists 0x0A as used, since it is only reserved (for ZIP 226 split notes); a § 2 'Notation' change block is added, with the § 5.3 constant placement made explicit; ρ is defined for both protocols in the receive re-derivations; the § 4.20.2 where-ψ deletion and the § 4.20.3 esk consistency-check replacement (the reason H^esk,Sapling takes an argument at all) are added; the protocol metavariable is bound; the § 3.2.1 lead-byte notes are synced, replacing the ZIP's note that only 0x03 is allowed for Ironwood-pool notes, which did not match the spec's ≥ 0x03 item; and the ZIP 212 note placement follows the precedent of ZIPs 230 and 246.

Cleanups

  • ak is typed {1..q_ℙ−1}. 0 is not the affine x-coordinate of any Pallas point in ℙ*, so this was already implied by the decoding rule in § 5.6.4.4, and it is consistent with the Action circuit (ak^ℙ is witnessed as a non-identity point) and with the implementation. This change is unconditional.
  • One term each for ask and ak — "Spend authorizing key" and "Spend validating key" — removing the alternative terms "spend authorization private key" and "spend authorization address key". Also unconditional. Fixes [protocol spec] Spec uses inconsistent terms for ask and ak #763.
  • The H^* derivation functions get macros, with the protocol and the key subscript as parameters, matching Derive_rcm.
  • The § 4.6 pnote scopes the shared rt/enableSpends/enableOutputs components to a given pool from NU6.3, since a transaction can then have bundles in two pools.
  • The NU6.2-only verifying-key rule uses \nusixtwoonlyitem, so that it renders as a list item.
  • zip-guide and zip-guide-markdown now say that the blank line after a note/warning marker is required for Markdown, rather than implying it in either format.
  • AGENTS.md explains why builds go through nix develop -c, gives the form of an open Change History entry, and points at the new scripts/find-section.py, which resolves protocol-spec section numbers to labels, titles, and source lines (or back) from a prior build's aux files. The new scripts/ directory anticipates Reduce clutter in the root directory by moving scripts #1025.
  • Sinsemilla terminology: the k-bit groups of a Sinsemilla hash input are called words rather than pieces (§ 5.4.1.9 and the index), matching halo2_gadgets; the Change History records the rename.
  • The Change History is rearranged: the entries for the ak type and the Orchard lead-byte note are marked as NU5 changes, and the receive-side entry is reworded.

Both build variants (nu6_3 and the deployed protocol.pdf) are green, and the affected ZIPs are re-rendered.

🤖 Claude Fable 5 and Fable 5.1

daira and others added 13 commits September 6, 2026 00:17
The Build section named the canonical form without the reason. Add it:
without the flake's tool set, the output is not reproducible and the
build may fail depending on installed tool versions.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
The rule said to add an open entry when none exists, but not what one
looks like, so an agent had to dig through git history to find the
\historyentry{\docversion}{} form and the release-time dating.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Update ZIPs and external documents refer to protocol-spec sections by
number, but numbering is assigned at build time and only exists in the
build's aux files, so resolving a number to a label and source line
meant digging by hand. scripts/find-section.py reads \newlabel entries
from the most recent protocol/aux/*.aux (or --aux) and answers queries
by number, label, or title substring. Mention it in AGENTS.md.

The new scripts/ directory is the intended home for the repo's helper
scripts (see issue zcash#1025 for moving the existing ones).

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
0 is not the affine-SW x-coordinate of any Pallas curve point in P*,
so the decoding rule in § 5.6.4.4 'Orchard Raw Full Viewing Keys'
already excluded ak = 0, the Action statement witnesses ak^P with type
P*, and the implementation rejects the identity when parsing a Spend
validating key and rejects ask = 0 at derivation. Typing ak as
{0..q_P-1} understated this and could mislead implementors. ZIP 2005's
§ 4.2.3 replacement already uses the tighter type; this change makes
the deployed sections agree independently of NU6.3.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Both "spend authorization private key" and "Spend authorizing key"
were used for ask, and both "spend authorization address key" and
"Spend validating key" for ak. Standardize on "Spend authorizing key"
and "Spend validating key", which § 3.1 and the key-components
sections already use, and remove the alternative term macros.

Fixes zcash#763.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
The quantum spending and intermediate keys (qsk, qk) and the use_qsk
derivation branch land in § 4.2.3 'Orchard Key Components', with the
named derivation functions H^ask, H^nk, H^rivk, H^qsk, H^qk (BLAKE3
derive_key), and H^rivk_ext, the generation note for ak, and the
note-recovery requirements note. The l_qsk and l_qk constants land in
§ 5.3 and in § 2's inventory of integer constants, in both cases
directly after l_dk. § 4.1.2's PRF^expand usage list gains the
0x0B/0x0C/0x0D first-byte domain separators, recording 0x0A as
reserved for split notes. References for BLAKE3, ZIP 226, and ZIP 312
are added to the bibliography, and a new open Change History entry
records the ZIP 2005 changes applied since release 2026.7.0. In
§ 3.2.1, the "Let pool" sentence moves directly above the
allowedLeadBytes definition, matching its position in the ZIP.

Three fixes are synced into ZIP 2005 itself: the use_qsk = false
branch regains the deployed "if ask = 0, discard" step, which the
declared type of ask requires; § 4.1.2's usage list no longer lists
0x0A as used, since ZIP 2005 only reserves it; and a § 2 change block
is added for the constants inventory, with the § 5.3 placement of the
new constants made explicit.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
The pnote in § 4.6 said that rt, enableSpends, and enableOutputs are
the same for all Action transfers in a transaction. From NU6.3 a
transaction can have both an Orchard-pool and an Ironwood-pool bundle,
each with its own root and flags, so in the NU6.3 variant the scope is
all Action transfers in a given pool.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
The H^ask, H^nk, H^rivk, H^qsk, H^qk, H^rivk_ext, H^{rcm,protocol},
H^{esk,protocol}, and H^{psi,Orchard} derivation functions were
spelled inline with \mathsf at every site. Give each a macro, with
the protocol and the key subscript as parameters where applicable,
matching \DeriveNoteCommitRand; also use \DeriveNoteCommitRand for
the remaining inline Derive_rcm spellings.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Derive_rcm^Sapling and H^{esk,Sapling} are defined in § 4.7.2 'Sending
Notes (Sapling)' and used for the rcm and esk derivations there and in
§ 4.8.2 'Dummy Notes (Sapling)'. For lead byte 0x02 they equal the
deployed derivations; the lead-byte case split and the unused argument
of H^{esk,Sapling} serve the receive-side re-derivations, which
ZIP 2005 routes through these functions uniformly for Sapling and
Orchard.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
The NU6.2-only verifying-key consensus rule used \nusixtwoonly, which
does not produce the \item that its sibling rules' -item macros do.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
The replacement line for § 4.20.2/§ 4.20.3 defined ρ only via the
Action description, which does not exist on the Sapling path although
the uniform H^{esk,protocol}(ρ) call still receives it. Define ρ as ⊥
for Sapling, and use the same "if protocol = ..." phrasing for the ψ
line and the Sapling g_d check.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
The receive-side re-derivations route through the lead-byte-dependent
derivation functions: ρ is taken from the Action description for the
Orchard protocol (or ⊥ for Sapling), esk is re-derived and checked via
H^{esk,protocol}, ψ via H^{ψ,Orchard}, and rcm via Derive_rcm^protocol,
with the derivation order changed so that rcm can depend on g_d and
pk_d. § 4.20.3's Sapling subgroup check moves up to the esk validity
line. The protocol metavariable is bound per pool, and the Orchard-pool
guards on the note-tuple and cm*' lines widen to Orchard-like pools, so
Ironwood-pool notes are covered.

Three fixes are synced into ZIP 2005: the missing where-ψ deletion for
§ 4.20.2, the missing replacement of § 4.20.3's esk consistency check
(the reason H^{esk,Sapling} takes an argument at all), and the binding
of the protocol metavariable.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Both guides said the marker is "followed by a blank line in either
case", but reStructuredText directives take indented content with or
without an intervening blank line, and the RST precedent (e.g. ZIP 230)
uses none. Say instead that a following blank line is required for
Markdown.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
@daira
daira force-pushed the apply-zip2005-remaining branch from 857cb23 to 03d7711 Compare September 7, 2026 01:21
daira and others added 2 commits September 7, 2026 02:27
ZIP 2005 changes the note encryption that ZIP 212 introduced; add the
note it specifies just after the Abstract heading, following the
placement precedent of ZIPs 230 and 246. Sync ZIP 2005's instruction
to name that placement and drop the Markdown-specific note marker,
since ZIP 212 is reStructuredText.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Apply ZIP 2005's change: the sk → ask and sk → rivk arrows in the
Orchard internal key derivation diagram gain ∗ marks, copied verbatim
(element, style, and relative position) from the marks already added
to the key components diagram in the protocol spec; the two diagrams
share their arrow geometry. The note under the diagram explains that
other derivations are possible but may forfeit ZIP 2005 note recovery.

The PNG is regenerated from the SVG at its previous dimensions using
rsvg-convert rather than the original Inkscape-on-Linux export, whose
text layout differs subtly (outer-label size and subscript spacing);
re-exporting with the original pipeline would restore exact fidelity.

This completes the application of ZIP 2005's currently-specified
changes to the protocol spec and other ZIPs.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
@daira
daira force-pushed the apply-zip2005-remaining branch from 03d7711 to ddeacac Compare September 7, 2026 01:29
daira and others added 4 commits September 7, 2026 13:42
The note on Orchard-pool note plaintexts says the lead byte must be
0x02 rather than ≥ 0x02, unconditionally: no other lead byte has been
allowed since Orchard was introduced. From NU6.3, a new note says that
allowedLeadBytes^OrchardPool and allowedLeadBytes^IronwoodPool must
remain disjoint.

ZIP 2005 now instructs both note changes. Its previous note, that the
only allowed lead byte for Ironwood-pool note plaintexts is 0x03, did
not match the spec's "≥ 0x03" item and is replaced by that item.

Both changes get Change History entries.

Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
Spacing around the concatenation in the § 4.1.2 quotation, and the
placement of the BLAKE3 footnote reference on the H^qk line.

Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
… NU5.

Signed-off-by: Daira-Emma Hopwood <daira@jacaranda.org>
…rds",

matching `halo2_gadgets`.

Signed-off-by: Daira-Emma Hopwood <daira@jacaranda.org>
daira added a commit to daira/ironwood that referenced this pull request Sep 8, 2026
A Sinsemilla input is split into K-bit words, the term halo2_gadgets
uses and the protocol specification uses as of zcash/zips#1358; "chunk"
is the specification's term for the 3-bit groups of a Bowe–Hopwood
Pedersen hash input as used in Sapling. The ledger layer's docstrings
and comments said "chunk" for the former; they now say "word", and the
identifiers defined in the ledger layer follow: `wordIdx`,
`wordIdx_of_lt`, the `hword` and `words` binders, and the private
`_words_onCurve` lemmas in `Bridge.lean`; the one mention in
`Zcash/Common/DiscreteLogRelation.lean` follows too. Identifiers
defined in the circuit layer (`chunksOf`, `merkleChunks`,
`noteCommitChunks_inj`, the `.chunks` field) keep their names here.

Co-authored-by: Claude Fable 5.1 <noreply@anthropic.com>
@daira daira changed the title Protocol spec: continue applying ZIP 2005, with related cleanups Protocol spec: apply ZIP 2005, and related cleanups Sep 8, 2026
@daira
daira marked this pull request as ready for review September 8, 2026 20:05
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

[protocol spec] Spec uses inconsistent terms for ask and ak

1 participant